Spring Security Login Example

By | | Updated : 2021-03-19 | Viewed : 502 times

Spring Security Login Example

In this tutorial, we learn how to use spring security in form login with example.

Maven Dependencies

Maven dependencies for Spring Security
<!-- Spring Security -->
 <dependency>
 <groupId>org.springframework.security</groupId>
 <artifactId>spring-security-web</artifactId>
 <version>${spring-security.version}</version>
 </dependency>
 
 <dependency>
 <groupId>org.springframework.security</groupId>
 <artifactId>spring-security-config</artifactId>
 <version>${spring-security.version}</version>
 </dependency>

Here we are using Spring MVC so we need to add Spring MVC dependencies. And we need to use security libraries. Those are spring-security-web and spring-security-config. These are main libraries for Spring security.

Login Form Example

We will look at an annotation-based example here for testing the login form with spring security.

Login Form Example with annotations

We will focus first on the config part then will look at the reaming classes in order to execute the form login example.

WebAppInitializer.java
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{WebMvcConfig.class, WebSecurityConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return null;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

Here WebAppInitializer is the implementation of AbstractAnnotationConfigDispatcherServletInitializer where ServletContext can be configured. Here configuration is set up in the mode of program-based. As Servlet 3.0 or above versions of Servlet supports zero-based XML configurations, so configuration is done in program based.

AbstractSecurityWebApplicationInitializer.java
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {

}

Here AbstractSecurityWebApplicationInitializer will take care of the registration of SpringSecurityFilterChain Filter for every URL in our application. So that it will be worked on the basis of WebSecurityConfig configuration. And moreover, WebSecurityConfig is required to configure in WebAppInitializer please have a look at the previous configuration.

WebMvcConfig.java
public class WebMvcConfig implements WebMvcConfigurer {

    @Bean
    public InternalResourceViewResolver resolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setViewClass(JstlView.class);
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
    }

    @Bean
    public MessageSource messageSource() {
        ResourceBundleMessageSource source = new ResourceBundleMessageSource();
        source.setBasename("messages");
        return source;
    }

}

Here we configured the WebMvc Configurations for InternalResourceViewResolver and MessageSource.

WebSecurityConfig.java
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user").password(passwordEncoder().encode("userpass")).roles("USER")
                .and()
                .withUser("admin").password(passwordEncoder().encode("adminpass")).roles("ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests()
                .antMatchers("/admin").access("hasRole('ROLE_ADMIN')")
                .antMatchers("/home").access("hasAnyRole('ROLE_USER', 'ROLE_ADMIN')")
                .and()
                .formLogin().loginPage("/login")
                .defaultSuccessUrl("/home")
                .failureUrl("/login?error")
                .usernameParameter("username").passwordParameter("password")
                .and()
                .logout().logoutSuccessUrl("/login?logout")
                .and()
                .exceptionHandling().accessDeniedPage("/accessDenied");

    }

}

configAuthentication() and configure() are main important methods in WebSecurityConfig class.

configAuthentication() will be checking the User's authentication details provided by the user.

configure() method is used to configure the HttpSecurity class. HttpSecurity holds the information of all the URLs and authorized roles. Here each role is defined for each URL's authorization. That is whether a particular user is allowed or not to access the particular URL.

We will write now the controller class and for accessing different types of URLs. Please look at the below code for the controller part.

HomeController.java
@Controller
public class LoginController {

    @GetMapping(value = {"/"})
    public String welcome(ModelMap model) {
        return "welcome";
    }

    @GetMapping(value = {"/home"})
    public String home(ModelMap model) {
        return "home";
    }

    @GetMapping(value = {"/admin"})
    public String admin(ModelMap model) {
        return "admin";
    }

    @GetMapping(value = {"/login"})
    public String login(ModelMap model, @RequestParam(value = "error", required = false) String error,
                            @RequestParam(value = "logout", required = false) String logout) {

        if (error != null) {
            model.addAttribute("error", "Credentials are invalid.");
        }
        if (logout != null) {
            model.addAttribute("message", "Logged out successfully.");
        }
        return "login";
    }
    @GetMapping(value = "/accessDenied")
    public String accessDenied(ModelMap model) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (!(authentication instanceof AnonymousAuthenticationToken)) {
            UserDetails userDetail = (UserDetails) authentication.getPrincipal();
            System.out.println(userDetail);

            model.addAttribute("username", userDetail.getUsername());

        }
        return "accessDenied";

    }
}

Here LoginController class is defined the different types of requesting mapping methods. Please have a look at this class.

Please generate a war file and please deploy the war in some web servers like the tomcat server. Please find the below screenshot for testing of the application.

Spring Security Login Example
Spring Security Login Example
Spring Security Login Example
Spring Security Login Example
Spring Security Login Example

To find more code related changes you can refer to the repository Spring-Security-Form-login-With-InMem-Example-App

Leave A Reply