<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【深入】聊聊權(quán)限

          共 13712字,需瀏覽 28分鐘

           ·

          2022-11-01 18:12

          常見(jiàn)的權(quán)限模型

          ACL

          定義:規(guī)定資源可以被哪些主體進(jìn)行哪些操作。同時(shí),主體可以將資源、操作的權(quán)限,授予其他主體
          在ACL的基礎(chǔ)上,DAC模型將授權(quán)的權(quán)力下放,允許擁有權(quán)限的用戶,可以自主地將權(quán)限授予其他用戶。

          DAC 自主訪問(wèn)控制

          定義:規(guī)定資源可以被哪些主體進(jìn)行哪些操作。同時(shí),主體可以將資源、操作的權(quán)限,授予其他主體。
          在ACL的基礎(chǔ)上,DAC模型將授權(quán)的權(quán)力下放,允許擁有權(quán)限的用戶,可以自主地將權(quán)限授予其他用戶。

          MAC 強(qiáng)制訪問(wèn)控制

          定義:當(dāng)一個(gè)操作,同時(shí)滿足a與b時(shí),允許操作
          a. 規(guī)定資源可以被哪些類(lèi)別的主體進(jìn)行哪些操作
          b. 規(guī)定主體可以對(duì)哪些等級(jí)的資源進(jìn)行哪些操作
          MAC是ACL的另一種實(shí)現(xiàn),強(qiáng)調(diào)安全性。MAC會(huì)在系統(tǒng)中,對(duì)資源與主體,都劃分類(lèi)別與等級(jí)。比如,等級(jí)分為:秘密級(jí)、機(jī)密級(jí)、絕密級(jí);類(lèi)別分為:軍事人員、財(cái)務(wù)人員、行政人員。

          MAC的優(yōu)勢(shì)就是實(shí)現(xiàn)資源與主體的雙重驗(yàn)證,確保資源的交叉隔離,提高安全性。

          RBAC 基于角色的訪問(wèn)控制

          定義:當(dāng)一個(gè)操作,同時(shí)滿足a與b時(shí),允許操作。
          a. 規(guī)定角色可以對(duì)哪些資源進(jìn)行哪些操作
          b. 規(guī)定主體擁有哪些角色
          RBAC的思想,來(lái)源于現(xiàn)實(shí)世界的企業(yè)結(jié)構(gòu)。
          比如,銷(xiāo)售角色,擁有查看客戶信息的權(quán)限。當(dāng)一個(gè)銷(xiāo)售人員小王入職了,可以把銷(xiāo)售角色賦予小王,那么小王就擁有了查看客戶的權(quán)限。這種方式,避免了ACL模型下,每次新人入職,需要逐個(gè)配置資源表的情況。同樣,權(quán)限變動(dòng)也變得很方便,只要修改角色,即可實(shí)現(xiàn)多用戶的權(quán)限修改。

          ABAC 基于屬性的訪問(wèn)控制

          定義:規(guī)定哪些屬性的主體可以對(duì)哪些屬性的資源在哪些屬性的情況下進(jìn)行哪些操作
          ABAC其中的屬性就是與主體、資源、情況相關(guān)的所有信息。

          主體的屬性:指的是與主體相關(guān)的所有信息,包括主體的年齡、性別、職位等。
          資源的屬性:指的是與資源相關(guān)的所有信息,包括資源的創(chuàng)建時(shí)間、創(chuàng)建位置、密級(jí)等。
          情況的屬性:指的是客觀情況的屬性,比如當(dāng)前的時(shí)間、當(dāng)前的位置、當(dāng)前的場(chǎng)景(普通狀態(tài)、緊急狀態(tài))。
          操作:含義還是一樣,比如增刪改查等。
          設(shè)定一個(gè)權(quán)限,就是定義一條含有四類(lèi)屬性信息的策略(Policy)。
          **一個(gè)請(qǐng)求會(huì)逐條匹配策略,如果沒(méi)有匹配到策略,則返回默認(rèn)效果,默認(rèn)效果可以根據(jù)場(chǎng)景定制,可以是默認(rèn)拒絕或是默認(rèn)允許。**另外,匹配方式也可以根據(jù)場(chǎng)景定制,可以使用逐條順序匹配,匹配到策略直接返回。也可以使用完全匹配,匹配所有的策略,如果有一個(gè)拒絕(允許),則拒絕(允許)。

          Linux權(quán)限D(zhuǎn)AC 安全模型

          DAC 的核心內(nèi)容是:在 Linux 中,進(jìn)程理論上所擁有的權(quán)限與執(zhí)行它的用戶的權(quán)限相同。其中涉及的一切內(nèi)容,都是圍繞這個(gè)核心進(jìn)行的。

          用戶和組 ID 信息控制

          用戶、組、口令信息

          通過(guò) /etc/passwd 和 /etc/group 保存用戶和組信息,通過(guò) /etc/shadow 保存密碼口令及其變動(dòng)信息, 每行一條記錄。
          用戶和組分別用 UID 和 GID 表示,一個(gè)用戶可以同時(shí)屬于多個(gè)組,默認(rèn)每個(gè)用戶必屬于一個(gè)與之 UID 同值同名的 GID 。
          對(duì)于 /etc/passwd , 每條記錄字段分別為 用戶名: 口令(在 /etc/shadow 加密保存):UID:GID(默認(rèn) UID): 描述注釋: 主目錄: 登錄 shell(第一個(gè)運(yùn)行的程序)
          對(duì)于 /etc/group , 每條記錄字段分別為 組名:口令(一般不存在組口令):GID:組成員用戶列表(逗號(hào)分割的用戶 UID 列表)
          對(duì)于 /etc/shadow ,每條記錄字段分別為:登錄名: 加密口令: 最后一次修改時(shí)間: 最小時(shí)間間隔: 最大時(shí)間間隔: 警告時(shí)間: 不活動(dòng)時(shí)間:

          舉例

          以下是對(duì)用戶和組信息的舉例。/etc/shadow 中的口令信息為加密存儲(chǔ),不舉例。

          文件權(quán)限控制信息

          文件類(lèi)型

          Linux 中的文件有如下類(lèi)型:

          • 普通文件, 又包括文本文件和二進(jìn)制文件, 可用 touch 創(chuàng)建;

          • 套接字文件, 用于網(wǎng)絡(luò)通訊,一般由應(yīng)用程序在執(zhí)行中間接創(chuàng)建;

          • 管道文件是有名管道,而非無(wú)名管道, 可用 mkfifo 創(chuàng)建;

          • 字符文件和塊文件均為設(shè)備文件, 可用 mknod 創(chuàng)建;

          • 鏈接文件是軟鏈接文件,而非硬鏈接文件, 可用 ln 創(chuàng)建。

          訪問(wèn)權(quán)限控制組

          分為三組進(jìn)行控制:

          • user 包含對(duì)文件屬主設(shè)定的權(quán)限

          • group 包含對(duì)文件屬組設(shè)定的權(quán)限

          • others 包含對(duì)其他者設(shè)定的權(quán)限

          可設(shè)定的權(quán)限

          下面給出常見(jiàn)(但非全部)的權(quán)限值, 包括:

          • r 表示具有讀權(quán)限。

          • w 表示具有寫(xiě)權(quán)限。

          • x 一般針對(duì)可執(zhí)行文件 / 目錄,表示具有執(zhí)行 / 搜索權(quán)限。

          • s 一般針對(duì)可執(zhí)行文件 / 目錄,表示具有賦予文件屬主權(quán)限的權(quán)限,只有 user 和 group 組可以設(shè)置該權(quán)限。

          • t 一般針對(duì)目錄,設(shè)置粘滯位后,有權(quán)限的用戶只能寫(xiě)、刪除自己的文件, 否則可寫(xiě)、刪除目錄所有文件。舊系統(tǒng)還表示可執(zhí)行文件運(yùn)行后將 text 拷貝到交換區(qū)提升速度。

          舉例

          通過(guò) ls -l 可以查看到其文件類(lèi)型及權(quán)限,通過(guò) chmod 修改權(quán)限。

          舉例來(lái)說(shuō),

          RBAC權(quán)限模型簡(jiǎn)介

          RBAC權(quán)限模型(Role-Based Access Control)即:基于角色的權(quán)限控制。模型中有幾個(gè)關(guān)鍵的術(shù)語(yǔ):

          • 用戶:系統(tǒng)接口及訪問(wèn)的操作者

          • 權(quán)限:能夠訪問(wèn)某接口或者做某操作的授權(quán)資格

          • 角色:具有一類(lèi)相同操作權(quán)限的用戶的總稱

          RBAC權(quán)限模型核心授權(quán)邏輯如下:

          • 某用戶是什么角色?

          • 某角色具有什么權(quán)限?

          • 通過(guò)角色的權(quán)限推導(dǎo)用戶的權(quán)限

          RBAC的演化進(jìn)程

          用戶與權(quán)限直接關(guān)聯(lián)

          想到權(quán)限控制,人們最先想到的一定是用戶與權(quán)限直接關(guān)聯(lián)的模式,簡(jiǎn)單地說(shuō)就是:某個(gè)用戶具有某些權(quán)限。如圖:

          • 張三具有創(chuàng)建用戶和刪除用戶的權(quán)限,所以他可能系統(tǒng)維護(hù)人員

          • 李四具有產(chǎn)品記錄管理和銷(xiāo)售記錄管理權(quán)限,所以他可能是一個(gè)業(yè)務(wù)銷(xiāo)售人員

          這種模型能夠清晰的表達(dá)用戶與權(quán)限之間的關(guān)系,足夠簡(jiǎn)單。但同時(shí)也存在問(wèn)題:

          • 現(xiàn)在用戶是張三、李四,以后隨著人員增加,每一個(gè)用戶都需要重新授權(quán)

          • 或者張三、李四離職,需要針對(duì)每一個(gè)用戶進(jìn)行多種權(quán)限的回收

          一個(gè)用戶擁有一個(gè)角色

          在實(shí)際的團(tuán)體業(yè)務(wù)中,都可以將用戶分類(lèi)。比如對(duì)于薪水管理系統(tǒng),通常按照級(jí)別分類(lèi):經(jīng)理、高級(jí)工程師、中級(jí)工程師、初級(jí)工程師。也就是按照一定的角色分類(lèi),通常具有同一角色的用戶具有相同的權(quán)限。這樣改變之后,就可以將針對(duì)用戶賦權(quán)轉(zhuǎn)換為針對(duì)角色賦權(quán)。

          • 一個(gè)用戶有一個(gè)角色

          • 一個(gè)角色有多個(gè)操作(菜單)權(quán)限

          • 一個(gè)操作權(quán)限可以屬于多個(gè)角色

          我們可以用下圖中的數(shù)據(jù)庫(kù)設(shè)計(jì)模型,描述這樣的關(guān)系。

          一個(gè)用戶一個(gè)或多個(gè)角色

          但是在實(shí)際的應(yīng)用系統(tǒng)中,一個(gè)用戶一個(gè)角色遠(yuǎn)遠(yuǎn)滿足不了需求。如果我們希望一個(gè)用戶既擔(dān)任銷(xiāo)售角色、又暫時(shí)擔(dān)任副總角色。該怎么做呢?為了增加系統(tǒng)設(shè)計(jì)的適用性,我們通常設(shè)計(jì):

          • 一個(gè)用戶有一個(gè)或多個(gè)角色

          • 一個(gè)角色包含多個(gè)用戶

          • 一個(gè)角色有多種權(quán)限

          • 一個(gè)權(quán)限屬于多個(gè)角色

          我們可以用下圖中的數(shù)據(jù)庫(kù)設(shè)計(jì)模型,描述這樣的關(guān)系。

          頁(yè)面訪問(wèn)權(quán)限與操作權(quán)限

          • 頁(yè)面訪問(wèn)權(quán)限: 所有系統(tǒng)都是由一個(gè)個(gè)的頁(yè)面組成,頁(yè)面再組成模塊,用戶是否能看到這個(gè)頁(yè)面的菜單、是否能進(jìn)入這個(gè)頁(yè)面就稱為頁(yè)面訪問(wèn)權(quán)限。

          • 操作權(quán)限: 用戶在操作系統(tǒng)中的任何動(dòng)作、交互都需要有操作權(quán)限,如增刪改查等。比如:某個(gè)按鈕,某個(gè)超鏈接用戶是否可以點(diǎn)擊,是否應(yīng)該看見(jiàn)的權(quán)限。

          為了適應(yīng)這種需求,我們可以把頁(yè)面資源(菜單)和操作資源(按鈕)分表存放,如上圖。也可以把二者放到一個(gè)表里面存放,用一個(gè)字段進(jìn)行標(biāo)志區(qū)分。

          數(shù)據(jù)權(quán)限

          數(shù)據(jù)權(quán)限比較好理解,就是某個(gè)用戶能夠訪問(wèn)和操作哪些數(shù)據(jù)。

          • 通常來(lái)說(shuō),數(shù)據(jù)權(quán)限由用戶所屬的組織來(lái)確定。比如:生產(chǎn)一部只能看自己部門(mén)的生產(chǎn)數(shù)據(jù),生產(chǎn)二部只能看自己部門(mén)的生產(chǎn)數(shù)據(jù);銷(xiāo)售部門(mén)只能看銷(xiāo)售數(shù)據(jù),不能看財(cái)務(wù)部門(mén)的數(shù)據(jù)。而公司的總經(jīng)理可以看所有的數(shù)據(jù)。

          • 在實(shí)際的業(yè)務(wù)系統(tǒng)中,數(shù)據(jù)權(quán)限往往更加復(fù)雜。非常有可能銷(xiāo)售部門(mén)可以看生產(chǎn)部門(mén)的數(shù)據(jù),以確定銷(xiāo)售策略、安排計(jì)劃等。

          所以為了面對(duì)復(fù)雜的需求,數(shù)據(jù)權(quán)限的控制通常是由程序員書(shū)寫(xiě)個(gè)性化的SQL來(lái)限制數(shù)據(jù)范圍的,而不是交給權(quán)限模型或者Spring Securityshiro來(lái)控制。當(dāng)然也可以從權(quán)限模型或者權(quán)限框架的角度去解決這個(gè)問(wèn)題,但適用性有限。

          Spring Security

          springsecurity底層實(shí)現(xiàn)為一條過(guò)濾器鏈,就是用戶請(qǐng)求進(jìn)來(lái),判斷有沒(méi)有請(qǐng)求的權(quán)限,拋出異常,重定向跳轉(zhuǎn)。

          springsecurity自帶一個(gè)登錄頁(yè)。
          從登陸入手,登錄頁(yè)替換成我們自己的,對(duì)輸入的賬號(hào)密碼進(jìn)行驗(yàn)證。

          /** * 表單登陸security * 安全  = 認(rèn)證 + 授權(quán) */
          @Configurationpublic class SecurityConfig extends WebSecurityConfigurerAdapter {
          @Override protected void configure(HttpSecurity http) throws Exception { //以下五步是表單登錄進(jìn)行身份認(rèn)證最簡(jiǎn)單的登陸環(huán)境 http.formLogin() //表單登陸 1 .and() //2 .authorizeRequests() //下面的都是授權(quán)的配置 3 .anyRequest() //任何請(qǐng)求 4 .authenticated(); //訪問(wèn)任何資源都需要身份認(rèn)證 5

          }}

          如果只實(shí)現(xiàn)一個(gè)WebSecurityConfigurerAdapter然后重寫(xiě)一下configure方法,效果會(huì)默認(rèn)使用springsecurity的登錄頁(yè) ,以及項(xiàng)目啟動(dòng)時(shí)后臺(tái)會(huì)打印出一個(gè)默認(rèn)的密碼,然后使用任意賬號(hào)就可以進(jìn)行登錄訪問(wèn)指定的資源

          如果想要使用自己的登錄頁(yè) 并且用戶名密碼是自己數(shù)據(jù)庫(kù)中的,進(jìn)一步完善spring security認(rèn)證體系,首先需要做以下配置。

            @Override    protected void configure(HttpSecurity http) throws Exception {            //以下五步是表單登錄進(jìn)行身份認(rèn)證最簡(jiǎn)單的登陸環(huán)境            http.formLogin() //表單登陸 1                    .loginPage("/login.html") //指定登陸頁(yè)面                .and() //2                .authorizeRequests() //下面的都是授權(quán)的配置 3                    .antMatchers("/login.html").permitAll()//訪問(wèn)此地址就不需要進(jìn)行身份認(rèn)證了,防止重定向死循環(huán)                .anyRequest() //任何請(qǐng)求 4                .authenticated(); //訪問(wèn)任何資源都需要身份認(rèn)證 5    }

          然后實(shí)現(xiàn)UserDetailsService接口進(jìn)行用戶姓名密碼校驗(yàn) (由于springboot2.x中security是5.x版本的,所以這里的密碼是默認(rèn)做了BCrypt加密的,就需要bean一個(gè)BCrypt)

          @Componentpublic class MyUserDetailService implements UserDetailsService {
          //注入mapper //...
          @Autowired private PasswordEncoder passwordEncoder;
          private Logger LOG = LoggerFactory.getLogger(MyUserDetailService.class);
          @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { LOG.error("登陸用戶輸入的用戶名:{}",s);
          //根據(jù)用戶名查找用戶信息
          //密碼進(jìn)行bcrypt加密 String pwd = "wangkai"; //String cryptPwd = BCrypt.hashpw(pwd, BCrypt.gensalt()); String cryptPwd = passwordEncoder.encode(pwd);
          LOG.error("加密后的密碼為: {}",cryptPwd);
          return new User("s",cryptPwd, AuthorityUtils.commaSeparatedStringToAuthorityList("admin")); //賬號(hào) 密碼 權(quán)限 }}
          /** * 表單登陸security * 安全  = 認(rèn)證 + 授權(quán) */
          @Configurationpublic class SecurityConfig extends WebSecurityConfigurerAdapter {
          /** * 介紹 * springboot2.x引入的security版本是5.x的,這個(gè)版本需要提供一個(gè)PasswordEncoder實(shí)例,不然就會(huì)報(bào)錯(cuò) * @return */ @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }
          @Override protected void configure(HttpSecurity http) throws Exception { //以下五步是表單登錄進(jìn)行身份認(rèn)證最簡(jiǎn)單的登陸環(huán)境 http.formLogin() //表單登陸 1 .loginPage("/login.html") //指定登陸頁(yè)面 .and() //2 .authorizeRequests() //下面的都是授權(quán)的配置 3 .antMatchers("/login.html").permitAll()//訪問(wèn)此地址就不需要進(jìn)行身份認(rèn)證了,防止重定向死循環(huán) .anyRequest() //任何請(qǐng)求 4 .authenticated(); //訪問(wèn)任何資源都需要身份認(rèn)證 5 }}

          添加登陸頁(yè)面提交頁(yè)面,關(guān)閉跨站請(qǐng)求偽造攻擊,登陸訪問(wèn)資源

          <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>登陸</title></head><body>   <h2>標(biāo)準(zhǔn)登陸頁(yè)面</h2>   <h3>表單登陸</h3>   <form action = "/authentication/form" method ="post">        <table>            <tr>                <td>用戶名:</td>                <td><input type="text" name="username"></td>            </tr>            <tr>                <td>密碼:</td>                <td><input type="password" name="password"></td>            </tr>            <tr>                <td colspan="2"><button type="submit">登陸</button></td>            </tr>        </table>   </form></body></html>
          @Override    protected void configure(HttpSecurity http) throws Exception {            //以下五步是表單登錄進(jìn)行身份認(rèn)證最簡(jiǎn)單的登陸環(huán)境            http.formLogin() //表單登陸 1                .loginPage("/login.html") //指定登陸頁(yè)面                .loginProcessingUrl("/authentication/form")//登陸頁(yè)面提交的頁(yè)面 開(kāi)始使用UsernamePasswordAuthenticationFilter過(guò)濾器處理請(qǐng)求                .and() //2                .authorizeRequests() //下面的都是授權(quán)的配置 3                .antMatchers("/login.html").permitAll()//訪問(wèn)此地址就不需要進(jìn)行身份認(rèn)證了,防止重定向死循環(huán)                .anyRequest() //任何請(qǐng)求 4                .authenticated() //訪問(wèn)任何資源都需要身份認(rèn)證 5                .and()                .csrf().disable();//關(guān)閉跨站請(qǐng)求偽造攻擊攔截
          }

          動(dòng)態(tài)配置登錄頁(yè)

          .做一個(gè)我們自己默認(rèn)的登錄頁(yè),如果不想用默認(rèn)的也可以動(dòng)態(tài)配置。使用到的注解@ConfigurationProperties。
          .增加接口/authentication/require
          .引導(dǎo)用戶進(jìn)入登錄頁(yè)登陸

             @Override    protected void configure(HttpSecurity http) throws Exception {            //以下五步是表單登錄進(jìn)行身份認(rèn)證最簡(jiǎn)單的登陸環(huán)境            http.formLogin() //表單登陸 1                //.loginPage("/login.html") //指定登陸頁(yè)面                .loginPage("/authentication/require")                .loginProcessingUrl("/authentication/form")//登陸頁(yè)面提交的頁(yè)面 開(kāi)始使用UsernamePasswordAuthenticationFilter過(guò)濾器處理請(qǐng)求                .and() //2                .authorizeRequests() //下面的都是授權(quán)的配置 3                .antMatchers("/login.html",                        "/authentication/require",                        securityProperties.getBrowser().getLoginPage()).permitAll()//訪問(wèn)此地址就不需要進(jìn)行身份認(rèn)證了,防止重定向死循環(huán)                .anyRequest() //任何請(qǐng)求 4                .authenticated() //訪問(wèn)任何資源都需要身份認(rèn)證 5                .and()                .csrf().disable();//關(guān)閉跨站請(qǐng)求偽造攻擊攔截
          }
          @RestControllerpublic class BrowserSecurityController {
          private Logger LOG = LoggerFactory.getLogger(BrowserSecurityController.class);

          //將當(dāng)前請(qǐng)求緩存到session里 private RequestCache requestCache = new HttpSessionRequestCache();
          private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
          @Resource private SecurityProperties securityProperties;
          /** * 當(dāng)需要身份認(rèn)證時(shí)跳轉(zhuǎn)到這里 * @param request * @param response * @return */ @RequestMapping(value = "/authentication/require",method = RequestMethod.GET) @ResponseStatus(code = HttpStatus.UNAUTHORIZED) //未授權(quán)狀態(tài)碼 public SimpleResponse requireAuthentication(HttpServletRequest request, HttpServletResponse response) throws IOException {
          //拿到引發(fā)跳轉(zhuǎn)的請(qǐng)求 SavedRequest savedRequest = requestCache.getRequest(request,response);
          if(savedRequest != null){ String targetUrl = savedRequest.getRedirectUrl(); String fileUrl=new URL(targetUrl).getFile(); LOG.info("引發(fā)跳轉(zhuǎn)的請(qǐng)求是:{}",targetUrl);
          if(StringUtils.endsWithIgnoreCase(targetUrl,".html") || fileUrl.equals("/")){ //調(diào)轉(zhuǎn)到登錄頁(yè) 》》這里登錄頁(yè)做成可配置的 redirectStrategy.sendRedirect(request,response,securityProperties.getBrowser().getLoginPage()); } } return new SimpleResponse("訪問(wèn)資源需要登陸,請(qǐng)?jiān)L問(wèn)登陸頁(yè)面"); }
          }

          從配置文件中讀取當(dāng)訪問(wèn)資源需要身份認(rèn)證調(diào)轉(zhuǎn)的頁(yè)面地址

          server.port=8888 #自定義springsecurity 登錄頁(yè)面 security.browser.loginPage = /mylogin.html

          package com.example.security.properties;
          import com.example.security.pojo.SecurityBrowserPojo;import org.springframework.boot.context.properties.ConfigurationProperties;
          /** * 實(shí)現(xiàn)動(dòng)態(tài)配置用戶專(zhuān)屬登陸頁(yè)面 */@ConfigurationProperties(prefix = "security")public class SecurityProperties {

          private SecurityBrowserPojo browser = new SecurityBrowserPojo();
          public SecurityBrowserPojo getBrowser() { return browser; }
          public void setBrowser(SecurityBrowserPojo browser) { this.browser = browser; }}
          public class SecurityBrowserPojo {
          //設(shè)置默認(rèn)地址 private String loginPage = "/login.html";
          public String getLoginPage() { return loginPage; }
          public void setLoginPage(String loginPage) { this.loginPage = loginPage; }}
          package com.example.security.config.securityconfig;
          import com.example.security.properties.SecurityProperties;import org.springframework.boot.context.properties.EnableConfigurationProperties;import org.springframework.context.annotation.Configuration;
          @Configuration@EnableConfigurationProperties({SecurityProperties.class}) //設(shè)置注解讀取生效 (試了下不用配置這里@ConfigurationProperties也可以生效)public class SecurityPropertiesConfig {}

          某些時(shí)候用戶登陸成功,登陸失敗的時(shí)候可能還需要做一些操作,比如成功登陸增加一積分之類(lèi)的操作,這里需要做兩個(gè)handler處理器

          /** * 設(shè)置通過(guò)請(qǐng)求攔截。登陸成功后處理 */@Component("wawAuthenticationSuccessHandler")public class WawAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
          private Logger LOG = LoggerFactory.getLogger(WawAuthenticationSuccessHandler.class);
          @Resource private ObjectMapper objectMapper;
          /** * @param authentication 封裝認(rèn)證信息>>用戶信息 請(qǐng)求ip之類(lèi)的 * @throws IOException * @throws ServletException */ @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { LOG.info("登陸成功");
          response.setContentType("application/json;charset=UTF-8"); response.getWriter().write(objectMapper.writeValueAsString(authentication)); }}

          /** * 設(shè)置通過(guò)請(qǐng)求攔截。登陸失敗后處理 */@Component("wawAuthenticationFailHandler")public class WawAuthenticationFailHandler implements AuthenticationFailureHandler{
          private Logger LOG = LoggerFactory.getLogger(WawAuthenticationFailHandler.class);
          @Resource private ObjectMapper objectMapper;
          @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException { LOG.info("登陸失敗");
          response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); response.setContentType("application/json;charset=UTF-8"); response.getWriter().write(objectMapper.writeValueAsString(e));


          }}

          成功與失敗的處理器 配置到配置信息中


          @Override protected void configure(HttpSecurity http) throws Exception { //以下五步是表單登錄進(jìn)行身份認(rèn)證最簡(jiǎn)單的登陸環(huán)境 http.formLogin() //表單登陸 1 //.loginPage("/login.html") //指定登陸頁(yè)面 .loginPage("/authentication/require") .loginProcessingUrl("/authentication/form")//登陸頁(yè)面提交的頁(yè)面 開(kāi)始使用UsernamePasswordAuthenticationFilter過(guò)濾器處理請(qǐng)求 .successHandler(wawAuthenticationSuccessHandler) .failureHandler(wawAuthenticationFailHandler) .and() //2 .authorizeRequests() //下面的都是授權(quán)的配置 3 .antMatchers("/authentication/require", "/login.html", securityProperties.getBrowser().getLoginPage()).permitAll()//訪問(wèn)此地址就不需要進(jìn)行身份認(rèn)證了,防止重定向死循環(huán) .anyRequest() //任何請(qǐng)求 4 .authenticated() //訪問(wèn)任何資源都需要身份認(rèn)證 5 .and() .csrf().disable();//關(guān)閉跨站請(qǐng)求偽造攻擊攔截
          }

          登陸失敗就會(huì)返回500 登陸異常信息


          瀏覽 22
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  人妻夜夜爽天天爽三区麻豆AV网站 | 91无码电影 | 亚洲日韩免费在线观看 | 亚洲无码家庭 | 青娱乐大香蕉视频在线观看 |