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.
For adding a Spring Boot Security to your Spring Boot application, we need to add the Spring Boot Starter Security dependency in our build configuration file. Maven users can add the following dependency in the pom. xml file. Gradle users can add the following dependency in the build.
If Spring Security is on the classpath, Spring Boot automatically secures all HTTP endpoints with “basic” authentication. However, you can further customize the security settings. The first thing you need to do is add Spring Security to the classpath.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With