1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

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

        共 13712字,需瀏覽 28分鐘

         ·

        2022-11-01 18:12

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

        ACL

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

        DAC 自主訪問控制

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

        MAC 強(qiáng)制訪問控制

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

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

        RBAC 基于角色的訪問控制

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

        ABAC 基于屬性的訪問控制

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

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

        用戶、組、口令信息

        通過 /etc/passwd 和 /etc/group 保存用戶和組信息,通過 /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)限控制信息

        文件類型

        Linux 中的文件有如下類型:

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

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

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

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

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

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

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

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

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

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

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

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

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

        • w 表示具有寫權(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)限的用戶只能寫、刪除自己的文件, 否則可寫、刪除目錄所有文件。舊系統(tǒng)還表示可執(zhí)行文件運(yùn)行后將 text 拷貝到交換區(qū)提升速度。

        舉例

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

        舉例來說,

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

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

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

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

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

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

        • 某用戶是什么角色?

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

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

        RBAC的演化進(jìn)程

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        Spring Security

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

        springsecurity自帶一個(gè)登錄頁。
        從登陸入手,登錄頁替換成我們自己的,對(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)證最簡單的登陸環(huán)境 http.formLogin() //表單登陸 1 .and() //2 .authorizeRequests() //下面的都是授權(quán)的配置 3 .anyRequest() //任何請(qǐng)求 4 .authenticated(); //訪問任何資源都需要身份認(rèn)證 5

        }}

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

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

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

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

        <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>登陸</title></head><body>   <h2>標(biāo)準(zhǔn)登陸頁面</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)證最簡單的登陸環(huán)境            http.formLogin() //表單登陸 1                .loginPage("/login.html") //指定登陸頁面                .loginProcessingUrl("/authentication/form")//登陸頁面提交的頁面 開始使用UsernamePasswordAuthenticationFilter過濾器處理請(qǐng)求                .and() //2                .authorizeRequests() //下面的都是授權(quán)的配置 3                .antMatchers("/login.html").permitAll()//訪問此地址就不需要進(jìn)行身份認(rèn)證了,防止重定向死循環(huán)                .anyRequest() //任何請(qǐng)求 4                .authenticated() //訪問任何資源都需要身份認(rèn)證 5                .and()                .csrf().disable();//關(guān)閉跨站請(qǐng)求偽造攻擊攔截
        }

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

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

           @Override    protected void configure(HttpSecurity http) throws Exception {            //以下五步是表單登錄進(jìn)行身份認(rèn)證最簡單的登陸環(huán)境            http.formLogin() //表單登陸 1                //.loginPage("/login.html") //指定登陸頁面                .loginPage("/authentication/require")                .loginProcessingUrl("/authentication/form")//登陸頁面提交的頁面 開始使用UsernamePasswordAuthenticationFilter過濾器處理請(qǐng)求                .and() //2                .authorizeRequests() //下面的都是授權(quán)的配置 3                .antMatchers("/login.html",                        "/authentication/require",                        securityProperties.getBrowser().getLoginPage()).permitAll()//訪問此地址就不需要進(jìn)行身份認(rèn)證了,防止重定向死循環(huán)                .anyRequest() //任何請(qǐng)求 4                .authenticated() //訪問任何資源都需要身份認(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)到登錄頁 》》這里登錄頁做成可配置的 redirectStrategy.sendRedirect(request,response,securityProperties.getBrowser().getLoginPage()); } } return new SimpleResponse("訪問資源需要登陸,請(qǐng)?jiān)L問登陸頁面"); }
        }

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

        server.port=8888 #自定義springsecurity 登錄頁面 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)配置用戶專屬登陸頁面 */@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í)候可能還需要做一些操作,比如成功登陸增加一積分之類的操作,這里需要做兩個(gè)handler處理器

        /** * 設(shè)置通過請(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之類的 * @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è)置通過請(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)證最簡單的登陸環(huán)境 http.formLogin() //表單登陸 1 //.loginPage("/login.html") //指定登陸頁面 .loginPage("/authentication/require") .loginProcessingUrl("/authentication/form")//登陸頁面提交的頁面 開始使用UsernamePasswordAuthenticationFilter過濾器處理請(qǐng)求 .successHandler(wawAuthenticationSuccessHandler) .failureHandler(wawAuthenticationFailHandler) .and() //2 .authorizeRequests() //下面的都是授權(quán)的配置 3 .antMatchers("/authentication/require", "/login.html", securityProperties.getBrowser().getLoginPage()).permitAll()//訪問此地址就不需要進(jìn)行身份認(rèn)證了,防止重定向死循環(huán) .anyRequest() //任何請(qǐng)求 4 .authenticated() //訪問任何資源都需要身份認(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)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产精品国产a级 | 夫妻性生活自拍视频 | 国产美女**毛片1 | 久久久天堂国产精品女人 | 豆花官网免费看 | 精品人妻一区二区免费蜜桃视频 | 无码激情做a爰片毛片A片孕妇 | 五月丁香婷婷在线视频 | 挺进太深了h御宅屋 | 狠狠干狠狠操视频 |