Why does Springs OAuth2LoginAuthenticationProvider call the UserInfo Endpoint? - spring-security

I am having a hard time learning OAuth2 and OpenID Connect.
Every time I think I understand everything now, I come across another gimmick.
This time it's Spring Securities OAuth2LoginAuthenticationProvider.
The OAuth2LoginAuthenticationProvider is used instead of OidcAuthorizationCodeAuthenticationProvider if scope openid is not contained in requested scopes.
if (loginAuthenticationToken.getAuthorizationExchange().getAuthorizationRequest().getScopes().contains("openid")) {
// This is an OpenID Connect Authentication Request so return null
// and let OidcAuthorizationCodeAuthenticationProvider handle it instead
return null;
}
But why does this AuthenticationProvider load an OAuth2User via UserInfoEndpoint?
Isn't UserInfoEndpoint OIDC specific?

You are correct that OIDC defines a User-Info endpoint.
When using OAuth 2.0 to authenticate, there is still a need to figure out the user's information and so Spring Security publishes an interface (OAuth2UserService) that does that.
For non-OIDC implementations, I'd imagine that the OAuth2UserService is not pointed at an OIDC-compliant User-Info endpoint.

Related

How to implement multiple authentication methods in Spring WebFlux Security?

I'd like to provide two ways to authenticate in my application, one is basic auth (users), and the other is some kind of token based (technical users). I understand that I need a custom ReactiveAuthenticationManager but I can't find clues on the big picture. (Actually, there are a very few insights for MVC, and none for WebFlux.)
1) How do I populate the Authentication's name and credentials in the token based approach? If I configure Spring Security to use httpBasic it's already populated. Some kind of filter needed?
2) How do I distinguish in the authentication manager where the credentials are coming from? Do I have to lookup in the userRepository and (if not found) in the technicalUserRepository too?
3) Do I have to override the SecurityContextRepository? All the tutorials do it but I don't see any reason to do so. What is it exactly? This source states that "SecurityContextRepository is similar to userDetailsService provided in regular spring security that compares the username and password of the user." but I think he means ReactiveUserDetailsService (neither UserDetailsService nor ReactiveUserDetailsService does that by the way, it's just for user lookup).
Since i am decent at Webflux and i have worked a lot with oauth2 i'll try and answer some of your questions.
1) How do I populate the Authentication's name and credentials in the
token based approach? If I configure Spring Security to use httpBasic
it's already populated. Some kind of filter needed?
A token never contains credentials. A token is something you get issued after an authentication has been done. So usually you authenticate against an issuing service. After you have authenticated yourself against that service you will be issued a token.
If its an oauth2 token the token itself is just a random string. It contains no data about the user itself. When this token is sent (using the appropriate header) to a service using spring security. Spring security has a token filter that will basically check that the token is valid, usually by sending the token to the issuer and asking "is this token valid?".
If using a jwt, its different, the jwt must contain some information like issuer, scopes, subject etc. etc. but its basically the same thing, there is a built in filter that will validate the jwt by sending it to the issuer (or using a jwk that the service fetches from the issuer so it can verify the integrity of the jwt without doing an extra request).
2) How do I distinguish in the authentication manager where the credentials are coming from? Do I have to lookup in the userRepository and (if not found) in the technicalUserRepository too?
You don't You usually define multiple SecurityWebFilterChains for different url paths. I have not done this in Webflux Spring Security, but thats how you do it in regular Spring Applications, and i don't see any difference here. Unless you are doing something crazy custom.
3) Do I have to override the SecurityContextRepository? All the tutorials do it but I don't see any reason to do so. What is it exactly? This source states that "SecurityContextRepository is similar to userDetailsService provided in regular spring security that compares the username and password of the user." but I think he means ReactiveUserDetailsService (neither UserDetailsService nor ReactiveUserDetailsService does that by the way, it's just for user lookup).
The answer here is probably no. You see Spring security 4 had very bad support for oauth2 and especially JWT. So people got accustomed to writing their own JWT parsers. When spring Security 5 came, Spring implemented a jwt filter that you can configure and use built in. But there are a lot of outdated Spring Security tutorials out there and foremost there are a lot of developers that don't read the official documentation.
They mostly google tutorials and get the wrong information and then work on that.
But easy explained:
SecurityContextRepository
If you have session based authentication (server establishes a session with a client) it will store the SecurityContext (session) in ThreadLocal during a request. But as soon as the request ends, the session will go lost unless we store it somewhere. The SecurityContextPersistenceFilter will use the SecurityContextRepository to extract the session from ThreadLocal and store it, most common is to store it in the HttpSession.
AuthenticationManager
Override this if you want to do a custom authentication process. Example if you want to validate something, call a custom LDAP, database, etc etc. It\s here you perform you authentication. But remember, most standard logins (like ldap, sql-servers, basic login etc.) already have prebuilt configurable managers implemented, when you select what login type like .httpBasic() you will get a pre-implemented AuthenticationManager.
UserDetailsManager
You override this when you want create a custom UserDetails object (also usually called Principal) In the UserDetailsManager you do you database lookup and fetch the user and then build and return a UserDetails object.
Those two interfaces are the most regular custom implementations, and are used if you need to to basic authentication/session based authentication.
If you wish to do token, you have to think about, who is the token issuer? usually the issuer is separate and all services just get tokens and validate them against the issuer.
I hope this explains some of the questions. I have written this on the bus so some things are probably wrong and not 100% correct etc. etc.

What's the different between oauth2Login and oauth2Client? what are the use-case of them?

I have seen the Spring security docs.https://docs.spring.io/spring-security/site/docs/5.2.1.RELEASE/reference/htmlsingle/#oauth2 But I don't really know the different use-case between oauth2Login() and oauth2Client(). Are there any samples ?
oauth2Login() will authenticate the user with OAuth2 (or OIDC), populating Spring's Principal with the information from either the JWT or the userInfo endpoint. oauth2Client() won't authenticate the user but will seek permission from the OAuth2 authorization server for the resources (scopes) it needs to access. With oauth2Client() you'll still need to authenticate the user, for example via formLogin().
A more detailed explanation can be found here.

REST API Authentication using BootstrapContext and JWT Handler

I am using WIF 4.5 to authenticate my user and need to use the Security Token from the WIF 4.5 authentication to call a REST API.
Here is the code I am using to get the IMS Security Token for the currently logged in user.
BootstrapContext bootstrapContext = ClaimsPrincipal.Current.Identities.First().BootstrapContext as BootstrapContext;
var myToken = bootstrapContext.SecurityToken;
So, far, so good. The token exists and has the Id, ValidFrom, and ValidTo values. The Security Keys count is zero, but I am not sure if that is relevant.
Now, I need to know how to use this token to then call the REST API.
It seems like I am supposed to use the JWT Handler for this:
https://blogs.msdn.microsoft.com/vbertocci/2012/11/20/introducing-the-developer-preview-of-the-json-web-token-handler-for-the-microsoft-net-framework-4-5/
But, I am having problems getting this to work. The code on the linked to page above actually does not compile as is. Some of the properties have been changed/renamed.

Getting rid of code/state URI parameters when using OAuth2RestTemplate

I have built a simple Spring Boot application that acts as an OAuth 2.0 client using the #EnableOAuth2Client annotation. My application is creating an OAuth2RestTemplate and the OAuth dance succeeds nicely.
The problem is that when I access my application e.g. at http://localhost:8080/someRequest (where the method serving this resource uses the OAuth2RestTemplate#getObject method to retrieve some remote resources, I end up with sth. like http://localhost:8080/someRequest?code=ABC&state=DEF in my browser.
Is there a way to get rid of these parameters using some Spring configuration magic or do I have to do that myself? I saw that the sample Tonr application suffers from the same problem.
The issue is that you have to handle the callback url that u have registered with OAuth2 provider. when you transfer code and state parameter to the provider Server for access token and refresh token, the provider sends request back to ur callback URL with access token. In callback URL u now have to check if access token is available, you redirect to the original request(u need to save original request before OAuth2 dance).
I know this stuff theoretically, but didnot find Spring-Security-OAuth2 example for handling the callback URL.
I asked same question, but didnot get any answer.
OAuth2 Dance With Spring Security
However without using spring security, i found one link which shows handling callback url manually.It will help u in understanding the flow.
Google Handle callback URl
If u found any example of spring secrity handling callback url , Share with me.
I found this as an issue with spring security oAuth2. Check this JIRA Issue

Authentication and Authorization of HTTP API in Play Framework

I am building an API using the Scala version of the play framework. Some of the endpoints will contain confidential data but I am not sure how exactly to secure this.
Secure social (http://securesocial.ws/guide/configuration.html) is a library that I've been looking at but it seems oriented around websites and logging in with OAuth providers.
In this case it seems like I need to be an OAuth provider. Or is it possible that I can allow users to login with a provider, say Twitter? But then how would that work? The documentation around OAuth seems to be incredibly awful.
There is no built in way to manage tokens. I would recommend building a token system, that would distribute and manage access token use. You can have one per user, or use a different system.
Then for each endpoint, you would have a wrapped action to secure the API.
case class SecuredAPIRequest(request:Request[AnyContent]) extends
WrappedRequest(request)
trait SecuredController{
import play.api.mvc.Results._
//This takes an action for a request, and checks to see if the apiKey equals or API_KEY
def SecuredAPIAction(f:SecuredAPIRequest => Result) = Action{
request =>
request.body.asJson.map{ jsValue =>
(jsValue \ "apiKey").asOpt[String] match{
case Some(key) if validKey(key) => f(SecuredAPIRequest(request)) //We are clear to go, execute our function.
// NOTE: validKey would be a function that checks the key against our DB ensuring that it is valid.
case None => Forbidden
}
}.getOrElse(Forbidden)
}
}
What SecureSocial does is route security request to the authentication service ( Twitter, Facebook, etc ), and uses their token as security. This would not work as an API, because it would be impossible to redirect users for auth.

Resources