Spring Boot中使用Spring Security進(jìn)行安全控制

我們?cè)诰帉慦eb應(yīng)用時(shí)校镐,經(jīng)常需要對(duì)頁(yè)面做一些安全控制衣厘,比如:對(duì)于沒(méi)有訪問(wèn)權(quán)限的用戶需要轉(zhuǎn)到登錄表單頁(yè)面。要實(shí)現(xiàn)訪問(wèn)控制的方法多種多樣择镇,可以通過(guò)Aop挡逼、攔截器實(shí)現(xiàn),也可以通過(guò)框架實(shí)現(xiàn)(如:Apache Shiro腻豌、Spring Security)家坎。

本文將具體介紹在Spring Boot中如何使用Spring Security進(jìn)行安全控制。

準(zhǔn)備工作

首先吝梅,構(gòu)建一個(gè)簡(jiǎn)單的Web工程虱疏,以用于后續(xù)添加安全控制,也可以用之前Chapter3-1-2做為基礎(chǔ)工程苏携。若對(duì)如何使用Spring Boot構(gòu)建Web應(yīng)用做瞪,可以先閱讀《Spring Boot開(kāi)發(fā)Web應(yīng)用》一文。

Web層實(shí)現(xiàn)請(qǐng)求映射

@Controller
public class HelloController {

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

    @RequestMapping("/hello")
    public String hello() {
        return "hello";
    }

}
  • /:映射到index.html
  • /hello:映射到hello.html

實(shí)現(xiàn)映射的頁(yè)面

  • src/main/resources/templates/index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Spring Security入門</title>
    </head>
    <body>
        <h1>歡迎使用Spring Security!</h1>
        <p>點(diǎn)擊 <a th:href="@{/hello}">這里</a> 打個(gè)招呼吧</p>
    </body>
</html>
  • src/main/resources/templates/hello.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Hello World!</title>
    </head>
    <body>
        <h1>Hello world!</h1>
    </body>
</html>

可以看到在index.html中提供到/hello的鏈接右冻,顯然在這里沒(méi)有任何安全控制装蓬,所以點(diǎn)擊鏈接后就可以直接跳轉(zhuǎn)到hello.html頁(yè)面著拭。

整合Spring Security

在這一節(jié),我們將對(duì)/hello頁(yè)面進(jìn)行權(quán)限控制矛物,必須是授權(quán)用戶才能訪問(wèn)茫死。當(dāng)沒(méi)有權(quán)限的用戶訪問(wèn)后,跳轉(zhuǎn)到登錄頁(yè)面履羞。

添加依賴

在pom.xml中添加如下配置峦萎,引入對(duì)Spring Security的依賴。

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

Spring Security配置

創(chuàng)建Spring Security的配置類WebSecurityConfig忆首,具體如下:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/", "/home").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }

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

}
  • 通過(guò)@EnableWebMvcSecurity注解開(kāi)啟Spring Security的功能
  • 繼承WebSecurityConfigurerAdapter爱榔,并重寫它的方法來(lái)設(shè)置一些web安全的細(xì)節(jié)
  • configure(HttpSecurity http)方法
  • 通過(guò)authorizeRequests()定義哪些URL需要被保護(hù)、哪些不需要被保護(hù)糙及。例如以上代碼指定了//home不需要任何認(rèn)證就可以訪問(wèn)详幽,其他的路徑都必須通過(guò)身份驗(yàn)證。
  • 通過(guò)formLogin()定義當(dāng)需要用戶登錄時(shí)候浸锨,轉(zhuǎn)到的登錄頁(yè)面唇聘。
  • configureGlobal(AuthenticationManagerBuilder auth)方法,在內(nèi)存中創(chuàng)建了一個(gè)用戶柱搜,該用戶的名稱為user迟郎,密碼為password,用戶角色為USER聪蘸。

新增登錄請(qǐng)求與頁(yè)面

在完成了Spring Security配置之后宪肖,我們還缺少登錄的相關(guān)內(nèi)容。

HelloController中新增/login請(qǐng)求映射至login.html

@Controller
public class HelloController {

    // 省略之前的內(nèi)容...

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

}

新增登錄頁(yè)面:src/main/resources/templates/login.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Spring Security Example </title>
    </head>
    <body>
        <div th:if="${param.error}">
            用戶名或密碼錯(cuò)
        </div>
        <div th:if="${param.logout}">
            您已注銷成功
        </div>
        <form th:action="@{/login}" method="post">
            <div><label> 用戶名 : <input type="text" name="username"/> </label></div>
            <div><label> 密  碼 : <input type="password" name="password"/> </label></div>
            <div><input type="submit" value="登錄"/></div>
        </form>
    </body>
</html>

可以看到健爬,實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的通過(guò)用戶名和密碼提交到/login的登錄方式控乾。

根據(jù)配置,Spring Security提供了一個(gè)過(guò)濾器來(lái)攔截請(qǐng)求并驗(yàn)證用戶身份娜遵。如果用戶身份認(rèn)證失敗蜕衡,頁(yè)面就重定向到/login?error,并且頁(yè)面中會(huì)展現(xiàn)相應(yīng)的錯(cuò)誤信息魔熏。若用戶想要注銷登錄衷咽,可以通過(guò)訪問(wèn)/login?logout請(qǐng)求,在完成注銷之后蒜绽,頁(yè)面展現(xiàn)相應(yīng)的成功消息镶骗。

到這里,我們啟用應(yīng)用躲雅,并訪問(wèn)http://localhost:8080/鼎姊,可以正常訪問(wèn)。但是訪問(wèn)http://localhost:8080/hello的時(shí)候被重定向到了http://localhost:8080/login頁(yè)面,因?yàn)闆](méi)有登錄相寇,用戶沒(méi)有訪問(wèn)權(quán)限慰于,通過(guò)輸入用戶名user和密碼password進(jìn)行登錄后,跳轉(zhuǎn)到了Hello World頁(yè)面唤衫,再也通過(guò)訪問(wèn)http://localhost:8080/login?logout婆赠,就可以完成注銷操作。

為了讓整個(gè)過(guò)程更完成佳励,我們可以修改hello.html休里,讓它輸出一些內(nèi)容,并提供“注銷”的鏈接赃承。


<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <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>

本文通過(guò)一個(gè)最簡(jiǎn)單的示例完成了對(duì)Web應(yīng)用的安全控制妙黍,Spring Security提供的功能還遠(yuǎn)不止于此,更多Spring Security的使用可參見(jiàn)Spring Security Reference瞧剖。

完整示例:Chapter4-3-1

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拭嫁,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子抓于,更是在濱河造成了極大的恐慌做粤,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捉撮,死亡現(xiàn)場(chǎng)離奇詭異驮宴,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)呕缭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)修己,“玉大人恢总,你說(shuō)我怎么就攤上這事〔欠撸” “怎么了片仿?”我有些...
    開(kāi)封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)尤辱。 經(jīng)常有香客問(wèn)我砂豌,道長(zhǎng),這世上最難降的妖魔是什么光督? 我笑而不...
    開(kāi)封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任阳距,我火速辦了婚禮,結(jié)果婚禮上结借,老公的妹妹穿的比我還像新娘筐摘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布咖熟。 她就那樣靜靜地躺著圃酵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪馍管。 梳的紋絲不亂的頭發(fā)上郭赐,一...
    開(kāi)封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音确沸,去河邊找鬼捌锭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛张惹,可吹牛的內(nèi)容都是我干的舀锨。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼宛逗,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼坎匿!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起雷激,我...
    開(kāi)封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤替蔬,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后屎暇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體承桥,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年根悼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了凶异。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡挤巡,死狀恐怖剩彬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情矿卑,我是刑警寧澤喉恋,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站母廷,受9級(jí)特大地震影響轻黑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜琴昆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一氓鄙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧业舍,春花似錦玖详、人聲如沸把介。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)拗踢。三九已至,卻和暖如春向臀,著一層夾襖步出監(jiān)牢的瞬間巢墅,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工券膀, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留君纫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓芹彬,卻偏偏與公主長(zhǎng)得像蓄髓,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子舒帮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容