Springブート+ Springセキュリティ+ Thymeleafの例

Spring Boot + Spring Security + Thymeleafの例

Spring Boot Thymeleafの例では、Spring Securityを使用してパス/admin/userを保護します

使用される技術:

  1. Spring Boot 1.5.3.RELEASE

  2. Spring 4.3.8.RELEASE

  3. Spring Security 4.2.2

  4. Thymeleaf 2.1.5.RELEASE

  5. ThymeleafエクストラSpring Security4 2.1.3

  6. Tomcat Embed 8.5.14

  7. メーベン3

  8. Java 8

1. プロジェクトディレクトリ

image

2. プロジェクトの依存関係

spring-boot-starter-securityを宣言します。これにより、Spring Boot + Spring SecurityWebアプリケーションの開発に必要なものがすべて取得されます。

pom.xml


    4.0.0

    spring-boot-web-spring-security
    jar
    Spring Boot Web Spring Security
    Spring Boot Web Spring Security Example
    https://www.example.com
    1.0

    
        org.springframework.boot
        spring-boot-starter-parent
        1.5.3.RELEASE
    

    
        1.8
    

    

        
        
            org.springframework.boot
            spring-boot-starter-security
        

        
        
            org.springframework.boot
            spring-boot-starter-thymeleaf
        

        
        
            org.thymeleaf.extras
            thymeleaf-extras-springsecurity4
        

        
        
            org.springframework.boot
            spring-boot-devtools
            true
        

        
        
            org.webjars
            bootstrap
            3.3.7
        

    
    
        
            
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

プロジェクトの依存関係を表示します。

$ mvn dependency:tree

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Spring Boot Web Spring Security 1.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.10:tree (default-cli) @ spring-boot-web-spring-security ---
[INFO] org.springframework.boot:spring-boot-web-spring-security:jar:1.0
[INFO] +- org.springframework.boot:spring-boot-starter-thymeleaf:jar:1.5.3.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:1.5.3.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:1.5.3.RELEASE:compile
[INFO] |  |  |  +- ch.qos.logback:logback-classic:jar:1.1.11:compile
[INFO] |  |  |  |  \- ch.qos.logback:logback-core:jar:1.1.11:compile
[INFO] |  |  |  +- org.slf4j:jcl-over-slf4j:jar:1.7.25:compile
[INFO] |  |  |  +- org.slf4j:jul-to-slf4j:jar:1.7.25:compile
[INFO] |  |  |  \- org.slf4j:log4j-over-slf4j:jar:1.7.25:compile
[INFO] |  |  +- org.springframework:spring-core:jar:4.3.8.RELEASE:compile
[INFO] |  |  \- org.yaml:snakeyaml:jar:1.17:runtime
[INFO] |  +- org.springframework.boot:spring-boot-starter-web:jar:1.5.3.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-tomcat:jar:1.5.3.RELEASE:compile
[INFO] |  |  |  +- org.apache.tomcat.embed:tomcat-embed-core:jar:8.5.14:compile
[INFO] |  |  |  +- org.apache.tomcat.embed:tomcat-embed-el:jar:8.5.14:compile
[INFO] |  |  |  \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:8.5.14:compile
[INFO] |  |  +- org.hibernate:hibernate-validator:jar:5.3.5.Final:compile
[INFO] |  |  |  +- javax.validation:validation-api:jar:1.1.0.Final:compile
[INFO] |  |  |  +- org.jboss.logging:jboss-logging:jar:3.3.1.Final:compile
[INFO] |  |  |  \- com.fasterxml:classmate:jar:1.3.3:compile
[INFO] |  |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.8.8:compile
[INFO] |  |  |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.8.0:compile
[INFO] |  |  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.8.8:compile
[INFO] |  |  +- org.springframework:spring-web:jar:4.3.8.RELEASE:compile
[INFO] |  |  \- org.springframework:spring-webmvc:jar:4.3.8.RELEASE:compile
[INFO] |  +- org.thymeleaf:thymeleaf-spring4:jar:2.1.5.RELEASE:compile
[INFO] |  |  \- org.thymeleaf:thymeleaf:jar:2.1.5.RELEASE:compile
[INFO] |  |     +- ognl:ognl:jar:3.0.8:compile
[INFO] |  |     +- org.javassist:javassist:jar:3.21.0-GA:compile
[INFO] |  |     \- org.unbescape:unbescape:jar:1.1.0.RELEASE:compile
[INFO] |  \- nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:jar:1.4.0:compile
[INFO] |     \- org.codehaus.groovy:groovy:jar:2.4.10:compile
[INFO] +- org.springframework.boot:spring-boot-starter-security:jar:1.5.3.RELEASE:compile
[INFO] |  +- org.springframework:spring-aop:jar:4.3.8.RELEASE:compile
[INFO] |  |  \- org.springframework:spring-beans:jar:4.3.8.RELEASE:compile
[INFO] |  +- org.springframework.security:spring-security-config:jar:4.2.2.RELEASE:compile
[INFO] |  |  +- org.springframework.security:spring-security-core:jar:4.2.2.RELEASE:compile
[INFO] |  |  \- org.springframework:spring-context:jar:4.3.8.RELEASE:compile
[INFO] |  \- org.springframework.security:spring-security-web:jar:4.2.2.RELEASE:compile
[INFO] |     \- org.springframework:spring-expression:jar:4.3.8.RELEASE:compile
[INFO] +- org.thymeleaf.extras:thymeleaf-extras-springsecurity4:jar:2.1.3.RELEASE:compile
[INFO] |  \- org.slf4j:slf4j-api:jar:1.7.25:compile
[INFO] +- org.springframework.boot:spring-boot-devtools:jar:1.5.3.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot:jar:1.5.3.RELEASE:compile
[INFO] |  \- org.springframework.boot:spring-boot-autoconfigure:jar:1.5.3.RELEASE:compile
[INFO] \- org.webjars:bootstrap:jar:3.3.7:compile
[INFO]    \- org.webjars:jquery:jar:1.11.1:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.072 s
[INFO] Finished at: 2017-05-04T10:13:05+08:00
[INFO] Final Memory: 19M/309M
[INFO] ------------------------------------------------------------------------

3. 春のセキュリティ

3.1 Extends WebSecurityConfigurerAdapter, and defined the security rules in the configure method.

ユーザー「admin」の場合:

  1. /adminページにアクセスできます

  2. /userページにアクセスできません。403アクセス拒否ページにリダイレクトしてください。

ユーザー「ユーザー」の場合:

  1. /userページにアクセスできます

  2. /adminページにアクセスできません。403アクセス拒否ページにリダイレクトしてください。

SpringSecurityConfig.java

package com.example.config;

import org.springframework.beans.factory.annotation.Autowired;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.web.access.AccessDeniedHandler;

@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private AccessDeniedHandler accessDeniedHandler;

    // roles admin allow to access /admin/**
    // roles user allow to access /user/**
    // custom 403 access denied handler
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().disable()
                .authorizeRequests()
                    .antMatchers("/", "/home", "/about").permitAll()
                    .antMatchers("/admin/**").hasAnyRole("ADMIN")
                    .antMatchers("/user/**").hasAnyRole("USER")
                    .anyRequest().authenticated()
                .and()
                .formLogin()
                    .loginPage("/login")
                    .permitAll()
                    .and()
                .logout()
                    .permitAll()
                    .and()
                .exceptionHandling().accessDeniedHandler(accessDeniedHandler);
    }

    // create two users, admin and user
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

        auth.inMemoryAuthentication()
                .withUser("user").password("password").roles("USER")
                .and()
                .withUser("admin").password("password").roles("ADMIN");
    }
}

3.2 Custom 403 Access denied handler, logs the request and redirect to /403

WelcomeController.java

package com.example.error;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

// handle 403 page
@Component
public class MyAccessDeniedHandler implements AccessDeniedHandler {

    private static Logger logger = LoggerFactory.getLogger(MyAccessDeniedHandler.class);

    @Override
    public void handle(HttpServletRequest httpServletRequest,
                       HttpServletResponse httpServletResponse,
                       AccessDeniedException e) throws IOException, ServletException {

        Authentication auth
                = SecurityContextHolder.getContext().getAuthentication();

        if (auth != null) {
            logger.info("User '" + auth.getName()
                    + "' attempted to access the protected URL: "
                    + httpServletRequest.getRequestURI());
        }

        httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + "/403");

    }
}

4. 春のブーツ

4.1 A controller class, to define the http request and view name.

DefaultController.java

package com.example.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class DefaultController {

    @GetMapping("/")
    public String home1() {
        return "/home";
    }

    @GetMapping("/home")
    public String home() {
        return "/home";
    }

    @GetMapping("/admin")
    public String admin() {
        return "/admin";
    }

    @GetMapping("/user")
    public String user() {
        return "/user";
    }

    @GetMapping("/about")
    public String about() {
        return "/about";
    }

    @GetMapping("/login")
    public String login() {
        return "/login";
    }

    @GetMapping("/403")
    public String error403() {
        return "/error/403";
    }

}

4.2 Start Spring Boot application.

DefaultController.java

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootWebApplication {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(SpringBootWebApplication.class, args);
    }

}

5. Thymeleaf +リソース+静的ファイル

5.1 For Thymeleaf files, put in src/main/resources/templates/ folder.

5.2 Thymeleaf fragments, for template layout – header.

src/main/resources/templates/fragments/header.html



    

5.3 Thymeleaf fragments, for template layout – footer. secタグを確認します。これは、Spring Securityのものを表示するのに便利なタグです。詳細については、このThymeleaf extra Spring Securityを参照してください。

src/main/resources/templates/fragments/footer.html





© 2017 example.com | Logged user: | Roles: | Sign Out

5.4 List of the Thymeleaf files, nothing special, self-explanatory.

ホーム〜

src/main/resources/templates/home.html




    Spring Boot Thymeleaf + Spring Security

    

管理者〜

src/main/resources/templates/admin.html




    

Admin page (Spring Security protected)

Hello [[httpServletRequest.remoteUser}]]!

ユーザー〜

src/main/resources/templates/user.html




    

User page (Spring Security protected)

Hello [[httpServletRequest.remoteUser}]]!

〜について

src/main/resources/templates/about.html




    

Normal page (No need login)

login ~

src/main/resources/templates/login.html




    Spring Security Example 
    

Please Sign In

Invalid username and password.
You have been logged out.

403〜

src/main/resources/templates/error/403.html




    

403 - Access is denied

Hello '[[httpServletRequest.remoteUser}]]', you do not have permission to access this page.

5.5 For static files like CSS or Javascript, put in /src/main/resources/static/

/src/main/resources/static/css/main.css

h1{
    color:#0000FF;
}

h2{
    color:#FF0000;
}

footer{
    margin-top:60px;
}

Note
このSpring Boot Serving static contentを読んで、リソースマッピングを理解してください。

6. Demo

6.1 Start the Spring Boot web app. この/admin/**は保護されています。アクセスするには、管理者としてログインする必要があります。

ターミナル

$ mvn spring-boot:run

//...

6.2 Access http://localhost:8080

image

6.3 Access http://localhost:8080/admin, redirect to http://localhost:8080/login

image

6.4 Invalid username or password http://localhost:8080/login

image

6.5 Login successful, redirect back to admin page http://localhost:8080/admin , review the footer section, the user info is displayed.

image

6.6 Access http://localhost:8080/user, redirect to http://localhost:8080/403

image

6.7 Clicks on the sign out link in the footer, redirect to http://localhost:8080/login?logout

image

完了しました。 別のユーザー名「user」でログインして、管理ページにアクセスしてください。

ソースコードをダウンロード

ダウンロード–spring-boot-spring-security-thymeleaf.zip(15 KB)