吐槽下若依(RuoYi)系統的權限系統(shiro和spring-security)


起因

有接觸若依,目前是前后端分離版本是用的spring-security,不分離版本是用的shiro,兩個權限都有些想吐槽的地方

shiro

RuoYi為例,當前是4.4.0版本,我們直接看realm的配置,在com.ruoyi.framework.shiro.realmdoGetAuthorizationInfo方法中:

    /**
     * 登錄認證
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
    {
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        String username = upToken.getUsername();
        String password = "";
        if (upToken.getPassword() != null)
        {
            password = new String(upToken.getPassword());
        }
        SysUser user = null;
        try
        {
            //這里
            user = loginService.login(username, password);
        }
        catch (CaptchaException e)
        {
            throw new AuthenticationException(e.getMessage(), e);
        }
        ...省略
        //就是這里
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
        return info;
    }

上方SimpleAuthenticationInfo的第二個參數直接將UsernamePasswordToken中的password傳遞過去了,但如果用shiro自身的邏輯的話,應該是將從數據庫查詢出來的user中的password傳遞過去,而且系統在ShiroConfig中壓根沒有配置HashedCredentialsMatcher憑證匹配器,所以shiro默認是用simpleCredentialsMatcher也就是密碼會直接字符串比較不做任何md5等哈希加密來進行密碼匹配,所以這里如果傳遞UsernamePasswordToken中的password那后續的assertCredentialsMatch(token, info)密碼比較方法必然成功,也就是相當於把shiro自帶的密碼驗證功能廢掉了,但若依系統之所以還能正常運行,是因為它實現了自己的密碼比較,就在上方的user = loginService.login(username, password)中。但真的有這個必要自己實現嗎?個人感覺不是很好,因為很多初學者會參考這些系統來學習shiro的配置什么的,感覺會造成困擾。

spring-security

RuoYi-Vue為例,當前版本是3.1.0

  • 目前token采用的是jwt的方式,但令人費解的是,所有的token又在redis做了存儲,以便於可以直接控制失效等,如果是redis中用黑名單的形式來剔除token的話還可以理解,但系統明顯是所有的token都存儲了,那這里用jwt的意義何在,還不如直接返回一個不重復的uuid作為token多好,不用每次都傳遞jwt的這么多數據,也不用額外解析jwt
  • 然后是系統中很多地方用LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest())來獲取當前用戶數據,這個需要再解析token,然后從redis緩存中讀取的數據,不明白為什么不直接從SecurityUtils.getLoginUser()中獲取,明明已經封裝好方法了。
  • 然后是權限校驗方面,我們先看UserDetail的實現類LoginUser
    /**
    * 登錄用戶身份權限
    * 
    * @author ruoyi
    */
    public class LoginUser implements UserDetails
    {
        private static final long serialVersionUID = 1L;
    
        ...省略
    
        /**
        * 權限列表(看這里)
        */
        private Set<String> permissions;
    
    ...省略
    
        public LoginUser(SysUser user, Set<String> permissions)
        {
            this.user = user;
            this.permissions = permissions;
        }
    
        ...省略
        //還有看這里
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities()
        {
            return null;
        }
    }
    
    
    這里明明有getAuthorities這個方面來設置權限,但偏偏不用,而是自己定義一個permissions來存放權限,然后導致@PreAuthorize("@ss.hasPermi('system:dict:list')")也只能能自定義了一個PermissionService來再實現hasPermi等方法,但這樣有意義嗎?為啥不直接用getAuthorities呢?同樣會對初學者參考時造成困擾。

總結

以上就是吐槽點,若依系統本身還是不錯的,而且每個作者都有自己的想法,希望越做越好吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM