Is it possible to have a login rest service that authenticates with Spring Security the container security and if successful then returns a JWT Token. Call to other services then would use JWT Filter.
The basic idea is this.
I have React Application that has a login Page. It sends a login request (via rest service) with username and password. The security is container based (an example would be Tomcat users). Spring security should authenticate via container and if the username and password are ok, then the login service returns a JWT Token.
All other services use Spring Security JWT Token Filter security.
I can't find examples of this situation when I google.
What you are trying to find is what Spring Security calls Pre-Authentication.
You can enable it for different scenarios, I will show an example Java EE container.
#Bean
SecurityFilterChain appSecurity(HttpSecurity http) throws Exception {
http
...
.jee(Customizer.withDefaults())
...
return http.build();
}
What the jee() will do is registering a J2eePreAuthenticatedProcessingFilter in your SecurityFilterChain, and the filter itself will extract the Principal from the HttpServletRequest and call the PreAuthenticatedAuthenticationProvider to authenticate it.
Then, in your controller, you can inject the Principal and build the JWT using the Principal's details.
Related
I have an application set up as follows:
Angular UI -> Spring Cloud Gateway -> Spring Boot-based Service
I am attempting to authenticate my application against a limited Oauth SSO server with ONLY the following endpoints:
/authorize
/token
/userdata
The SSO does not provide an /introspect endpoint, nor does it issue JWTs.
What I would like to do is have Spring Cloud Gateway handle the authentication, but based on the result from /userdata, I would like to generate my own JWT to relay to the service.
My questions:
Is this possible?
If so, can someone give pointers or guide me to the resources that will get me started?
Spring Security OAuth2.0 Client and Spring Cloud Gateway combination works well in this case.
Client(Angular UI) requests to the Gateway service with OAuth2.0 login URL
The Gateway redirects the request to Identity Provider(Such as Google) login page.
After user login successful Identity Provider redirects the request to the Gateway with user info.
On Authentication success handler(Gateway service)
Parse user info and save it to somewhere
Create access token and refresh tokens. Set them to request cookies
Redirect to client(Angular UI)
I don't know the reason to pass the token downstream services at this point. If there is no specific requirement then I would implement all the security related operations on the Gateway service. Such as token generation, validation etc. This way new services can be easily added without concerning about authentication and authorization.
Here is a sample project.
I deployed a Standalone Keycloak (KC) server and I developed one API that acts as a resource server(it is not supposed to handle login/registration of users etc) with Spring Boot. I want this API to be secured with KC JWT tokens. I expect every user coming has already obtained a JWT token. To the security configurations of my API I added the following configuration:
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8180/auth/realms/<REALM_NAME>.
Everything works as expected, my API is able to allow only authenticated and authorized users to call the endpoints. However, I have the following question:
As my configurations are right now, anyone who receives a token from my KC server and the issuer-uri can build another API and do her/his own stuff. How is it possible to restrict the KC server in order to be used only from APIs that I allow? E.g: my API should provide a client_name and a client-secret before it is allowed to verify a token with the issuer.
I am using spring-boot-starter-oauth2-resource-server to configure OAuth2 instead of the one that Keycloak provides. I am running Spring Boot 2.4, Spring Security 5 and Keycloak 12.0.4.
I have created 2 JHipster applications (JHipster v6.3.1):
Microservice Gateway
authenticationType: oauth2
Microservice Application
authenticationType: jwt
I have configured Okta with the gateway app and this works fine, I can log in with my user. I can also see that the ROLE_ADMIN and ROLE_USER authorities are being correctly assigned in Spring Security.
However I get the following error from the Microservice Application when I attempt to add/view an entity:
Unsupported JWT token.
Unauthorized: Full authentication is required to access this resource
Is there some configuration I need to do to get the JWT token passed in to the Microservice Application?
You cannot mix authentication types between microservice apps. You have to use either OAuth 2.0 or JWT in all of them. FWIW, JHipster's OAuth 2.0 support does use JWTs.
I am working on integrating Spring Security SAML into our existing security infrastructure, to handle partner SSO. I am looking at the sample app that comes with Spring Security SAML as a template.
I see that in SAML, the SP must specify the AssertionConsumerServiceBinding to provide the return url to which the IdP will send the AuthenticationResponse.
With the Spring Security SAML sample, we set this to:
http://localhost:8080/spring-security-saml2-sample/saml/SSO.
However, after the IdP posts the AuthenticationResponse back to that url, the user's browser is redirected to
http://localhost:8080/spring-security-saml2-sample.
Can I specify a specific url to which the user will be redirected after the SSO authentication succeeds? I am not finding any documentation on this and am not seeing how it happens in the sample app.
One specifies the url to which the user should be routed after successful authentication via the defaultTargetUrl value in the successRedirectHandler bean's definition.
I'm using the Spring Security SAML extension for my SP. After a user is authenticated from the IDP, the SP uses some sort of method to allow subsequent calls to not have to be reauthenticated with the IDP. How is this done in the Spring Security SAML extension?
A related question:
Authenticating mobile users against SAML IDP
In the accepted answer from the above related question, the SP should create a token and pass it back to the client for future requests. I'm not seeing anything like this when watching the flow in Chrome's Network Tool. What should I be looking for?
Update 1: I'm coming to the conclusion that Spring SAML doesn't pass anything back to a browser in the form of a token. It must be keeping track of the user on the server side. Can I get confirmation on this? Is it possible to generate a token to pass back to the client in the case of a REST call?
Spring SAML is relaying on Spring Security for handling of user's authentication state. By default user state is stored in SecurityContext and Authentication objects which are put into user's HTTP Session (identified by secure cookie typically JSESSIONID which is passed to the browser). You'll be able to find all details related to this in the Spring Security documentation.
In case your user is calling REST APIs from browser where she authenticated, and the API is deployed together with the Spring Security application, the call will be providing same cookies as you would get for normal server calls and they will be authenticated using the same mechanism without need for any tokens.
In case you want to perform calls to a 3rd party REST API where you have not established a session or authenticated using other means, one way to secure such scenario is e.g. issue and use OAuth 2.0 Bearer tokens.
After the user is authenticated from the IDP, the IDP sends back a SAML assertion to the SP. The Spring Security SAML extension validates this assertion.
If the validation is successful, Spring Security establishes a user session, which is generally persisted through the cookie mechanism.
In the case of a REST service, your suggestion is basically what is done on OAuth-enabled REST services. The client sends an authorization token with each request.