I am playing with the Spring Cloud OAuth2 implementation using the following examples:
https://github.com/spring-cloud-samples/authserver
https://github.com/spring-cloud-samples/sso
The first is an OAuth server that generates JWT tokens upon authenticating the user. The second is a resource that is being consumed. The resource relays the authentication of the user to authserver as per the OAuth spec.
All seems to work very well, leading me to additional questions:
In the authserver, during authentication, how can I get access to the clientId and clientSecret?
Can I determine which values are used for generating the JWT token?
In SSO, how do I get access to the content of the token (for instance, the principal) once the user is authenticated?
Answer to 3): change the method signature to include:
#AuthenticationPrincipal User principal
This way the authentication credentials will be passed to the controller method called by Spring. The other way is through the security context:
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication authentication = securityContext.getAuthentication();
As for 2), my guess at this point is that to influence the parameters used to compute the JWT token, one needs to implement a custom AccessTokenConverter. If my understanding is correct the default one called DefaultAccessTokenConverter does not allow for this. I welcome any other opinion on this.
Related
While implementing Azure OAuth flow I have used state parameter, Azure docs says about state param:
A value included in the request that is also returned in the token response. It can be a string of any content that you wish. A randomly generated unique value is typically used for preventing cross-site request forgery attacks. The value can also encode information about the user's state in the app before the authentication request occurred. For instance, it could encode the page or view they were on.
So, My web application is already generating such unique string and that is a CSRf token (UUID). So I used the same CSRF token (UUID) and passed to state parameter. When response comes from OAuth provider I have crossed with the CSRF token from session.
But, recently security team in my company said CSRF token should not used in this way. According to them
A CRSF token is a secret that should not be shared. Using it as a state value is therefore improper use of the CSRF token and introduces a (small) security risk.
But, if I look closely at other normal (non-Oauth) requests then the same CSRF token is passed in request header, so I asked them that if CSRF token is secret then why it is being passed in request header that could also "introduces a (small) security risk." the answer I received is not convincing. Hence asking this question on this large forum:
Can we use CSRF token as a value for state parameter in OAuth request? Is there any security risk involve if we use CSRF token as state parameter?
I have a controller method that has an argument OAuth2AuthorizedClient with annotation #RegisteredOAuth2AuthorizedClient.
ResponseEntity<String> getFoo(
#RegisteredOAuth2AuthorizedClient("custom") OAuth2AuthorizedClient client) {
OAuth2AccessToken token = client.getAccessToken();
....
}
In order to resolve this, spring look for OAuth token on OAuth2AuthorizedClientService which actually stores the previously authenticated tokens in memory.
Now, I have a scenario where I obtain JWT token from OAuth server outside of this spring resource server, and trying to authenticate this server by passing token using Authorization header.
But when spring trying to resolve OAuth2AuthorizedClient it is looking for token in-memory with the principle of JWT (which will obviously not found since token is not obtained on this server). Hence send new login redirection for new token.
Overall question would be, is it possible to resolve OAuth2AuthorizedClient with the JWT token (obtained ourside of the server) passed in Authorization header?
I am consuming a secured Restful Service that grants access through Basic Auth (Username and Password). I have successfully accessed the API service and consumed its API; however, I am still confused as to what is the right way to implement HTTP headers with Basic Auth. I would assume I should authenticate only once, but the way I have constructed my code, it looks like I need to authenticate API with each service method I create.
Should I create a helper method with the authentication and call it on each service?
If you are using Basic Auth you need to always include credentials with your request. In case of OAuth, tokens have expiry. In this case, a token caching mechanism for the duration of a little bit less than the expiration duration would do the trick.
The Basic Auth is a kind of no status authentication. That means the server wouldn't record. Every time you need to provide username and password with your request. Each request is equal to the Server.
For another authentication called OAuth, the first time you request with username and password, the server will return a token to the frontend, which has an expiration period. So, you request every time with the token through the filter, where checks the expiry of the token. If it's not expired, using the same token for requests, otherwise, making a request to get another token.
I want to make an automatic login into web application, which will be accessible on company's intranet.
The login will function in a way that when user is accessing the application, he will automatically send its credentials (username and password), example (company.com/myapplication/login?user=jhon&pass=123).
How can I implement that instead standard Spring Security login using HTML forms? Maybe using hidden form which will be then filled with GET parameters? I can't find any examples for that scenario.
My part is only after user has sent the link with parameters.
You can do this is two ways (or more). (after our comment, it seams that you need to go with way two, because you do not have a username and password)
First way:
Use the standard spring form login and then modify you application so that is send login request like the normal web form login would do.
Assume you have configured the login-processing-url="/login/j_spring_security_check"
<security:form-login
login-processing-url="/login/j_spring_security_check"
login-page="/login"
authentication-failure-url="/login?login_error=t" />
then send a
HTTP POST to https://yourApplication/login/j_spring_security_check with the two POST parameters
j_username=<login>
j_password=<password>
Second way:
Write your own Authentication Processing filter. That is a class that extends AbstractAuthenticationProcessingFilter and it is responsible for
taking stuff that the user used to authenticate (normally username and password) from the request,
forming some the users authentication token object from them (for example an UsernamePasswordAuthenticationToken)
and invoking AuthenticationManager.authenticate(Authentication authentication) with this authentication token
To register your filter, you only need to add them to the spring security filter chain:
<security:custom-filter ref="yourFilter" after="FORM_LOGIN_FILTER"/>
I recommend to have a view on the UsernamePasswordAuthenticationFitler (and keep in mind that is extends AbstractAuthenticationProcessingFilter) - this will explain it best.
If you do not have an username and password, then you need to create your own token (extends Authentication) and then you have to implement your own AuthenticationProvider (and register with the AuthenticationManager). A AuthenticationProvider is reponsible to
- consume an (special type of) Authentication Token and
- validating that the stuff in the Authentication Token is valid
- creating an OTHER Authentication object with UserDetails and Privileges
- or, if the Authentication Token is not valid, throwing an AuthenticationException
Have a look at AbstractUserDetailsAuthenticationProvider and its subclass, for an example.
I would like to develop a portal which contains some modules
The portal and each module consume data provided by a webservice based on Jersey and secured with OAuth 1.0
For the moment I have almost implement the OAuth provider
A user can connect to the portal and access to a module
Each app or module has a specific access token to consume resource
What I want to do is to add a role implementation
For example for the module1, the user can have 2 roles (role1 and role2) but can't use the 2 roles in parallel
First the user uses the access (module1 / user1 / role1) and he will have a token and later the user uses the access (module1 / user1 / role2) and he will have an other token
Depending on the role, I would like to filter the request with a RolesAllowed annotation for example
I have read this article: http://objecthunter.congrace.de/tinybo/blog/articles/89
When the user is authenticated to the web service I could persist in a database the username, and the role used for the module and the RolesAllowedResourceFilterFactory could use the realm to check if the user is in the role and can access to the resource
But can I by-passed the auth method?
Anyway I really need your help to implement this role filter thing
I will try to give you more details if you need
Thanks
The Jersey oauth filter sets the security context based on what access token was used. You just have to make sure your custom implementation of the oauth provider assigns a token with the right return values from the isInRole() method when called with various roles. The role for a given token can be established during the token authorization flow (e.g. the client can request a particular role using a custom parameter that it passes to the server when requesting a request token (this gets passed in the parameters parameter to the provider.newRequestToken() method).
The security context that the oauth filter sets will delegate to the token isInRole() method when determining the roles - and the RolesAllowedResourceFilterFactory relies on the security context. So, everything should work as expected if OAuthToken.isInRole() returns the right value. Are you facing any issues?
I know it is an old post but I was facing similar issue. In my case I solved it exactly the same way as Martin described. During token authorisation I set allowed roles:
String verifier = provider.authorizeToken(token, sContext.getUserPrincipal(), roles);
where provider is #Context DefaultOAuthProvider, token is DefaultOAuthProvider.Token and roles is a Set of roles I want to allow the access by this token:
Set<String> roles = new HashSet<String>();
roles.add("someRole");
Then in my service I just use a #Context SecurityContext method isUserInRole("someRole") which gives me true in case the user is in specified role and false if not:
if (sContext.isUserInRole("someRole")) {
....
}
Hope it will help somebody.