成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

我是這樣用shiro的

nanchen2251 / 3012人閱讀

摘要:我這里為了簡化只寫了用戶名密碼參數(shù)。如下代碼可以退出當(dāng)前用戶,這樣我們?cè)僬?qǐng)求登錄的時(shí)候就會(huì)繼續(xù)安全認(rèn)證了。當(dāng)我們登錄成功后,我們用是角色但是沒有權(quán)限的用戶訪問是可以請(qǐng)求成功,但是訪問是會(huì)跳轉(zhuǎn)到的配置文件的對(duì)應(yīng)的地址,表示權(quán)限不足不可訪問。

小述

我在shiro學(xué)習(xí)上花費(fèi)了一些時(shí)間,shiro的資料網(wǎng)上一大推,之前自己學(xué)習(xí)的知識(shí)點(diǎn)一直記錄在有道云筆記上,有道云有自己的好處 那就是沒有網(wǎng)絡(luò)的時(shí)候依然可以記錄一些東西,但是弊端就是不能與大家一起分享和討論,最后還是選擇在segmentFault,一上來發(fā)現(xiàn)自己聲望值是負(fù)數(shù),有點(diǎn)小悲傷啊,以后學(xué)習(xí)到東西后自己會(huì)在這里寫寫記記,一是歸納梳理知識(shí)且自己記性不好,方便以后自我回憶,二是希望能和大家討論,我有不對(duì)的地方希望能有大神指點(diǎn)。廢話不多說,寫一下我最近學(xué)習(xí)的shiro的用法。

正文

大體的登錄認(rèn)證流程如上圖,當(dāng)進(jìn)入登錄頁面后,會(huì)先進(jìn)入通過shiroFilter安全認(rèn)證過濾器,然后讀取數(shù)據(jù)庫信息來進(jìn)行登錄和授權(quán)的認(rèn)證,這一部分是交給realm來進(jìn)行的,當(dāng)認(rèn)證成功后會(huì)跳轉(zhuǎn)到successURL對(duì)應(yīng)的地址中去如果失敗會(huì)跳轉(zhuǎn)到loginUrl中。圖上的的${adminPath}只是從配置文件properties中讀出配置參數(shù)罷了,可以把它看成/a。

web.xml配置
    
    
        shiroFilter
        org.springframework.web.filter.DelegatingFilterProxy
        
            targetFilterLifecycle
            true
        
    
    
        shiroFilter
        /*
    

web.xml基本上是固定模板,/*攔截了所有的請(qǐng)求,但是記住下shiroFilter這個(gè)名字。

spring-context-shiro.xml 配置
Shiro Configuration

    
    
    
    
    
        
            
                /static/** = anon
                /userfiles/** = anon
                ${adminPath}/login = authc
                ${adminPath}/logout = logout
                ${adminPath}/sys/** = roles[sys]
                ${adminPath}/cms/** = perms[cms:view]
                ${adminPath}/** = user
            
        
    
    
    
    
         
        
        
        
        
            
                
            
        
        
            
        
    
    
    
    
        
        
    
    
    
    
    
    
    
        
    
    
        
    

XML配置文件中很多也是固定不變的,官網(wǎng)文檔也有介紹,anon表示請(qǐng)求對(duì)應(yīng)的路徑不認(rèn)證,authc表示請(qǐng)求對(duì)應(yīng)的路徑需要登錄認(rèn)證,roles[sys]表示請(qǐng)求對(duì)應(yīng)的路徑需要角色為sys的才允許,perms[cms:view]表示請(qǐng)求對(duì)應(yīng)的路徑需要有cms:view權(quán)限的才允許。這里的安全認(rèn)證過濾器的名字要與web.xml中的shiroFilter一樣。

表示登錄失敗后會(huì)跳轉(zhuǎn)到對(duì)應(yīng)請(qǐng)求

表示登錄成功后會(huì)跳轉(zhuǎn)的請(qǐng)求

表示訪問了無權(quán)訪問的鏈接后跳轉(zhuǎn)的請(qǐng)求。

 

表示 authc這個(gè)會(huì)通過FormAuthenticationFilter這個(gè)類來驗(yàn)證

這是我們自定義的realm來認(rèn)證登錄和授權(quán)信息的

實(shí)驗(yàn)的目錄結(jié)構(gòu),如上圖

重寫FormAuthenticationFilter類
@Service
public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.FormAuthenticationFilter{
    
    public static final String DEFAULT_CAPTCHA_PARAM = "validateCode";
    
    private String captchaParam = DEFAULT_CAPTCHA_PARAM;

    @Override
    protected AuthenticationToken createToken(ServletRequest request,ServletResponse response) {
        System.out.println("-------------進(jìn)入創(chuàng)建token方法-------------");
        // TODO Auto-generated method stub
        String username = getUsername(request);
        String password = getPassword(request);
        if(password == null){
            password = "";
        }
        String captcha = getCapcha(request);
        System.out.println("-------------出創(chuàng)建token方法-------------");
        return new UsernamePasswordToken(username,password,captcha);
    }
    
    
    public String getCapcha(ServletRequest request){
        return WebUtils.getCleanParam(request, captchaParam);
    }
    
    public String getSuccessUrl(){
        return super.getSuccessUrl();
    }
    
    @Override
    protected void issueSuccessRedirect(ServletRequest request,ServletResponse response) throws Exception {
        // TODO Auto-generated method stub、
        System.out.println("-------------issueSuccessRedirect-------------");
        WebUtils.issueRedirect(request, response, getSuccessUrl());
    }


    @Override
    protected boolean onLoginFailure(AuthenticationToken token,AuthenticationException e, ServletRequest request,
            ServletResponse response) {
        // TODO Auto-generated method stub
        System.out.println("-------------onLoginFailure-------------");
        String className = e.getClass().getName();
        String message = "";
        System.out.println("=========e.getCLass().getName()===========:"+className);
        if(IncorrectCredentialsException.class.getName().equals(className)
                || UnknownAccountException.class.getName().equals(className)){
            message = "用戶名或密碼錯(cuò)誤";
        }else{
            message = "系統(tǒng)出現(xiàn)點(diǎn)問題,請(qǐng)稍后再試!";
            e.printStackTrace(); // 輸出到控制臺(tái)
        }
        request.setAttribute("message",message);
        return true;
    }

}

當(dāng)我們輸入完用戶密碼后需要進(jìn)入一個(gè) shiroFilter 安全認(rèn)證過濾器,這里為什么需要重寫了呢,其實(shí)本質(zhì)是shiro已經(jīng)給我們提供了相應(yīng)的 FormAuthenticationFilter 類,可以在其中根據(jù)用戶輸入的信息創(chuàng)建 token 來供以后流程的認(rèn)證,但是如果我們還想加入一些其他的東西來一起創(chuàng)建這個(gè) token,比如說我們通過用戶名、密碼、驗(yàn)證碼、是否記住我、是否是手機(jī)端登錄等等信息來一起組成一個(gè)token的時(shí)候,這個(gè)時(shí)候我們就可以重寫 FormAuthenticationFilter 中的一些方法來實(shí)現(xiàn)了。

WebUtils.getCleanParam(request, captchaParam) 是 shiro 給我們提供的封裝,其實(shí)就是 request.getParameter(paramName) 的一個(gè)封裝罷了,我們可以通過它來獲取前臺(tái)輸入的參數(shù)。

重寫UsernamePasswordToken類
public class UsernamePasswordToken extends org.apache.shiro.authc.UsernamePasswordToken{
    
    private static final long serialVersionUID = 1L;
    
    private String captcha;
    
    public UsernamePasswordToken(String username,String password){
        super(username,password);
    }

    public UsernamePasswordToken() {
        super();
    }
    
    public UsernamePasswordToken(String username,String password,String captcha){
        super(username,password);
        this.captcha = captcha;
    }

    public String getCaptcha() {
        return captcha;
    }

    public void setCaptcha(String captcha) {
        this.captcha = captcha;
    }
    
}

通過重寫UsernamePasswordToken,目的是來根據(jù)開發(fā)者想創(chuàng)建token的參數(shù)來構(gòu)造出一個(gè)新的UsernamePasswordToken以供使用。我這里為了簡化只寫了用戶名密碼參數(shù)。

此時(shí)此刻我們就有了token,下面開始我們的認(rèn)證啦~

通過自定義的 Realm 來認(rèn)證授權(quán)
@Service
public class SystemAuthorizingRealm extends AuthorizingRealm{
    
    @Autowired
    private SystemService systemService;
    /**
     * 登錄認(rèn)證
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
        // TODO Auto-generated method stub
        System.out.println("-------------進(jìn)入登錄認(rèn)證方法-------------");
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
        String username = token.getUsername();
        User user = systemService.getUserByName(username);
        System.out.println("-------1----getName()--------:"+getName());
        if(user != null){
            System.out.println("-------2----getName()--------:"+getName());
            System.out.println("-------------登錄認(rèn)證結(jié)束--返回SimpleAuthenticationInfo-------------");
            return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
        }else{
            System.out.println("------------登錄認(rèn)證結(jié)束--返回null------------");
            return null;
        }
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // TODO Auto-generated method stub
        System.out.println("-------------進(jìn)入授權(quán)認(rèn)證方法-------------");
//        Principal principal = (Principal) getAvailablePrincipal(principals);
        String name = (String) principals.getPrimaryPrincipal();
//        User user = systemService.getUserByName(principal.getName());
        User user = systemService.getUserByName(name);
        if(user != null){
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            List Roles = systemService.getRoleByUserId(user.getId());
            for(Role r:Roles){
                System.out.println("role---> "+r.getRole());
                info.addRole(r.getRole());
                List Perms = systemService.getPermByRoleId(r.getId());
                if(Perms != null && Perms.size() >0 ){
                    for(Perm p:Perms){
                        System.out.println("perm---> "+p.getPermission());
                        info.addStringPermission(p.getPermission());
                    }
                }
            }
            System.out.println("-----------授權(quán)認(rèn)證結(jié)束--返回info------------");
            return info;
        }else{
            System.out.println("-----------授權(quán)認(rèn)證結(jié)束--返回null------------");
            return null;
        }
    }
}

在 realm 中我們需要繼承 AuthorizingRealm,并重寫兩個(gè)方法:

doGetAuthenticationInfo 方法:用戶身份認(rèn)證方法,根據(jù)參數(shù)返回
SimpleAuthenticationInfo,如果登錄成功則跳轉(zhuǎn)到xml配置文件中的 successUrl 地址,如果登錄失敗則跳轉(zhuǎn)到 loginUrl 地址;

doGetAuthorizationInfo 方法:身份權(quán)限認(rèn)證,利用了 SimpleAuthorizationInfo,把角色和權(quán)限都給予 SimpleAuthorizationInfo 來進(jìn)行授權(quán);在是 shiro 中如果訪問了無權(quán)訪問的地址,則會(huì)跳轉(zhuǎn)到 xml 配置文件中
unauthorizedUrl 對(duì)應(yīng)的地址。

到這里基本上shiro就完畢了,當(dāng)我們登錄時(shí)候的順序:

上圖為登錄成功的流程

上圖為登錄失敗的流程

這時(shí)候 shiro 已經(jīng)記住了用戶的信息,當(dāng)再請(qǐng)求路徑的時(shí)候就不會(huì)繼續(xù)驗(yàn)證了,在此輸入請(qǐng)求攔連接的時(shí)候就會(huì)直接去找對(duì)應(yīng)的 action 而不會(huì)再進(jìn)入安全過濾器,所有我們想在此登錄需要退出當(dāng)前用戶才行。如下代碼可以退出當(dāng)前用戶,這樣我們?cè)僬?qǐng)求登錄的時(shí)候就會(huì)繼續(xù)安全認(rèn)證了。

SecurityUtils.getSubject().logout();

當(dāng)我們登錄成功后,我們用是sys角色但是沒有 perms[cms:view] 權(quán)限 的用戶訪問 a/sys 是可以請(qǐng)求成功,但是訪問 a/cms 是會(huì)跳轉(zhuǎn)到 shiro 的 xml 配置文件的unauthorizedUrl 對(duì)應(yīng)的地址,表示權(quán)限不足不可訪問。

上圖為授權(quán)成功,用戶有該請(qǐng)求權(quán)限,跳轉(zhuǎn)到對(duì)應(yīng) action 中

上圖為授權(quán)失敗,跳轉(zhuǎn)到 unauthorized.jsp 頁面,提示無權(quán)訪問

以后會(huì)有新的內(nèi)容會(huì)加已補(bǔ)充,比如shiro的標(biāo)簽和shiro和ehcache的整合等等。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/70053.html

相關(guān)文章

  • Shiro權(quán)限管理(一)——介紹

    摘要:大家好,今天給大家分享一個(gè)權(quán)限管理的框架的,說實(shí)話本來我是準(zhǔn)備看的,畢竟是家族的框架,和整合更加容易一些。官方給出的介紹是是一個(gè)強(qiáng)大且易用的安全框架執(zhí)行身份驗(yàn)證授權(quán)密碼學(xué)和會(huì)話管理。由此可知,的主要功能是認(rèn)證授權(quán)加密密和會(huì)話管理。 showImg(https://segmentfault.com/img/bV1BsT?w=1726&h=256); 大家好,今天給大家分享一個(gè)權(quán)限管理的框...

    liuhh 評(píng)論0 收藏0
  • Shiro權(quán)限管理(一)——介紹

    摘要:大家好,今天給大家分享一個(gè)權(quán)限管理的框架的,說實(shí)話本來我是準(zhǔn)備看的,畢竟是家族的框架,和整合更加容易一些。官方給出的介紹是是一個(gè)強(qiáng)大且易用的安全框架執(zhí)行身份驗(yàn)證授權(quán)密碼學(xué)和會(huì)話管理。由此可知,的主要功能是認(rèn)證授權(quán)加密密和會(huì)話管理。 showImg(https://segmentfault.com/img/bV1BsT?w=1726&h=256); 大家好,今天給大家分享一個(gè)權(quán)限管理的框...

    王偉廷 評(píng)論0 收藏0
  • 【Java EE】從零開始寫項(xiàng)目【總結(jié)】

    摘要:目前該功能并未完善,敬請(qǐng)期待。反正每次都會(huì)有新的東西補(bǔ)充上去一開始我本來想做的是可以使用微信登陸,也可以使用賬戶郵箱登陸,也可以使用短信登陸的。后來發(fā)現(xiàn)微信登陸要企業(yè)認(rèn)證,做不了。 從零開發(fā)項(xiàng)目概述 最近這一直在復(fù)習(xí)數(shù)據(jù)結(jié)構(gòu)和算法,也就是前面發(fā)出去的排序算法八大基礎(chǔ)排序總結(jié),Java實(shí)現(xiàn)單向鏈表,棧和隊(duì)列就是這么簡單,十道簡單算法題等等... 被虐得不要不要的,即使是非常簡單有時(shí)候繞半...

    imtianx 評(píng)論0 收藏0
  • Spring Security

    摘要:框架具有輕便,開源的優(yōu)點(diǎn),所以本譯見構(gòu)建用戶管理微服務(wù)五使用令牌和來實(shí)現(xiàn)身份驗(yàn)證往期譯見系列文章在賬號(hào)分享中持續(xù)連載,敬請(qǐng)查看在往期譯見系列的文章中,我們已經(jīng)建立了業(yè)務(wù)邏輯數(shù)據(jù)訪問層和前端控制器但是忽略了對(duì)身份進(jìn)行驗(yàn)證。 重拾后端之Spring Boot(四):使用JWT和Spring Security保護(hù)REST API 重拾后端之Spring Boot(一):REST API的搭建...

    keelii 評(píng)論0 收藏0
  • Shiro統(tǒng)一認(rèn)證授權(quán)

    摘要:的統(tǒng)一認(rèn)證授權(quán)是下面的一個(gè)簡單,易用的權(quán)限框架,對(duì)于單體應(yīng)用來講,完全能夠極好的,快速的滿足權(quán)限的需求,所以一般在做項(xiàng)目的時(shí)候,都會(huì)成為開發(fā)者的首選。 Shiro的統(tǒng)一認(rèn)證授權(quán) Shiro是Apache下面的一個(gè)簡單,易用的Java權(quán)限框架,對(duì)于單體應(yīng)用來講,Shiro完全能夠極好的,快速的滿足權(quán)限的需求,所以一般在做項(xiàng)目的時(shí)候,Shiro都會(huì)成為開發(fā)者的首選。 可是,如果你需要做第二...

    cocopeak 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<