Spring Boot(五):Spring Boot 集成 Spring Security (I)

今天我們將在上一篇博客《Spring Boot(四):Spring Boot 集成 Thymeleaf》的基礎(chǔ)上來集成Spring Security.

1. 添加Maven依賴

在pom.xml引用spring security.

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>

添加Maven依賴后,運(yùn)行項(xiàng)目昂拂,訪問https://localhost:8443/SpringBootBase/ 瀏覽器會(huì)彈出如下身份驗(yàn)證框:

如圖1所示:


圖1

這是因?yàn)镾pring Security對(duì)我們的工程默認(rèn)使用"basic"身份認(rèn)證受神,只要引入了Spring Security, 那么整個(gè)web應(yīng)用都是安全的,所有資源訪問都要經(jīng)過身份驗(yàn)證授權(quán)才可以訪問格侯”翘可用user 及 隨機(jī)密碼登錄财著,隨機(jī)密碼可從web應(yīng)用啟動(dòng)日志查詢, 如:

Using default security password: 89c19869-277c-4eba-89c8-590e0405ae84

當(dāng)然也可以在application.properties里自定義username和password.

security.user.name=admin
security.user.password=123456

或者直接關(guān)閉這個(gè)默認(rèn)的basic認(rèn)證

security.basic.enabled=false

詳情請(qǐng)參考官方文檔:https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/html/boot-features-security.html

當(dāng)你客制化自己的授權(quán)體系后撑碴,這個(gè)默認(rèn)的"basic"認(rèn)證將會(huì)自動(dòng)被替代撑教。

2. 配置spring security

我們還是以上一篇博客的工程代碼為基礎(chǔ)來整合Spring Security.

  • index.html: 登錄界面
<!DOCTYPE html>
<html lang="zh-cn" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8"/>
    
    <title>Login</title>
    
    <link rel="stylesheet" th:href="@{css/bootstrap.min.css}"/>
    <link rel="stylesheet" th:href="@{css/customer/login.css}"/>
</head>

<body>
    <div class="container">
        <h3 align="center">這是一個(gè)帶有登錄框的主頁</h3> 
        <form class="form-signin" th:action="@{/login}" th:object="${user}" method="post">
            <h2 class="form-signin-heading">請(qǐng) 登 錄</h2>
            <input type="text" class="form-control" placeholder="賬號(hào)" th:field="*{username}"/>
            <input type="password" class="form-control" placeholder="密碼" th:field="*{password}"/>
            <p th:if="${param.logout}" class="error-code">已成功注銷</p>
            <p th:if="${param.error}" class="error-code">用戶名或者密碼錯(cuò)誤</p>
            <button class="btn btn-lg btn-primary btn-block" type="submit">登錄</button>
        </form>
    </div>
</body>
</html>

這回我們新增了兩行代碼:

<p th:if="${param.logout}" class="error-code">已成功注銷</p>
<p th:if="${param.error}" class="error-code">用戶名或者密碼錯(cuò)誤</p>

其中th:if="${param.logout}" 為Thymeleaf模板引擎判斷語法,表示如果http post/get 請(qǐng)求的參數(shù)中帶有l(wèi)ogout,則顯示已成功注銷灰羽。

  • 再增加一個(gè)登錄成功的歡迎界面welcome.html驮履,帶有注銷按鈕鱼辙。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="utf-8"/>
        <title>Hello World!</title>
    </head>
    <body>
        <h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1>
        <form th:action="@{/logout}" method="post">
            <input type="submit" value="注 銷"/>
        </form>
    </body>
</html>

th:inline="text"表示文本內(nèi)聯(lián)廉嚼,即取${#httpServletRequest.remoteUser}值作為文本顯示。

  • 在LoginController.java里新增兩個(gè)controller
@RequestMapping(value ="/welcome", method = RequestMethod.GET)
String welcome() {
  return "welcome";
}

@RequestMapping(value ="/login", method = RequestMethod.GET)
String login(Model model, UserVO user) {
  model.addAttribute("user", user);
  return "index";
}

一個(gè)是用來welcome跳轉(zhuǎn)倒戏,一個(gè)是用來login頁面跳轉(zhuǎn)怠噪。

  • 定制安全策略

接下來寫個(gè)類WebSecurityConfig來繼承WebSecurityConfigurerAdapter,用于確保經(jīng)過認(rèn)證的用戶才能訪問我們?cè)O(shè)置的需要經(jīng)過驗(yàn)證的url.

package tech.onroad.springbootbase.auth;

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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("admin").password("123456").roles("USER");
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/welcome")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }
    
    @Override
    public void configure(WebSecurity web) throws Exception {
        //解決靜態(tài)資源被攔截的問題
        web.ignoring().antMatchers("/css/**");
    }
}
auth.inMemoryAuthentication()
            .withUser("admin").password("123456").roles("USER");

表示在內(nèi)存中創(chuàng)建一個(gè)username為admin, password為123456杜跷,role為USER的用戶傍念。但大多數(shù)web應(yīng)用肯定會(huì)有自己的用戶管理系統(tǒng),這個(gè)我們?cè)诮酉聛淼牟┛蜁?huì)另起一篇博客介紹葛闷,這里先用內(nèi)存用戶憋槐。

注意:前臺(tái)login表單傳過來的賬戶名及密碼的參數(shù)名必須為username和password,否則Spring Security無法正確獲取用戶名及密碼與后臺(tái)用戶系統(tǒng)進(jìn)行匹配淑趾,具體原因是Sping Security的默認(rèn)定義用戶系統(tǒng)的用戶名和密碼為username和password. 如果想詳細(xì)了解一下為什么阳仔,可參考auth.inMemoryAuthentication().withUser("admin").password("123456").roles("USER")源碼。

configure(HttpSecurity http)方法是用來定義安全策略扣泊,如哪些url路徑需要經(jīng)過授權(quán)才能訪問近范,哪些不用。如上面的代碼中延蟹,"/"就不需要授權(quán)就可以訪問评矩,即我們可以正常訪問https://localhost:8443/SpringBootBase/,而不需要用戶授權(quán)阱飘。

當(dāng)一個(gè)用戶成功登錄后斥杜,即Spring Security認(rèn)證成功后,我們的web應(yīng)用將重定向到之前用戶請(qǐng)求的頁面沥匈,也可以客制化蔗喂,使用defaultSuccessUrl方法將其重定向到指定頁面。loginPage("/login")表示在沒有授權(quán)前咐熙,任何訪問需要授權(quán)才能訪問的頁面都會(huì)先跳轉(zhuǎn)到/login登錄頁面弱恒。

web.ignoring().antMatchers("/css/**");表示所以css目錄下的靜態(tài)資源都不作攔截。

3. 驗(yàn)證

按照代碼邏輯:我們?cè)L問https://localhost:8443/SpringBootBase/棋恼,首先會(huì)跳轉(zhuǎn)到index.html界面(因?yàn)?a target="_blank" rel="nofollow">https://localhost:8443/SpringBootBase/和https://localhost:8443/SpringBootBase/index.html是一樣的)返弹,然后輸入賬戶名admin及密碼123456锈玉,點(diǎn)擊登錄,將用戶名及密碼傳到后臺(tái)進(jìn)行匹配义起,如果成功拉背,則跳轉(zhuǎn)到welcome.html界面,如果失敗默终,則會(huì)默認(rèn)指向/login?error椅棺,而從LoginController, 又將其定向到index.html頁面,提示用戶名或者密碼錯(cuò)誤齐蔽。點(diǎn)擊welcome界面注銷按鈕两疚,則會(huì)默認(rèn)跳轉(zhuǎn)到/login?logout, 所以又回到index.html頁面,顯示已成功注銷含滴。

我們來運(yùn)行一下诱渤,看結(jié)果是不是一樣的?

  1. 訪問https://localhost:8443/SpringBootBase/谈况, 如圖2所示

    圖2

  2. 輸入admin及密碼123456勺美,點(diǎn)擊登錄,成功跳轉(zhuǎn)到welcome界面碑韵,如圖3所示


    圖3
  3. 點(diǎn)擊注銷登出赡茸,如圖4所示


    圖4
  4. 輸入錯(cuò)誤的賬戶名或密碼,則得圖5結(jié)果


    圖5

一切如我們預(yù)期執(zhí)行祝闻,說明我們spring security集成成功了占卧。當(dāng)然,這只用了spring security最簡單的功能治筒,還有自定義用戶系統(tǒng)等等屉栓,我們接下來會(huì)慢慢介紹。


完整代碼可到我的github下載:
https://github.com/onroadtech/SpringbootBase/
branch: master
commit-id: 2872ee008f23197b5fa28acee95aae378d4d1f01


本博文已同步發(fā)表于我的個(gè)人博客網(wǎng)站耸袜,歡迎轉(zhuǎn)載指正并注明出處友多。
個(gè)人博客: www.onroad.tech
指正郵箱: onroad_tech@163.com

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市堤框,隨后出現(xiàn)的幾起案子域滥,更是在濱河造成了極大的恐慌,老刑警劉巖蜈抓,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件启绰,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡沟使,警方通過查閱死者的電腦和手機(jī)委可,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人着倾,你說我怎么就攤上這事拾酝。” “怎么了卡者?”我有些...
    開封第一講書人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵蒿囤,是天一觀的道長。 經(jīng)常有香客問我崇决,道長材诽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任恒傻,我火速辦了婚禮脸侥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘碌冶。我一直安慰自己湿痢,他們只是感情好涝缝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開白布扑庞。 她就那樣靜靜地躺著,像睡著了一般拒逮。 火紅的嫁衣襯著肌膚如雪罐氨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,115評(píng)論 1 296
  • 那天滩援,我揣著相機(jī)與錄音栅隐,去河邊找鬼。 笑死玩徊,一個(gè)胖子當(dāng)著我的面吹牛租悄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播恩袱,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼泣棋,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了畔塔?” 一聲冷哼從身側(cè)響起潭辈,我...
    開封第一講書人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎澈吨,沒想到半個(gè)月后把敢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谅辣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年修赞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片桑阶。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡柏副,死狀恐怖熙尉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情搓扯,我是刑警寧澤检痰,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站锨推,受9級(jí)特大地震影響铅歼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜换可,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一椎椰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧沾鳄,春花似錦慨飘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至吞歼,卻和暖如春圈膏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背篙骡。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來泰國打工稽坤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人糯俗。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓尿褪,卻偏偏與公主長得像,于是被迫代替她去往敵國和親得湘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子杖玲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353