spring security 5.x 使用及分析(二:自定義配置—登錄頁配置及原理)

二、自定義配置

上一篇中,介紹了Spring Security的一些基礎的配置,及源碼的介紹。本篇將介紹如何進行自定義的一些配置來實現權限的控制。

1.1、登錄頁配置及使用

我們繼續在之前的代碼裏進行操作,首先,我們修改loginPage頁面,修改爲我們自定義的頁面,頁面代碼示例如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>登錄頁面</h1>
</body>
</html>

在代碼中添加配置SecurityConfig,需要繼承WebSecurityConfigurerAdapter類,重寫void configure(HttpSecurity http) throws Exception;這個方法是Security的安全配置方法,大部分的基礎配置在這個方法中配置,例如登錄頁、登錄接口、session配置等等,要作爲Spring Security的配置類,需要使用@EnableGlobalMethodSecurity註解,如下:

/**
 * spring security 配置
 *
 * @author liwenqiang 2018/7/12 17:51
 **/
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class AbeilleSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * http 請求安全配置
     *
     * @param http 安全請求
     * @throws Exception 異常
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin().loginPage("/login");
    }

}

注:這裏值得注意的是,loginPage需要配置的是訪問登錄頁的資源路徑,而不是登錄頁的名字,否則會報異常,例如配置爲“login.html”:

配置之後,先啓動項目,然後訪問http://localhost:8080,頁面提示404?這個是爲什麼呢?先想一下,404錯誤碼代表什麼?404錯誤碼代表的是服務未找到,也就是說http://localhost:8080/這個路徑沒有對應的服務,那我們配置一個Controller,匹配路徑就默認爲“/”,代碼如下:

/**
 * controller
 *
 * @author liwenqiang 2019/8/24 22:07
 **/
@RestController
public class LoginController {

    @RequestMapping
    public String path(){
        return "你好!";
    }
}

然後重啓服務,刷新頁面,看到了“你好!”的信息;

問題一:那就有疑問了,spring 沒有攔截路徑?

配置類雖然繼承了WebSecurityConfigurerAdapter,但是重寫了方法,所以默認的攔截配置就被覆蓋了,知識配置了登錄頁面,所以訪問路徑沒有別攔截,直接通過,那我們要使用其他的默認配置,就在void configure(HttpSecurity http) throws Exception方法的代碼中加入一行,如下:

    /**
     * http 請求安全配置
     *
     * @param http 安全請求
     * @throws Exception 異常
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.formLogin().loginPage("/login");
    }

現在重新啓動項目,刷新頁面,出現了新的問題,由於重定向次數太多,頁面報錯(safari瀏覽器會直接下載文件);

問題二:重定向次數太多,這個又是因爲什麼呢?

回過頭再看下源碼是怎麼寫的,在源碼中的配置是任何請求都必須是認證過的纔可以,包括“/”和“/login”,所以我們要把“/login”路徑配置爲不需要認證也可以訪問;

protected void configure(HttpSecurity http) throws Exception {
	http
		.authorizeRequests()
            //看這一行,意思是任何請求,都需要被認證
			.anyRequest().authenticated()
			.and()
		.formLogin().and()
		.httpBasic();
}

要配置不需要認證也可以訪問,需要添加配置如下:

@Override
protected void configure(HttpSecurity http) throws Exception {
    super.configure(http);
    //配置登錄頁任何條件都可以訪問
    http.formLogin().loginPage("/login").permitAll();
}

再次啓動,然後刷新頁面,意外的事發生了,出現了“你好!”的信息;

問題三:不應該是攔截了路徑,跳轉到“/login”上嗎?

因爲在LoginController中配置的是@RequestMapping,沒有具體的路徑,同時沒有“/login”的具體資源匹配,所以就匹配到了這個唯一的資源,返回了“你好!”的信息;

修改資源匹配爲具體的,將“你好!”的資源修改爲@RequestMapping("/"),然後重啓服務,刷新頁面,由於“/login”匹配不到對應的資源,就出現了404錯誤,那麼,前面也說了,配置中的loginPage配置的其實是login.html的資源路徑“/login”,這裏牽扯到視圖資源解析,不做多餘說明。在修改LoginController將類上的註解@RestController修改爲@Controller,在path()方法上添加@ResponseBody,並在其中添加一個“/login”視圖解析的資源配置,代碼如下:

/**
 * controller
 *
 * @author liwenqiang 2019/8/24 22:07
 **/
@Controller
public class LoginController {

    @RequestMapping("/")
    @ResponseBody
    public String path(){
        return "你好!";
    }

    @RequestMapping("/login")
    public String login(){
        return "login.html";
    }
}

修改完LoginController之後,重啓服務,刷新頁面,這時候,就跳轉到了我們想要的登錄頁面了;

1.2、登錄配置及使用

配置了登錄頁,接下來配置登錄路徑等相關配置,首先進行登錄處理配置,在配置之前,先簡單寫一個登錄頁;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="user-login">
    <div class="content-wrapper">
        <div class="form-container">
            <h2 class="form-title">登錄表單</h2>
            <form id="form-login" class="login-form" action="/">
                <div>
                    <input placeholder="手機號" name="mobile" />
                </div>
                <div>
                    <input type="password" placeholder="密碼" name="pwd"/>
                </div>
                <div>
                    <checkbox>
                        Remember me
                    </checkbox>
                    <button class="login-form-button" type="submit">Log In</button>
                </div>
            </form>
        </div>
    </div>
</div>
</body>
</html>

在上面寫的配置類中添加一個配置loginProcessingUrl這個配置是定義登錄表單提交之後是由那個資源去處理的。與其相關的配置有,用戶名獲取的字段,密碼獲取的字段以及登錄失敗後跳轉的路徑。

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.formLogin().loginPage("/login").permitAll()
                .loginProcessingUrl("/signin").usernameParameter("mobile").passwordParameter("pwd")
                .failureForwardUrl("/login");
    }

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章