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

資訊專欄INFORMATION COLUMN

基于shiro框架實(shí)現(xiàn)自動(dòng)登錄(rememberMe)

gghyoo / 1479人閱讀

摘要:關(guān)于的自動(dòng)對(duì)用戶對(duì)象序列化并加密當(dāng)獲得請(qǐng)求時(shí)能夠獲取反序列化且解密之后的用戶對(duì)象。

shirorememberMe流程原理研究

輸入用戶密碼正兒八經(jīng)登錄時(shí), 如果勾選了"記住我", 則后臺(tái)給shiro設(shè)置rememberme

前一次登錄勾選了記住我, 則本次登錄時(shí)isRemembered()==true(如果上一次設(shè)置了rememberme, 本次登錄是不會(huì)觸發(fā)action中的login()的方法的, 即會(huì)直接進(jìn)入登錄狀態(tài). 這里為了演示, 強(qiáng)行進(jìn)入login()方法).

經(jīng)過shirologin()則表示為認(rèn)證登錄的. 就是說authentication==true. 訪問權(quán)限最高.

rememberMe==true, 則將不會(huì)進(jìn)入任何action. 可以訪問所有user控制的頁面或路徑. 但不能訪問authc控制的.

但是authentication=false. 這里有個(gè)關(guān)鍵點(diǎn):

subject.isAuthenticated()==true,
則subject.isRemembered()==false;
反之一樣

下圖所示, authentication=false, 并且能夠principle不為空, 能夠獲取用戶信息.

關(guān)于過濾器規(guī)則設(shè)置

另外對(duì)于過濾器,一般這樣使用:

訪問一般網(wǎng)頁,如個(gè)人在主頁之類的,我們使用user攔截器即可,user攔截器只要用戶登錄(isRemembered()==true or isAuthenticated()==true)通過即可訪問成功;

訪問特殊網(wǎng)頁,如我的訂單,提交訂單頁面,我們使用authc攔截器即可,authc攔截器會(huì)判斷用戶是否是通過Subject.login(isAuthenticated()==true)登錄的,如果是才放行,否則會(huì)跳轉(zhuǎn)到登錄頁面叫你重新登錄。

關(guān)于rememberMecookie

shiro自動(dòng)對(duì)用戶對(duì)象序列化并加密. 當(dāng)獲得請(qǐng)求時(shí), 能夠獲取反序列化且解密之后的用戶對(duì)象。

當(dāng)設(shè)置rememberMe==false, 將會(huì)自動(dòng)清空rememberMe cookie.

如下圖, 在設(shè)置rememberMe==false的前提下, 之前的rememberMe cookie已經(jīng)不見了.

項(xiàng)目重啟后(排除緩存影響). 強(qiáng)行訪問action, 能夠獲取user對(duì)象.

不想要自動(dòng)登錄怎么辦?

調(diào)用shirologout()方法, 即消除自動(dòng)登錄功能.

rememberMe功能實(shí)現(xiàn) 簡(jiǎn)單實(shí)現(xiàn)

引入shiro框架

引入maven坐標(biāo).

   
        
            org.apache.shiro
            shiro-all
            ${shiro.version}
        

配置spring


    
    
        
        
        
        
        
        

        
        
            
                /css/**=anon
                /js/**=anon
                /images/**=anon
                /validatecode.jsp*=anon
                /userAction_login.action=anon
                /customerAction_login.action=anon
                /info.jsp*=anon
                /courierAction_pageQuery*=perms["courier:list"]
                /pages/base/courier.jsp*=perms["courier:list"]
                /** = user
                /pay/** = authc

            
        
    
    
    
        
        
        
    
    
    

 

    
    
        
        
    

實(shí)現(xiàn)上文配置文件中realm

public class UserRealm extends AuthorizingRealm {

    @Autowired
    private UserDao userDao;
    @Autowired
    private PermissionDao permissionDao;


    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        // !這里的username可能并不是真正的username, 可能是手機(jī)號(hào)或者其他可以作為登錄憑證的字段!
        String username = token.getUsername();

        User u = userDao.findByUsernameOrTelephone(username, username);
        if (u == null) {
            return null;
        }
        AuthenticationInfo info = new SimpleAuthenticationInfo(u, u.getPassword(), this.getName());
        return info;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        //獲取當(dāng)前用戶
        User user = (User) principalCollection.getPrimaryPrincipal();
        //內(nèi)置用戶:授予所有權(quán)限
        List permissions = null;
        if (user != null && user.getUsername().equals("admin")) {
            permissions = permissionDao.findAll();
        } else { // 其他普通用戶:查出該用戶對(duì)應(yīng)的所有權(quán)限
            permissions = permissionDao.findByUserId(user.getId());
        }

        // 授權(quán)
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        for (Permission p : permissions) {
            info.addStringPermission(p.getKeyword());
        }


        return info;
    }
}

登錄action

   @Action(value = "userAction_login")
    public String login() throws UnsupportedEncodingException {
        Log.begin();
        String validateCode_ser = (String) ServletActionContext.getRequest().getSession().getAttribute("validateCode");
        Subject subject;
        if (StringUtils.isNotBlank(this.validateCode) && this.validateCode.equals(validateCode_ser)) {

            subject = SecurityUtils.getSubject();

            // 不論用戶輸入的是用戶名還是手機(jī)號(hào), 前臺(tái)標(biāo)簽統(tǒng)一用username接收
            UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
            //[[ADD 2018-1-9 14:44:01
            // 設(shè)置是否"記住我"
            rememberme = rememberme == null ? false : rememberme;   //null=>false
            token.setRememberMe(rememberme);
            // ]]

            try {
                subject.login(token);
                if (rememberme)
                    LOG.info("用戶【{}】自動(dòng)登錄----{}", "天王", String.valueOf(System.currentTimeMillis()));
            } catch (AuthenticationException e) {
                e.printStackTrace();
                return LOGIN;
            }
        } else {
            this.addActionError("輸入的驗(yàn)證碼有誤!");
            return ERROR;
        }//end if

        return "home";
    }

注意: 默認(rèn)cookie會(huì)保存一年. 這個(gè)有點(diǎn)太長(zhǎng)了, 通常需要縮短.

自定義cookie, 并指定壽命

主要是spring配置的區(qū)別, 需要: 1. 配置自定義cookie; 2. 注入給rememberMeManager; 3. 將rememberMeManager注入給securityManager.

 
    
    
        
        
        
        
        
        

        
        
            
                /css/**=anon
                /js/**=anon
                /images/**=anon
                /validatecode.jsp*=anon
                /userAction_login.action=anon
                /customerAction_login.action=anon
                /info.jsp*=anon
                /courierAction_pageQuery*=perms["courier:list"]
                /pages/base/courier.jsp*=perms["courier:list"]
                /** = user
                /pay/** = authc

            
        
    
    
    
        
        
        
        
        
    
    

    
    
        
        
        
    

    
    
        
        
    

    
    
        
        
    
復(fù)雜實(shí)現(xiàn)

這種方式需要在spring中配置很多參數(shù). 很繁瑣. 但是功能齊全. 如果只想實(shí)現(xiàn)簡(jiǎn)單的自動(dòng)功能, 可以參照簡(jiǎn)單實(shí)現(xiàn).
本部分spring配置可參見: 第十三章 RememberMe——《跟我學(xué)Shiro》

參考資料:
[1] http://jinnianshilongnian.ite...
[2] http://blog.icoolxue.com/shir...
[3] http://blog.csdn.net/lhacker/...

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

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

相關(guān)文章

  • 不用 Spring Security 可否?試試這個(gè)小而美的安全框架

    摘要:寫在前面在一款應(yīng)用的整個(gè)生命周期,我們都會(huì)談及該應(yīng)用的數(shù)據(jù)安全問題。用戶的合法性與數(shù)據(jù)的可見性是數(shù)據(jù)安全中非常重要的一部分。 寫在前面 在一款應(yīng)用的整個(gè)生命周期,我們都會(huì)談及該應(yīng)用的數(shù)據(jù)安全問題。用戶的合法性與數(shù)據(jù)的可見性是數(shù)據(jù)安全中非常重要的一部分。但是,一方面,不同的應(yīng)用對(duì)于數(shù)據(jù)的合法性和可見性要求的維度與粒度都有所區(qū)別;另一方面,以當(dāng)前微服務(wù)、多服務(wù)的架構(gòu)方式,如何共享Sessi...

    toddmark 評(píng)論0 收藏0
  • 從http驗(yàn)證流程解析CAS單點(diǎn)登錄

    JAVA單點(diǎn)登錄有好多種方式,譬如用cookie的domain做,用中間代理做等等,但都需要自行做許多開發(fā)工作。而其中耶魯大學(xué)的開源項(xiàng)目CAS提供了一個(gè)一站式解決方案,只需很少的擴(kuò)展即可輕松實(shí)現(xiàn)企業(yè)級(jí)單點(diǎn)登錄?;A(chǔ)知識(shí)網(wǎng)上其他挺多的,這里我就不詳述了。本文通過分析http請(qǐng)求過程中httpheader,cookie等數(shù)據(jù)剖析了cas(非代理模式,默認(rèn)驗(yàn)證邏輯。其他如restletAPI等可擴(kuò)展邏輯...

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

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

0條評(píng)論

gghyoo

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<