[JAVA] Authentication / authorization with Spring Security & Thymeleaf

What is Spring Security?

Spring Security is a framework that provides authentication / authorization functions for applications created with Spring. You can add the following functions to your Web application just by adding a few settings.

--Vulnerability countermeasures --Session fixation measures --Clickjacking measures --CSRF measures --Authentication / authorization --Login mechanism using forms authentication, etc. --Access control using roles

Premise

What to do this time

This time, we will use the Spring Security feature to achieve the following:

--Authentication --Form authentication using user and password -Use the user and password that you have in memory (although you can do it in the database) --Returns an error message if the user or password is wrong --Authorization --Separate roles for administrator account and general user --Administrators can access / admin and / user --General users can only access / user

This time, I will describe the procedure to enable security for Spring Boot application.

Library version

Spring Boot uses 1.4 series and Spring Securiry uses 4.x series. Please note that different versions have different grammars.

Sample code

The sample code that actually works is published on GitHub. If you can read the code, please go to the following directly.

Preparation

Add dependent libraries

This time, we will build the server side with Spring Boot and use Tymeleaf as the template engine to draw the screen. The following libraries are required for that.

In addition, the following libraries are required to enable the Spring Securirty function.

This time, let's add the following libraries to integrate Spring Security and Tymeleaf.

In summary, the following settings will be added to build.gradle.

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web:1.4.1.RELEASE")
    compile("org.springframework.boot:spring-boot-starter-thymeleaf:1.4.1.RELEASE")
    compile("org.springframework.boot:spring-boot-starter-security:1.4.1.RELEASE")
    compile("org.thymeleaf.extras:thymeleaf-extras-springsecurity4:2.1.3.RELEASE")
    compile("org.springframework.security:spring-security-core:4.2.3.RELEASE")
    compile("org.springframework.security:spring-security-web:4.2.3.RELEASE")
    compile("org.springframework.security:spring-security-config:4.2.3.RELEASE")
}

Controller First, create a screen for the administrator and a screen for general users. ʻAdminController for administrators and ʻUserController for general users, respectively.

@Controller
@RequestMapping("/admin")
@Slf4j
public class AdminController {

    @RequestMapping
    public String index() {
        return "admin";
    }
}
@Controller
@RequestMapping("/user")
@Slf4j
public class UserController {

    @RequestMapping
    public String index() {
        return "user";
    }

}

Template Prepare the Tymeleaf template corresponding to the above Controller. Let's say ʻadmin.html and ʻuser.html, respectively (see sample code for details).

After that, create ʻApplication.javaaccording to the method of SpringBoot, and ifgradle bootRun` passes, you are ready.

Implementation example

Now that we're ready, let's move on to Spring Security.

Config First, create a configuration class to enable Spring Security. Spring Security is enabled by providing a class that inherits WebSecurityConfigurerAdapter and has @EnableWebSecurity.

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private static String ROLE_USER = "USER";
    private static String ROLE_ADMIN = "ADMIN";

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/user").hasAnyRole(ROLE_USER, ROLE_ADMIN)
                .antMatchers("/admin").hasRole(ROLE_ADMIN)
                .and()

                .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/user")
                .usernameParameter("username")
                .passwordParameter("password")
                .permitAll()
                .and()

                .logout()
                .permitAll()
                .and()

                .csrf();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring()
                .antMatchers("/*.html", "/*.css")
                .antMatchers("/bootstrap/**");
    }

}

To briefly explain what we are doing in the above example,

Like this. I think that the implementation is such that you can imagine the settings.

This time, in order to work with Tymeleaf, it is necessary to set an instance of TemplateResolver in SpringTemplateEngine. The specific implementation is as follows.

@Autowired
public TemplateResolver templateResolver;

@Bean
public SpringTemplateEngine templateEngine() {
    SpringTemplateEngine engine = new SpringTemplateEngine();
    engine.addDialect(new SpringSecurityDialect());
    engine.setTemplateResolver(templateResolver);
    return engine;
}

In addition, set the user name and password information used for authentication. This time, for simplification of implementation, it is set in-memory instead of from the database. See the sample code for ʻUserDto`.

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    UserDto support = supportUser();
    UserDto admin = adminUser();

    auth.inMemoryAuthentication()
        .withUser(support.getUsername()).password(support.getPassword()).roles(ROLE_USER)
        .and()
        .withUser(admin.getUsername()).password(admin.getPassword()).roles(ROLE_ADMIN);
}

@Bean
@ConfigurationProperties("inmotion.admin")
public UserDto adminUser() {
    return new UserDto();
}

@Bean
@ConfigurationProperties("inmotion.user")
public UserDto supportUser() {
    return new UserDto();
}

I will leave the actual user name and password in ʻapplication.yml`.

inmotion:
  user:
    username: user
    password: pass12345
  admin:
    username: admin
    password: pass12345

Controller After that, prepare a Controller corresponding to the login screen,

@Controller
public class AuthenticationController {

    @RequestMapping({"/", "/login"})
    public String login(@RequestParam(value = "error", required = false) String error, Model model) {
        if (error != null) {
            //Processing to output an error message
        }
        return "login";
    }

}

Template All you have to do is prepare a login form for POST with / login.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<body>
<div class="container">
    <form class="form-signin" method="post" th:action="@{/login}">
        <div class="alert alert-dismissible alert-danger" th:if="${errorMessage}">
            <button type="button" class="close" data-dismiss="alert">×</button>
            <p th:text="${errorMessage}"></p>
        </div>
        <h2 class="form-signin-heading">Please sign in</h2>
        <label for="username" class="sr-only">Username</label>
        <input type="text" id="username" name="username" class="form-control" placeholder="UserName"/>
        <label for="password" class="sr-only">Password</label>
        <input type="password" id="password" name="password" class="form-control" placeholder="Password"/>
        <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
    </form>
</div>
</body>
</html>

Start the application with gradle bootRun and

--You must be able to log in with the specified user name and password. --Access control is enabled --403 is returned when trying to access an unauthorized screen --A token for CSRF measures has been generated.

Let's check.

Reference material

Recommended Posts

Authentication / authorization with Spring Security & Thymeleaf
Spring Security usage memo Authentication / authorization
Implemented authentication function with Spring Security ②
Implemented authentication function with Spring Security ①
Achieve BASIC authentication with Spring Boot + Spring Security
Try LDAP authentication with Spring Security (Spring Boot) + OpenLDAP
Add your own authentication items with Spring Security
[Introduction to Spring Boot] Authentication function with Spring Security
Login function with Spring Security
Use Basic Authentication with Spring Boot
Spring Boot Tutorial Using Spring Security Authentication
Learn Spring Security authentication processing architecture
Oauth2 authentication with Spring Cloud Gateway
I get a 404 error when testing forms authentication with Spring Security
Implement CRUD with Spring Boot + Thymeleaf + MySQL
Use Spring Security JSP tags with FreeMarker
Implement paging function with Spring Boot + Thymeleaf
How Spring Security works with Hello World
Run WEB application with Spring Boot + Thymeleaf
Hash passwords with Spring Boot + Spring Security (with salt, with stretching)
Make HTML page dynamic with thymeleaf (spring + gradle)
Create CRUD apps with Spring Boot 2 + Thymeleaf + MyBatis
Create Spring Cloud Config Server with security with Spring Boot 2.0
Build a WEB system with Spring + Doma + H2DB + Thymeleaf
Spring Security usage memo: Cooperation with Spring MVC and Boot
Implement a simple Rest API with Spring Security with Spring Boot 2.0
Spring Security causes 403 forbidden
Create a simple demo site with Spring Security with Spring Boot 2.1
Generate JavaScript with Thymeleaf
Let's experience the authorization code grant flow with Spring Security OAuth-Part 1: Review of OAuth 2.0
Try to work with Keycloak using Spring Security SAML (Spring 5)
Call your own method with PreAuthorize in Spring Security
Spring with Kotorin ―― 1. SPRING INITIALIZR
Download with Spring Boot
Create API key authentication for Web API in Spring Security
Add your own authentication items with Spring Security
Handle Java 8 date and time API with Thymeleaf with Spring Boot
Until INSERT and SELECT to Postgres with Spring boot and thymeleaf
Use thymeleaf3 with parent without specifying spring-boot-starter-parent in Spring Boot
Implement a simple Rest API with Spring Security & JWT with Spring Boot 2.0
Login with HttpServletRequest # login in Spring Security of Servlet 3.x environment
Generate barcode with Spring Boot
Use Thymeleaf with Azure Functions
Hello World with Spring Boot
Java Config with Spring MVC
Basic Authentication with Java 11 HttpClient
Spring Security usage memo CSRF
Spring with Kotorin --8 Repository layer
Get started with Spring boot
Spring Security usage memo Run-As
Hello World with Spring Boot!
Spring with Kotorin --6 Asynchronous processing
[Spring] [Thymeleaf] Insert CSRF token
Run LIFF with Spring Boot
SNS login with Spring Boot
[Java] Thymeleaf Basic (Spring Boot)
Spring Security Usage memo Method security
Spring Security usage memo Remember-Me
Spring with Kotorin ―― 7. Service layer
Using Mapper with Java (Spring)
Spring Boot starting with Docker