Accessing user name in SAML SSO failure handler in spring - spring-saml

I am using a spring SAML for intergrating spring SAML SSO. The issue I am facing right now is how to get the user name in my custom SimpleUrlAuthenticationFailureHandler.
I have created my own SimpleUrlAuthenticationFailureHandler and onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) method how do i get the access to the username over here ?

Related

Retrieve Entire SAML Response in Spring Security SAML Extension

I have a Spring Boot application that is setup as a Service Provider. My end goal is to be able to call the AWS STS Assume Role with SAML service to generate AWS temporary credentials on behalf of the user with the SAML response used to initially authenticate users of my application.
I found this other question. With that answer I am able to get only the assertion, not the entire response. From my testing, the AWS API call linked above wants the entire response, not just the assertion piece.
I used this Chrome Extension to view the SAML response. When I include everything (outline below)
<samlp:Response>
...
<saml:Assertion>
...
</saml:Assertion>
</samlp:Response>
The AWS STS Assume Role with SAML works. The other related question's answer only provides me the
<saml:Assertion>...</saml:Assertion>
block and the AWS STS Assume Role with SAML fails.
So my question is how do I get the entire SAML Response XML object back in a controller of my Spring Boot application?
I don't know any direct way in spring-security-saml, but maybe you could try to implement your own SAMLProcessingFilter ie simply extending the existing one and overriding the method attemptAuthentication().
Principle:
In this method, you have access to the response returned from the IdP and post back to the SP (at least in a Redirect-POST profile)
You probably have a way to extract what you need from the httpRequest
Then you can store (session, ThreadLocal variable, ...)
And finally you delegate the authentication process to the parent (by calling super.attemptAuthentication())
`
#Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if ("POST".equalsIgnoreCase(request.getMethod())) {
String samlResponse = request.getParameter("SAMLResponse");
System.out.println("Original SAML Response (base64 decoded) : " + new
String(Base64.getDecoder().decode(samlResponse), StandardCharsets.UTF_8));
}
return super.attemptAuthentication(request, response);
}
`

spring 5 - Oauth2 server get current user

I have build a Spring boot oauth2 server using spring 5. The oauth server works and I can login using basic auth and username/password. I get a bearer token and I can verify the token using the /oauth/check_token url.
In the same Spring boot project I want to add an endpoint that will print out the authenticated user information so that oauth2 clients can get information over the logged in user. I created an endpoint /user and it looks like this:
#GetMapping("/user")
#ResponseBody
public Principal user(Principal user) {
return user;
}
I startup postman so that I can do the api calls and such, call /oauth/token and I receive a token. I then start a new request, set the authentication method to bearer token and fill in the received bearer token. I do a GET call to the url (http://localhost:8080/user) and it turns out the principal is always null. I know because I can debug my application in Spring tool suite and Principal is always empty. I have also tried:
OAuth2Authentication oAuth2Authentication = (OAuth2Authentication)SecurityContextHolder.getContext() .getAuthentication();
That is empty as well. How can I create an endpoint that will print the user info so that clients can set the userInfoUri property.
I have the answer. I'll post it here just in case someone else runs into this problem.
I have a ResourceServerConfigurerAdapter with the following configure in it:
public void configure(HttpSecurity http) throws Exception {
http.anonymous()
.disable()
.requestMatchers()
.antMatchers("/api/user/**").and().authorizeRequests()
.antMatchers("/user").authenticated()
// More rules here
The reason it didn't work because of the first antMatchers("/api/user/**"). I changed it into this:
http.anonymous()
.disable()
.requestMatchers()
.antMatchers("**").and().authorizeRequests()
I believe that the first antMatchers determines the path in which it forces authorizeRequests (Enabling oauth2 security in that path) so if the first path is .antMatchers("/api/user/**") after that is .antMatchers("/user") then it won't match and the /user url won't have the oauth2 security enabled.

JWT and Spring Security

I've built a REST Service using Spring Boot and Spring Security for authentication. I'm pretty new to both Spring Boot and Spring Security. I've made one authentication module in one JAR file. The front end client sends a request with username and password to the authentication module. The authentication module then authenticates the user's details against a DB. A JWT is created and then sent back to the client if the authentication is successful. The username and role is coded into the JWT. The JWT is then used to verify the user when resources are requested from the other REST Service endpoints that are built in separate JAR files. There are a few things I'm not sure about.
In Spring Security is there one authentication object created for each user so that several users can be authenticated at the same time or is one authentication done each time and only one user can be logged in?
How long is the authentication object in valid? Should I "logout"/remove the authentication successful when the JWT has been created in the authentication module or will it take care of it itself when the request is done? For the resource endpoints (not the authentication endpoint) is there a way to set authentication successful in the authentication object once I've verified the JWT? Similarly can I set the role in the authentication object once the JWT has been verified?
I've based my code on this example https://auth0.com/blog/securing-spring-boot-with-jwts/. I've split it into different JARs for authentication and verification of the JWT (I'm doing verification in resource endpoint). I've also added JDBC authentication instead of in memory authentication.
In Spring Security is there one authentication object created for each
user so that several users can be authenticated at the same time or is
one authentication done each time and only one user can be logged in?
Of course multiple users can be authenticated at the same time!
How long is the authentication object in valid? Should I
"logout"/remove the authentication successful when the JWT has been
created in the authentication module or will it take care of it itself
when the request is done?
You write your service is REST, and if you want to stay "puritan" REST you should configure the authentication to be stateless, which means that the Authentication object is removed when the request has been processed. This does not affect the validity of the JWT token, you can set an expiry of JWT token if you want.
How to make REST stateless with "Java config":
#Configuration
public static class RestHttpConfig extends WebSecurityConfigurerAdapter
{
#Override
protected void configure(HttpSecurity http) throws Exception
{
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// and the rest of security config after this
For the resource endpoints (not the authentication endpoint) is there
a way to set authentication successful in the authentication object
once I've verified the JWT? Similarly can I set the role in the
authentication object once the JWT has been verified?
I use code similar to below after verification of the token:
Collection<? extends GrantedAuthority> authorities = Collections.singleton(new SimpleGrantedAuthority("ROLE_JWT"));
Authentication authentication = new PreAuthenticatedAuthenticationToken(subject, token, authorities);
SecurityContextHolder.getContext().setAuthentication(authentication);
By constructing the authentication object with at least one role (authority), it is marked as "successful" (authenticated).

Spring Security Sequence of execution

I am not able to find out where and when exactly the authentication manager is executed by spring security. I mean there are certian filters which are executed sequentially as below:
FIRST
- CHANNEL_FILTER
- CONCURRENT_SESSION_FILTER
- SECURITY_CONTEXT_FILTER
- LOGOUT_FILTER
- X509_FILTER
- PRE_AUTH_FILTER
- CAS_FILTER
- FORM_LOGIN_FILTER
- OPENID_FILTER
- BASIC_AUTH_FILTER
- SERVLET_API_SUPPORT_FILTER
- REMEMBER_ME_FILTER
- ANONYMOUS_FILTER
- EXCEPTION_TRANSLATION_FILTER
- SESSION_MANAGEMENT_FILTER
- FILTER_SECURITY_INTERCEPTOR
- SWITCH_USER_FILTER
- LAST
But when exactly authentication provider authenticates the provided username and password, i mean to ask after which these below filters is the authentication provider is executed .
Regards
Jayendra
From Spring Security documentation:
The order that filters are defined in the chain is very important.
Irrespective of which filters you are actually using, the order should
be as follows:
ChannelProcessingFilter, because it might need to redirect to a different protocol
SecurityContextPersistenceFilter, so a SecurityContext can be set up in the SecurityContextHolder at the beginning of a web request, and
any changes to the SecurityContext can be copied to the HttpSession
when the web request ends (ready for use with the next web request)
ConcurrentSessionFilter, because it uses the SecurityContextHolder functionality but needs to update the SessionRegistry to reflect
ongoing requests from the principal
Authentication processing mechanisms - UsernamePasswordAuthenticationFilter, CasAuthenticationFilter,
BasicAuthenticationFilter etc - so that the SecurityContextHolder can
be modified to contain a valid Authentication request token
The SecurityContextHolderAwareRequestFilter, if you are using it to install a Spring Security aware HttpServletRequestWrapper into your
servlet container
RememberMeAuthenticationFilter, so that if no earlier authentication processing mechanism updated the SecurityContextHolder,
and the request presents a cookie that enables remember-me services to
take place, a suitable remembered Authentication object will be put
there
AnonymousAuthenticationFilter, so that if no earlier authentication processing mechanism updated the SecurityContextHolder,
an anonymous Authentication object will be put there
ExceptionTranslationFilter, to catch any Spring Security exceptions so that either an HTTP error response can be returned or an
appropriate AuthenticationEntryPoint can be launched
FilterSecurityInterceptor, to protect web URIs and raise exceptions when access is denied
So the authentication manager is called at step 4. If you look at the source code of UsernamePasswordAuthenticationFilter you will see something like:
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
// ...
return this.getAuthenticationManager().authenticate(authRequest);
}

Access Denied Spring Security with javaconfig

I hope you could give me a hand with the following:
I am using spring security and spring MVC to build a web app, and I need to redirect the flow to the login page, once there is a try to access a forbidden resource (403 HTTP status code).
Now, spring Security already does the work of preventing from unauthorized access to every resource I've exposed in my Restful API (#RestController), and responding with the proper 403 default page. But as I need to redirect to the login page, I need to push spring security to do a redirect instead of sending a 403. In this regard I've been trying to do the following but I haven't been able to make it works:
Setting the HttpSecurity bean to manage the exception when accessing a denied page:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().exceptionHandling().accessDeniedPage("/security/403");
}
Now, I set my controller to catch /security/403 URL
// for 403 access denied page
#RequestMapping(value = "/security/403", method = RequestMethod.GET)
public void accesssDenied() {
//Do stuff here, redirecting or whatever.
}
thanks
Create a new class that acts as an Interceptor.
This class will implement the HandlerInterceptor interface and override the following methods:
From the documentation:
preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) – Intercept the execution of a handler (called just before the controller).
postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) – called immediately after the controller
afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler) – called just before sending response to view
In your case, use the preHandle() method to check if the client is trying to access a forbidden resource and if so, redirect the client to the login page. In fact, this is one of the most common paradigms where an Interceptor is used to handle the flow of execution.

Resources