Pass a role to authenticate basic http from postman - spring

I am using Spring boot security and defined user in memory authentication to authenticate http basic but I am not seeing option in Postman to pass user role so my question is how can i pass role in postman for all requests??
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password(passwordEncoder().encode("passowrd"))
.authorities("ADMIN");
}

You don't need to pass Role from Postman request as inMemoryAuthentication you have set user with role "ADMIN" so path you have defined can be accessed by ADMIN role and if you try to call end points by this user, you will have access as "user" as role is "ADMIN" in your memory where user will be authenticated in basic auth.
So from Postman just select Basic Auth and pass user as user and password as password, you will be able to call those end points for which have defined to access by "hasRole = ADMIN..

Related

Spring w/ Cognito get email from SecurityContextHolder

Currently I've got Oauth2 through Cognito set up for my Spring API. I mostly followed this resource and authentication is working so far.
To be able to access a private user's profiles and edit them I want to be able to compare the currently authenticated user with the relevant user of the profile to determine if they're authorized.
My thought on how to do this is that I would define a custom PreAuthorize type that would compare the User from the database's email with the authenticated user's email using the SecurityContextHolder.
However, I'm not able to get the email from the Cognito token. Debugging an endpoint with the below method
var principal = (Jwt)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
principal.getClaims().forEach((k, v) -> System.out.println(k + ": " + v));
None of the values correspond to email. The User Pool is using email to log in, but it creates a generated uid for the username and that's what I receive here.
I could hit the userinfo endpoint manually to try and get the email, but that seems like the wrong way to go about it. Is there a way I can get the user's email to be included in the access token instead of the username? Is there a better way to compare Cognito data to database data?
Here's my relevant code, fairly simple for now:
WebSecurityConfigurerAdapter -
#Override
public void configure(HttpSecurity http) throws Exception {
http.cors();
http.csrf().disable();
http.authorizeRequests(expressionInterceptUrlRegistry -> expressionInterceptUrlRegistry.anyRequest().authenticated())
.oauth2ResourceServer().jwt();
}
Application.yaml -
security:
oauth2:
resourceserver:
jwt:
issuer_uri: https://cognito-idp.us-east-1.amazonaws.com/us-east-1_pKhoaGXXu

Update the authorities in the Authentication object once the user is authenticated and before authorizing him for an endpoint

I have a situation where i have to authorize the user to certain path (endpoint) depending on the role he has.
Problem: Once the user is authenticated, i see an empty set of authorities in authentication object (which is used by authorizing filter to determine access for the user.)
I am new to spring security and would need help to address this.
Background: We have a authorization server implemented in the organization which uses oauth2 and lets us do the single sign on. SSO happens in the front end which gets the token from the authorization server and embeds it to every request sent to my server. Now my server decodes the token and authenticates the user. the user claim doesn't have authorities information and i am not allowed to make any code changes in my authorization server..
What i am looking for : Once the user gets authenticated and before he proceeds for authorization (i am using filters in my web security config) i want to make a call to the DB and get the user respective roles and save it to my authentication object, so that the authorities are now updated, user will be authorized to the endpoint.
You can create a SecurityService and call it from #PreAuthorize annotation
#GetMapping()
#PreAuthorize("securityService.hasRole('ADMIN', authentication.principal.username)")
public String getData() {
return "response";
}
And call authorized server from SecurityService with rest template for example:
public class SecurityService {
public boolean hasRole(String role, String username) {
String role = restTemplate.getRoleByUserName...;
// check role
return false/true
}
}

Spring 4 MVC + Security login page redisplayed

I am implementing the security for my web application. The below are different event that takes place in authentication.
1) Successful login takes the users to the "dasboard" page.
2) Failure will take to the login page with the error.
3) The unauthenticated user access the secured page directly, redirected to the login, success takes to the dashboard, failure to the login with error.
4) The unauthenticated user access the secured page directly, redirected to the login, success takes to the dashboard, failure to the login with error.
The problem,
1) The user is successfully authenticated, views the dashboard page. Again he navigates directly to the login page, login is displayed. But, why should it? Should it not, by default, redirect to the dashboard? Should I need to check in my login controller if the user has already logged-in and redirect to dashboard or any configuration I am missing?
2) I have 3 role of users, super admin, admin and user. Can I redirect to different pages based on different role of users? If so how? If not how can this be implemented?
3) Based on the configuration I should be able to switch between LDAP auth or DB. If the app needs to be authenticated, in future, with ldap shall I inject the auth provider based on configuration? How do configure multiple authenticators?
Please share your wisdom/docs/links on "this is how it should be done" spring-security
My WebSecurityConfig.java
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated().and().formLogin()
.loginPage("/login").loginProcessingUrl("/authenticate")
.defaultSuccessUrl("/dashboard").failureUrl("/login?error")
.usernameParameter("username").passwordParameter("password")
.permitAll().and().logout().logoutUrl("/logout").permitAll();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
AuthenticationProvider authenticationProvider = new CustomAuthenticationProvider();
auth.authenticationProvider(authenticationProvider);
}
1) As you said this can be easily done in your login controller. Just send a redirect instead of the login page if you know that the user is already logged in.
2) I think you mean the redirect after the user logged in, are you?
This can be achieved using a custom AuthenticationSuccessHandler. Maybe this question can give you more details.
3) You can configure multiple AuthenticationProviders (e.g. one for LDAP and one for DB) using an ProviderManager AuthenticationManager. An option would be to configure the AuthenticationProviders during startup in your java config based on the given environment or configuration values.
1) Create session when the user login.and always check that login session on you login page...if session is caught ,redirect to dashboard,....if session in null let it live on login page...
2) Create sessions according to the which user is login, for example if "super user" logins, create session of "superUser"....and vice-versa...
Now check that session,if session has value of superUser,redirect it to desired page for super user....and vice versa...
In both of these using session is good choice.

Spring security Oauth2 Resource Owner Password Credentials Grant

Have just installed spring security oauth2 in my eclipse IDE. The service am trying to implement will be consumed by second party users through their installed applications hence i chose to use password grant type. As per my understanding of Oauth2 the following request should work for the demo sparklr2 service without the need of me encording the username and password parameters. i.e
POST http://localhost:8080/sparklr2/oauth/token?grant_type=password&client_id=my-trusted-client&scope=trust&username=marissa&password=koala
but i keep getting
<oauth>
<error_description>
Full authentication is required to access this resource
</error_description>
<error>unauthorized</error>
</oauth>
am i missing something in this request or do i need to enable something in the repo
It seems like Spring OAuth2 doesn't support the password grant type for a secret-less OAuth2 client. This might be as per the OAuth2 spec: https://www.rfc-editor.org/rfc/rfc6749#section-4.3.2, although the spec seems to indicate that the client authentication is not always required (that's not very clear to me).
That means that when calling the token endpoint using the password grant type, you need to pass in the client ID and secret (using basic auth), which also mean that you can't use the password grant if the client does not have a secret (you might still be able to use the implicit flow).
In sparklr2, my-trusted-client does not have a secret defined which is why your call fails.
If you want to see the password grant type in action you can try my-trusted-client-with-secret:
curl -u my-trusted-client-with-secret:somesecret "http://localhost:8080/sparklr2/oauth/token?grant_type=password&username=marissa&password=koala"
Although the question is a bit old, I would like to contribute with my findings around this.
It is true that for Spring OAuth you need to specify a client ID in order to access to the token endpoint, but it is not necessary to specify client Secret for password grant type.
Next lines are an example of an Authorization Server client for password grant type without any client Secret. Yout just need to add them in your class that extends AuthorizationServerConfigurerAdapter:
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("clientId")
.authorizedGrantTypes("password")
.authorities("ROLE_CLIENT")
.scopes("read");
}
}
Furthermore, it is indeed possible to avoid the HTTP Basic Authentication in the token endpoint and add our client_id as another request parameter in our POST call.
To achieve this, you just need to add these lines in the same class as before:
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.allowFormAuthenticationForClients();
}
Now we can call the token endpoint by this way, which seems more correct following the examples found in Stormpath webpage
POST http://localhost:8080/sparklr2/oauth/token?grant_type=password&client_id=clientId&scope=read&username=marissa&password=koala

How to get authenticated user in spring-security-oauth

For my REST aplication I used Basic Authentication (sending user's password and login with every request). For some needs I obtain logged user using:
User loggedUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
But then I implemented Spring-Security-Oauth2 and I am using access token instead password and login. And now .getPrincipal() method returns "anonymousUser".
So my question: Is there any way to obtain logged User somehow as above in spring-security-oauth?
EDIT:
I figured out that I had a proplem in my security "intercept-url pattern". So now I can use SecurityContextHolder from which I can obtain authenticated user.
inside controller method you can add this paramter then it will be injected for you and you can access user information
getUserAuthentication(OAuth2Authentication auth,Model model)

Resources