Spring Boot with read-only session for single sign on - java

We have a legacy Spring application (A) (that is not using spring-boot) that handles authentication and writes the session to Redis using spring-session (the data in Redis is stored as XML).
We now want to introduce a new application (B), using spring-boot 2.2.6.RELEASE and spring-session Corn-RC1, that should be useable if a user has signed into (A) with ROLE_ADMIN. I.e. this can be regarded as a very crude way of doing single sign on. A user should never be able to authenticate in B (it'd like to disable authentication if possible), it should only check that an existing user is authenticated in the session repository (redis) and has ROLE_ADMIN. Both A and B will be located under the same domain so cookies will be propagated by the browser. I've tried various different ways of getting this to work, for example:
#Configuration
#EnableWebSecurity
class ServiceBSpringSecurityConfig : WebSecurityConfigurerAdapter() {
#Autowired
fun configureGlobal(auth: AuthenticationManagerBuilder) {
auth.inMemoryAuthentication()
}
override fun configure(http: HttpSecurity) {
http
.authorizeRequests()
.anyRequest().hasRole("ADMIN")
.and()
.formLogin()
.and()
.httpBasic().disable()
}
}
but this will show the default login screen:
I've also tried removing this part entirely:
#Autowired
fun configureGlobal(auth: AuthenticationManagerBuilder) {
auth.inMemoryAuthentication()
}
but then it'll generate a default user and password and it does not seem to call the configure method (or the configuration doesn't work regardless).
How can I solve this?

What you need is to disable formLogin and httBasic on Application B and add a filter before spring's authentication filter AnonymousAuthenticationFilter or UsernamePasswordAuthenticationFilter. In the custom filter you will extract the cookie/header/token from the request object and based on that reach out to the redis cache for session details. This filter would then validate the session and create object of type org.springframework.security.core.Authentication and set that in the current SpringSecurityContext.
Below is the sudo code for this;
ServiceBSpringSecurityConfig
#Configuration
#EnableWebSecurity
public class ServiceBSpringSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(authEntryPoint()).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.httpBasic().disabled().and()
.formLogin().disabled().and()
.authorizeRequests().anyRequest().hasRole("ADMIN")
http.addFilterBefore(authTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
#Bean
public AuthTokenFilter authTokenFilter() {
return new AuthTokenFilter();
}
#Bean
public AuthEntryPoint authEntryPoint() {
return new AuthEntryPoint()
}
}
AuthEntryPoint
public class AuthEntryPoint implements AuthenticationEntryPoint {
private static final Logger logger = LoggerFactory.getLogger(AuthEntryPoint.class);
#Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
// Very generic authEntryPoint which simply returns unauthorized
// Could implement additional functionality of forwarding the Application A login-page
logger.error("Unauthorized error: {}", authException.getMessage());
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Error: Unauthorized");
}
}
AuthTokenFilter
public class AuthTokenFilter extends OncePerRequestFilter {
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// extract some sort of token or cookie value from request
token = request.getHeader("Token");
if (token != null) {
// Validate the token by retrieving session from redis cache
// Create org.springframework.security.core.Authentication from the token
Authentication auth = authFactory.getAuthentication(token);
// Set the spring security context with the auth
SecurityContextHolder.getContext().setAuthentication(auth);
} else {
// Do something if token not present at all
}
// Continue to to filter chain
filterChain.doFilter(request, response);
}
}
As mentioned this is sudo code so some adjustment might be required. However the general gist of token based auth remains the same.

Related

Spring SAML redirecting to a different URL

I employed this spring boot SAML sample project to my existing project. But I noticed that the redirect url will be automatically set as the url where I get redirected to the log in page. I am wondering is there anyway for me to change this redirect url to a different one? The base url that will trigger redirection to the auth page is a http link but I need to redirect to a https link after logging in. (Now I am not able to move forward to the page where I can input credentials. I am blocked by the invalid url error.) For now I tried create a custom LoginSuccessHandler that implements AuthenticationSuccessHandler .
#Component
public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler{
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
redirectStrategy.sendRedirect(request, response,"/testing");
}
}
And I had this in the saml config
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.authenticationEntryPoint(samlEntryPoint());
http
.addFilterBefore(metadataGeneratorFilter(), ChannelProcessingFilter.class)
.addFilterAfter(samlFilter(), BasicAuthenticationFilter.class)
.addFilterBefore(samlFilter(), CsrfFilter.class);
http
.authorizeRequests()
.antMatchers("/api/**").permitAll()
.anyRequest().authenticated().and().formLogin().successHandler(successHandler);
http
.logout()
.disable(); // The logout procedure is already handled by SAML filters.
}
But this doesn't work. The redirect url does't get changed to what I specified ("/testing"). While using Inteli J debugging mode, it seems that this custom class is not being executed. So I am suspecting I had the wrong way calling this class. Then I also tried provided this LoginSuccessHandler class to samlWebSSOProcessingFilter, which also made no difference.
#Bean
public SAMLProcessingFilter samlWebSSOProcessingFilter() throws Exception {
SAMLProcessingFilter samlWebSSOProcessingFilter = new SAMLProcessingFilter();
samlWebSSOProcessingFilter.setAuthenticationManager(authenticationManager());
samlWebSSOProcessingFilter.setFilterProcessesUrl("/spring-security-saml2-sample");
samlWebSSOProcessingFilter.setAuthenticationSuccessHandler(successRedirectHandler());
return samlWebSSOProcessingFilter;
}
You need to do the following changes to redirect to desired URL.
First inject the dependency LoginSuccessHandler in the WebSecurityConfig file
#Autowired
private LoginSuccessHandler loginSuccessHandler;
and then update the SAMLProcessingFilter as mentioned below
// Processing filter for WebSSO profile messages
#Bean
public SAMLProcessingFilter samlWebSSOProcessingFilter() throws Exception {
SAMLProcessingFilter samlWebSSOProcessingFilter = new SAMLProcessingFilter();
samlWebSSOProcessingFilter.setAuthenticationManager(authenticationManager());
samlWebSSOProcessingFilter.setAuthenticationSuccessHandler(loginSuccessHandler);
samlWebSSOProcessingFilter.setAuthenticationFailureHandler(authenticationFailureHandler());
return samlWebSSOProcessingFilter;
}
then do the following change in the LoginSuccessHandler
#Component
public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
// Add your server URL below.
String redirectUri = "https://{server}/testing";
response.sendRedirect(redirectUri);
}
}

How do i write a WebSecurityConfigurerAdapter correctly when using a JWT filter?

I'm struggling to implement the jwt authentication while i understand (i think so) the theory behind it.
The whole idea is to send a jwt token every time user wants to access personal data through backend secured endpoints, instead of sending the credentials every time.
My backend is based on this repo. I have edited the code for my needs:
JwtTokenFilter.java
public class JwtTokenFilter extends OncePerRequestFilter {
private JwtTokenProvider jwtTokenProvider;
public JwtTokenFilter(JwtTokenProvider jwtTokenProvider) {
this.jwtTokenProvider = jwtTokenProvider;
}
#Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
FilterChain filterChain) throws ServletException, IOException {
// Save initial path. Since CustomErrorController always uses /error path
// we can't retrieve the initial path using httpRequest.getRequestURI() method
httpServletRequest.setAttribute("initialPath", httpServletRequest.getRequestURI());
if (httpServletRequest.getHeader("Authorization") == null) {
throw new TokenException("Authorization field is empty.");
}
String token = jwtTokenProvider.resolveToken(httpServletRequest);
if (token == null) {
throw new TokenException("Non Bearer Token");
}
// throws TokenException
jwtTokenProvider.validateToken(token);
// throws NoUserFoundException
Authentication auth = jwtTokenProvider.getAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(auth);
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
}
WebSecurityConfig.java
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private JwtTokenProvider jwtTokenProvider;
#Override
protected void configure(HttpSecurity http) throws Exception {
// Disable CSRF (cross site request forgery)
http.csrf().disable();
// No session will be created or used by spring security
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// Entry points
// http.authorizeRequests()
// .antMatchers("/signin").permitAll()
// .antMatchers("/signup").permitAll()
// Disallow everything else..
// .antMatchers("/profile").authenticated();
// If a user tries to access a resource without having enough permissions
// http.exceptionHandling().accessDeniedHandler((request, response, accessDeniedException) -> {
// System.out.println("**************** INSIDE HANDLEEEEEEEEER");
// response.sendError(417);
// });
// IMPORTANT!!!
// DO I NEED THESE???
// http.authorizeRequests().antMatchers("/signin", "signup").permitAll();
// http.authorizeRequests().antMatchers("/signin", "signup").hasAnyRole("ADMIN", "USER");
// http.authorizeRequests().antMatchers("/signin", "signup").hasAnyRole("ADMIN");
// http.authorizeRequests().antMatchers("/profile").authenticated();
http.antMatcher("/profile").apply(new JwtTokenFilterConfigurer(jwtTokenProvider));
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
Here are my questions:
See the commented out code on the WebSecurityConfigurerAdapter. First of, it doesn't seem to work. But even if it did, it wouldn't make sense.
We want the jwt filter to be applied only to specific urls. It wouldn't make sense to ask for a token when everyone has the right to sign up or sign in. The last line inside WebSecurityConfigurerAdapter applies the filter only on the /profile endpoint.
The jwt token contains (if it is valid) the username. When extracted, we search for that user on the database. This user object contains its' role. So, in order to have a user's role we MUST pass through the jwt filter in order to validate it and THEN find the saved user.
So why the code doesn't work at all?
Is the commented code really useless or am i missing something? How would it be possible to authenticate the user before even applying the jwt filter?

Toggle Spring Security for the requests with particular Request Header

I am trying to toggle/bypass/disable Spring Security (Authentication and Authorization) for all the requests having particular Request Header.
For example, if a request url is hit with that Request Header, Spring Security should be bypassed, if not it should not be bypassed.
For this, I am using following requestMatchers Spring Security config:
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.GET)
.antMatchers(HttpMethod.OPTIONS)
.requestMatchers(new RequestHeaderRequestMatcher("TEST-HEADER","TEST-VALUE"));
}
My remaining Security Config is :
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity (prePostEnabled = true)
#ConditionalOnProperty (name = "security.enabled", havingValue = "true", matchIfMissing = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private SecurityProps securityProps;
#Autowired
private MyUserDetailsService myUserDetailsService;
#Autowired
private MyAuthenticationEntryPoint myAuthenticationEntryPoint;
#Autowired
private MyCORSFilter myCORSFilter;
public SecurityConfig() {
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf().disable()
.addFilterBefore(myCORSFilter, SessionManagementFilter.class)
.addFilterBefore(requestHeaderFilter(), RequestHeaderAuthenticationFilter.class)
.authenticationProvider(preauthAuthProvider())
.authorizeRequests()
.antMatchers(HttpMethod.GET, securityProps.getNoAuthGetPattern()).permitAll()
.antMatchers(HttpMethod.OPTIONS, securityProps.getNoAuthOptionsPattern()).permitAll()
.requestMatchers(new RequestHeaderRequestMatcher("TEST-HEADER","TEST-VALUE")).permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(myAuthenticationEntryPoint);
}
#Autowired
#Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(preauthAuthProvider());
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.GET)
.antMatchers(HttpMethod.OPTIONS)
.requestMatchers(new RequestHeaderRequestMatcher("TEST-HEADER","TEST-VALUE"));
}
public RequestHeaderAuthenticationFilter requestHeaderFilter() throws Exception {
RequestHeaderAuthenticationFilter requestHeaderAuthenticationFilter = new RequestHeaderAuthenticationFilter();
requestHeaderAuthenticationFilter.setPrincipalRequestHeader(MySecurityConstants.LOGIN_HEADER);
requestHeaderAuthenticationFilter.setAuthenticationManager(authenticationManager());
requestHeaderAuthenticationFilter.setExceptionIfHeaderMissing(false);
requestHeaderAuthenticationFilter.setAuthenticationFailureHandler(new AuthenticationFailureHandler() {
#Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
if (exception instanceof MySecurityException) {
myAuthenticationEntryPoint.commenceMySecurityException(request, response, (MySecurityException) exception);
} else if (exception instanceof UsernameNotFoundException) {
myAuthenticationEntryPoint.commenceUsernameNotFoundException(request, response,
(UsernameNotFoundException) exception);
} else if (exception instanceof PreAuthenticatedCredentialsNotFoundException) {
myAuthenticationEntryPoint.commence(request, response, exception);
}
}
});
return requestHeaderAuthenticationFilter;
}
#Bean
public PreAuthenticatedAuthenticationProvider preauthAuthProvider() throws Exception {
PreAuthenticatedAuthenticationProvider authProvider = new PreAuthenticatedAuthenticationProvider();
authProvider.setPreAuthenticatedUserDetailsService(userDetailsServiceWrapper());
return authProvider;
}
#Bean
public UserDetailsByNameServiceWrapper<PreAuthenticatedAuthenticationToken> userDetailsServiceWrapper()
throws Exception {
UserDetailsByNameServiceWrapper<PreAuthenticatedAuthenticationToken> wrapper =
new UserDetailsByNameServiceWrapper<>();
wrapper.setUserDetailsService(ivyUserDetailsService);
return wrapper;
}
}
With the above settings, I am unable to disable/bypass Spring Security and I am getting the AuthenticationCredentialsNotFoundException exception:
org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
Can anyone help me by identifying what am I doing wrong? Is my approach correct or I need to do something else to achieve this?
EDIT :
I am getting this exception in org.springframework.security.access.intercept.AbstractSecurityInterceptor class in beforeInvocation() method where it tries to get the authentication object from SecurityContextHolder. AbstractSecurityInterceptor is invoked by its subclass MethodSecurityInterceptor which is invoked from my Spring Controller which is annotated with #PreAuthorize.
I think your bypass is working fine. Its skipping the check.
The security's authorization check part gets the authenticated object from SecurityContext, which will be set when a request gets through the spring security filter.
So when you skip security filter SecurityContext is not set yet thus the error
You can do something like this to set it manually for your Custom Header Case
try {
SecurityContext ctx = SecurityContextHolder.createEmptyContext();
SecurityContextHolder.setContext(ctx);
ctx.setAuthentication(event.getAuthentication());
} finally {
SecurityContextHolder.clearContext();
}
Edit 1:
Answering all the queries.
But if thats the case, then I guess all GET call should also have
failed, but my GET calls are working fine.
Since you have added this line All your GET calls are skipped from security check.
.antMatchers(HttpMethod.GET, securityProps.getNoAuthGetPattern()).permitAll()
where can I add the code you have mentioned? Any particular filter or
somewhere else ?
I have done something like this in a Filter.
Refer Here
Look at TokenAuthenticationFilter Class in Answer. Where am manually setting.
Note: Its JWT implementation but good to refer
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (tokenHelper.validateToken(authToken, userDetails)) {
// create authentication
TokenBasedAuthentication authentication = new TokenBasedAuthentication(userDetails);
authentication.setToken(authToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
What is event in your answer?
I just got that case from Some Answer, cant find its link now. But you can setAuthentication like this or like above
Authentication authentication = new PreAuthenticatedAuthenticationToken("system", null);
authentication.setAuthenticated(true);
context.setAuthentication(authentication);

Configuring an AuthenticationSuccessHandler with Spring Boot 1.3.2 (without spring-cloud-security) and #EnableOAuth2Sso

We have a Spring Boot 1.3.2/Webflow web app which we're converting to use SSO. I've followed the steps in the "Migrating OAuth2 Apps from Spring Boot 1.2 to 1.3" blog and have the app handing off to our Auth server for authentication and the web app using the token to populate it's security context correctly.
The only piece not working is the custom authentication success handler we have that configures a few bits in the users session before they continue to their landing page.
This is currently configured as follows in our security config, which extends WebSecurityConfigurerAdapter
#Override
protected void configure(HttpSecurity http) throws Exception {
// These are all the unprotected endpoints.
http.authorizeRequests()
.antMatchers(new String[] { "/", "/login", "/error",
"/loginFailed", "/static/**" })
.permitAll();
// Protect all the other endpoints with a login page.
http.authorizeRequests().anyRequest()
.hasAnyAuthority("USER", "ADMIN").and().formLogin().loginPage("/login").failureUrl("/loginFailed")
.successHandler(customAuthenticationSuccessHandler()).and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
http.exceptionHandling().accessDeniedHandler(new AccessDeniedHandler() {
#Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException, ServletException {
if (accessDeniedException instanceof CsrfException) {
response.sendRedirect(request.getContextPath() + "/logout");
}
}
});
}
I can see the handler being configured during startup, but it is never called once the user has successfully logged in.
All of the questions I've found on the subject refer to using a OAuth2SsoConfigurerAdapter, however as we're no longer using spring-cloud-security this class is not available.
UPDATE: I've discovered that this is possible using a BeanPostProcessor:
public static class DefaultRolesPrefixPostProcessor implements BeanPostProcessor, PriorityOrdered {
#Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof FilterChainProxy) {
FilterChainProxy chains = (FilterChainProxy) bean;
for (SecurityFilterChain chain : chains.getFilterChains()) {
for (Filter filter : chain.getFilters()) {
if (filter instanceof OAuth2ClientAuthenticationProcessingFilter) {
OAuth2ClientAuthenticationProcessingFilter oAuth2ClientAuthenticationProcessingFilter = (OAuth2ClientAuthenticationProcessingFilter) filter;
oAuth2ClientAuthenticationProcessingFilter
.setAuthenticationSuccessHandler(customAuthenticationSuccessHandler());
}
}
}
}
return bean;
}
}
Is there a better way to configure this though?
If you follow Dave Syers excellent Spring boot oauth2 tutorial, you will end up with a method that returns your ssoFilter
I added a setAuthenticationSuccessHandler to this filter
#Autowired
private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;
private Filter ssoFilter() {
OAuth2ClientAuthenticationProcessingFilter facebookFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/facebook");
OAuth2RestTemplate facebookTemplate = new OAuth2RestTemplate(facebook(), oauth2ClientContext);
facebookFilter.setRestTemplate(facebookTemplate);
facebookFilter.setTokenServices(new UserInfoTokenServices(facebookResource().getUserInfoUri(), facebook().getClientId()));
facebookFilter.setAuthenticationSuccessHandler(customAuthenticationSuccessHandler);
return facebookFilter;
}
And my CustomAuthenticationSuccessHandler was just a component that extended AuthenticationSuccessHandler
#Component
public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
//implementation
}
}

How to configure Spring Security for a single page application?

I faced with a problem configuration Spring Security for single page application.
So, defualt config looks like
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
#Qualifier("customUserDetailsService")
UserDetailsService userDetailsService;
#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/list").permitAll()
.antMatchers("/admin/**").access("hasRole('ADMIN')")
.and().formLogin().loginPage("/login").permitAll()
.usernameParameter("ssoId").passwordParameter("password")
.and().csrf()
.and().exceptionHandling().accessDeniedPage("/Access_Denied");
}
#Bean(name="authenticationManager")
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
From the documentation for the methods for Login().loginPage("/login") says the it use for redirecting to the login page. For single page this configuration doesn't relevant.
How I should configure spring for single page application? I mean how to configure login, logout in controller and in configuration file.
Spring Lemon can be a complete example for this, but let me summarize the things below.
By default, when a user successfully logs in, Spring Security redirects him to the home page. When a login fails, or after a successful logout, the user is redirected back to the login page. Also, on trying to access URLs for which a user does not have sufficient rights, he is redirected to the login page.
As you say, this behavior won't suit for single page applications. Your API should instead send a 200 response along with the user data, or a 4xx response. This can be done by supplying your own handlers, like this:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
...
.successHandler(your authentication success handler object)
.failureHandler(your authentication failure handler object)
.and()
.logout()
...
.logoutSuccessHandler(your logout success handler object)
.and()
.exceptionHandling()
.authenticationEntryPoint(new Http403ForbiddenEntryPoint())
...
}
You will find many examples in the Internet on how to code these handler classes. For example, in the spring-lemon project, these are coded as below.
Authentication Success Handler
#Component
public class AuthenticationSuccessHandler
extends SimpleUrlAuthenticationSuccessHandler {
#Autowired
private ObjectMapper objectMapper;
#Autowired
private LemonService<?,?> lemonService;
#Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication authentication)
throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_OK);
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
AbstractUser<?,?> currentUser = lemonService.userForClient();
response.getOutputStream().print(
objectMapper.writeValueAsString(currentUser));
clearAuthenticationAttributes(request);
}
}
In summary, it returns a 200 response with the JSONified current-user in the response data.
Authentication Failure Handler
In fact, there is no need to code a class for the authentication failure handler - the SimpleUrlAuthenticationFailureHandler provided by Spring, if instantiated without any arguments, works as desired.
Logout Success Handler
public class LemonLogoutSuccessHandler
implements LogoutSuccessHandler {
#Override
public void onLogoutSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_OK);
}
}
For a detailed example, referring Spring Lemon's LemonWebSecurityConfig class and other classes in it's security packages of various modules can be helpful.

Categories