springSecurity之java配置篇


一 前言

本篇是springSecurity知識的入門第二篇,主要內容是如何使用java配置的方式進行配置springSeciruty,然后通過一個簡單的示例自定義登陸頁面,覆蓋原有springSecurity默認的登陸頁面;學習這篇的基礎是 知識追尋者之前發布 過 的《springSecurity入門篇》

公眾號:知識追尋者

知識追尋者(Inheriting the spirit of open source, Spreading technology knowledge;)

二 java配置

2.1配置賬號密碼

如下所示, 使用 @EnableWebSecurity 在配置類上開啟security配置功能; 在配置類中定義bean 名為 UserDetailsService, 主要是 負責 設置賬號密碼,攔截URL,校驗成功后重定向至URL;如果要使用多用戶,使用 manager.createUser 方法即可;

/**
 * @Author lsc
 * <p> </p>
 */
@EnableWebSecurity// 開啟springSecurity
public class WebSecurityConfig {

    /* *
     * @Author lsc
     * <p> 主要是讓SpringSecurity知道springSecurityFilterChain負責管理應用的URL
     * 校驗,通過賬號,密碼的方式校驗成功后重定向至應用;
     *  </p>
     * @Param []
     */
    @Bean
    public UserDetailsService userDetailsService() throws Exception {
        //
        User.UserBuilder users = User.withDefaultPasswordEncoder();
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(users.username("user").password("user").roles("USER").build());
        manager.createUser(users.username("admin").password("admin").roles("USER","ADMIN").build());
        return manager;
    }

}

訪問 localhost:8080/login 此時輸入的密碼就是 user , user ; 或者 admin, admin;

2.2 默認授權配置

如下所示 往配置類中 添加 配置類,其 繼承 WebSecurityConfigurerAdapter, 重寫 configure(HttpSecurity http) 方法, 此方便的作用就是Security 的授權過程,如下示例中,任何的請求都需要認證才可以訪問,並且登陸頁面還是security自帶的登陸頁面;

    @Configuration
    public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .authorizeRequests(authorize ->
                            authorize // 授權
                            .anyRequest() // 任何請求
                            .authenticated() // 認證認證
                    )
                    .formLogin(withDefaults()); //
        }
    }

2.3 過濾器順序

再向配置中添加如下配置,其內容和上節內容差不多,但是 攔截的url 是 以/api 為開頭的URL, 並且 是 ADMIN 角色才擁有訪問權限; 使用@Order(1), 過濾器配置會優先走着條配置,其次才是上節 的配置;

    @Configuration
    @Order(1)
    public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .antMatcher("/api/**")
                    .authorizeRequests(authorize -> authorize
                            .anyRequest().hasRole("ADMIN")
                    )
                    .httpBasic(withDefaults())
                    .formLogin(withDefaults());
        }
    }

控制層添加代碼如下

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

首先使用user用戶訪問 http://localhost:8080/api/login 賬號密碼校驗成功后跳轉應用請求url, 出現禁止頁面,原因是user沒有ADMIN角色權限;

然后使用admin用戶登陸訪問 http://localhost:8080/api/login 賬號密碼校驗成功后跳轉應用請求url 正常放問;

登陸頁面如下

登陸成功后跳轉如下

三 自定義登陸頁面

3.1 實現自定頁面登陸

自定義登陸頁面 知識追尋者這邊需要引入引擎模板依賴 , thymeleaf; application配置如下

spring:
  # 引擎模板配置
  thymeleaf:
    cache: false # 關閉緩存
    mode: HTML
    prefix: classpath:/templates/ # 指定 thymeleaf 模板路徑
    encoding: UTF-8 # 指定字符集編碼
  mvc:
    static-path-pattern: /static/** # js ,css 等靜態文件路徑

然后在templates 下新建 login.html , 內容如下

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<head>
    <title>Please Log In</title>
</head>
<body>
<h1>Please Log In</h1>
<div th:if="${param.error}">
    Invalid username and password.</div>
<div th:if="${param.logout}">
    You have been logged out.</div>
<form th:action="@{/login}" method="post">
    <div>
        <input type="text" name="username" placeholder="Username"/>
    </div>
    <div>
        <input type="password" name="password" placeholder="Password"/>
    </div>
    <input type="submit" value="Log in" />
</form>
</body>
</html>

springSecurity授權配置內容如下,如下所示,loginPage 配置登陸頁面,注意不要帶上.html,loginProcessingUrl 配置登陸url,注意這邊的url要與 login.html里面的action的url一致,否則會報錯;后面就是successForwardUrl 登陸成功后的轉發,當然還有登陸失敗的轉發failureForwardUrl(), 讀者按需配置即可;

    @Configuration
    @Order(1)
    public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .antMatcher("/**")
                    .authorizeRequests(authorize -> authorize
                            .anyRequest().hasRole("USER")
                    )
                    .formLogin(form -> {
                        form
                                .loginPage("/login") // 配置登陸頁
                                .loginProcessingUrl("/login")
                                .successForwardUrl("/login/success")// 登陸成功后會轉發至 /login/success 請求
                                .permitAll(); // 允許所有人訪問
                    })
                    .csrf().disable()
                    .httpBasic();// http請求方式 ,web 瀏覽器會彈出對話框

        }
    }

再將控制層內容替換如下啊,登陸邏輯就是我們請求 /login 會被轉發至login.html, 然后action 提交至 /login, 這邊已經到springSecurity 內部, 登陸成功后其會轉發 至 /login/success;

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

    @PostMapping("/login/success")
    @ResponseBody
    public String success() {
        return "sucess";
    }

啟動項目,瀏覽器輸入http://localhost:8080/login 或者其它 ip + port + / path 會自動跳轉至自定義 登陸頁面

輸入成功后會跳轉的 /login/success ,返回內容如下

3.2 自定義登陸流程分析

來自官網的圖片如下,是form表單登陸的流程,

  1. 首先客戶端會發送未授權請求到服務端會被 FilterSecurityInterceptor 攔截標明為未授權的請求,拋出 AccessDeniedException;
  2. ExceptionTranslationFilter 會捕獲 AccessDeniedException 異常
  3. 此時 AuthenticationEntryPoint 會初始化配置流程;
  4. 捕獲異常后並且重定向到登陸頁面
  5. 最后 在登陸頁面輸入賬號密碼就會進入認證流程;

3.3 登陸認證流程分析

官網登陸時的認證流程圖片如下

  1. 賬號密碼輸入成功后,UsernamePasswordAuthenticationFilter 就會創建UsernamePasswordAuthenticationToken;
  2. AuthenticationManager儲存着用戶的信息,UsernamePasswordAuthenticationToken 會被送至這邊進行認證;
  3. 如果認證失敗,SecurityContextHolder(主要是儲存認證的數據,principle,credentials,authorities)會被清空, RememberMeServices.loginFail 與 AuthenticationFailureHandler都會被調用;
  4. 如果登陸成功SessionAuthenticationStrategy 會被喚起重新定制下一次的登陸,認證信息會被儲存至SecurityContextHolder,如果配置了remberMe, RememberMeServices.loginSuccess會被調用,ApplicationEventPublisher 會發布InteractiveAuthenticationSuccessEvent,AuthenticationSuccessHandler會被調用;

簡單概括就是賬號密碼輸入后進入認證流程,發放token, 在manager中認證,如果認證成功存儲認證信息,否則清空認證信息;

四 參考文檔

官方文檔

https://docs.spring.io/spring-security/site/docs/5.3.3.BUILD-SNAPSHOT/reference/html5/#servlet-authentication-form


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM