Hi Folks,
This article is quick overview of how to use Spring boot security basic login with In-Memory authentication. Its a web based application, when user browse the application a spring security based Login Form presented to the user.
The Maven dependencies are:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Once these dependenceis added in POM.xml file next step to do Spring security Java side configuration.
To integrate spring security, we need to extend WebSecurityConfigurerAdapter class. Also annoted class with @EnableWebSecurity annotation to get Spring security support.
Code Snippet: showing in-memory authentication and defined 3 users.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user1").password(passwordEncoder().encode("user1Pass")).roles("USER")
.and()
.withUser("user2").password(passwordEncoder().encode("user2Pass")).roles("USER")
.and()
.withUser("admin").password(passwordEncoder().encode("adminPass")).roles("ADMIN");
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/anonymous*").anonymous()
.antMatchers("/login*").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginProcessingUrl("/perform_login")
.defaultSuccessUrl("/", true)
.failureHandler(new CustomAuthenticationFailureHandler())
.and()
.logout()
.logoutUrl("/perform_logout")
.deleteCookies("JSESSIONID")
.logoutSuccessHandler(new CustomLogoutSuccessHandler());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
We overridden the configure method and starting with Spring 5, we also have to define a password encoder. In our example, we’ve used the BCryptPasswordEncoder.
Here I haven’t customized the login page, the spring security displayed its own login page at /login URL. To customize the same use formLogin().loginPage(“/login.html”)
defaultSuccessUrl() – to specify landing page after a successful login
The CustomAuthenticationFailureHandler class is as below:
public class CustomAuthenticationFailureHandler
implements AuthenticationFailureHandler {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void onAuthenticationFailure(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException exception)
throws IOException, ServletException {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
Map<String, Object> data = new HashMap<>();
data.put(
"timestamp",
Calendar.getInstance().getTime());
data.put(
"exception",
exception.getMessage());
response.getOutputStream()
.println(objectMapper.writeValueAsString(data));
}
}
And the CustomLogoutSuccessHandler class is defined as below:
public class CustomLogoutSuccessHandler extends
SimpleUrlLogoutSuccessHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(
HttpServletRequest request,
HttpServletResponse response,
Authentication authentication)
throws IOException, ServletException {
String refererUrl = request.getHeader("Referer");
super.onLogoutSuccess(request, response, authentication);
}
}
In this way we can define and configure the Spring Security while bulding the application or POC.