ADD SPRING SECURITY WITH SPRING BOOT
This tutorial will teach you on how to add spring security to spring boot application.
Add Spring Boot Starter Security Dependency
To add spring security to spring boot, first we add the dependency spring-boot-starter-security.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Extending WebSecurityConfigureAdapter
Next, create a class that extends the WebSecurityConfigureAdapter.
Add the annotation @EnableWebSecurity to the class to tell spring that this class is spring security configuration.
Override the two overloaded methods configure(HttpSecurity) and configure(AuthenticationManagerBuilder). The configure(HttpSecurity) defines the mapping of secured URLs or path that will determine if the user can access specific pages. The configure(AuthenticationmanagerBuilder) determines how the security will handle the retrieval of user information commonly in the database.
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired private AuthenticationSuccessHandler authenticationSuccessHandler;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests()
.antMatchers("/", "/css/**", "/js/**", "/images/**").permitAll()
.antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/")
.loginProcessingUrl("/login")
.failureUrl("/?login_error")
.successHandler(authenticationSuccessHandler);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user")
.password("user")
.roles("USER")
.and()
.withUser("admin")
.password("admin")
.roles("ADMIN");
}
}
In the above code, inside the method configure(HttpSecurity), tells you the following:
that any request for “/” or index or css and js and images are not secured and are all permitted.
that any request with starting url of “/user/” can only be viewed with user that has ROLE_USER or ROLE_ADMIN authorities.
that any request with starting url of “/admin/” can only be viewed with user that has ROLE_ADMIN.
if the user is not authenticated, then the user will be redirected to form login page which is in the “/” URL.
the loginProcessingUrl(“/login”) tells you that your form should have an action=’/login’.
the failureUrl(“/?login_error”) means that if the username/password is incorrect, the user will be redirected to this page.
the successHandler(authenticationSuccessHandler) is our own implemenation of AuthenticationSuccessHandler interface so that we can redirect the user depending on its role.
Inside the method configure(AuthenticationManagerBuilder), contains the information on how to retrieve the user information. In our case, we just create an inMemoryAuthentication with 2 users that has username and password to be user/user for ROLE_USER and admin/admin for ROLE_ADMIN.
In real life scenario, you may need to create your own implementation of UserDetailsService interface and add it to the AuthenticationManagerBuilder.
public class AuthenticationSuccessHandlerImpl implements AuthenticationSuccessHandler {
private static final SimpleGrantedAuthority ADMIN_AUTHORITY = new SimpleGrantedAuthority("ROLE_ADMIN");
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
if (authorities.contains(ADMIN_AUTHORITY)) {
redirectStrategy.sendRedirect(httpServletRequest, httpServletResponse, "/admin");
} else {
redirectStrategy.sendRedirect(httpServletRequest, httpServletResponse, "/user");
}
}
}
Bean Configurations
In order for our @Autowired annotation to work inside WebSecurityConfiguration class, we need to create the bean for our AuthenticationSuccessHandler implementation. The class should be annotated by @Configuration to tell spring that this is a configuration class.
@Configuration
public class BeanConfigurations {
@Bean
public AuthenticationSuccessHandler authenticationSuccessHandler() {
return new AuthenticationSuccessHandlerImpl();
}
}
Creating the Controllers
We create two controllers. The UserController and AdminController.
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping
public String viewUserProfile() {
return "user/profile";
}
}
The viewUserProfile method will be called for any GET request in “/user” path. The “user/profile” that will be returned means that the view that will be displayed can be found in templates/user/profile.html. The same explanation for AdminController. Below is the code for AdminController.
@Controller
@RequestMapping("/admin")
public class AdminController {
@RequestMapping
public String viewManageUsers() {
return "/admin/manage-users";
}
}
Creating the Views
Next, we create the html files for profile.html inside the user folder and manage-users.html inside the admin folder.
Run the Application
Finally, we can now run the application. Open Application.java then run the main method. Go to your browser and type localhost:8085/javapointers. This is the index page and the login page. Try to login using user/user and admin/admin and you will be redirected depending on your credentials. Accessing the /user or /admin url without logging in will redirect the user to the login page.
RESOURCES: