吐槽下若依(RuoYi)系統的許可權系統(shiro和spring-security)
阿新 • • 發佈:2020-08-26
起因
有接觸若依,目前是前後端分離版本是用的spring-security
,不分離版本是用的shiro
,兩個許可權都有些想吐槽的地方
shiro
以RuoYi為例,當前是4.4.0
版本,我們直接看realm
的配置,在com.ruoyi.framework.shiro.realm
中doGetAuthorizationInfo
方法中:
/** * 登入認證 */ @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
呢?同樣會對初學者參考時造成困擾。
總結
以上就是吐槽點,若依系統本身還是不錯的,而且每個作者都有自己的想法,希望越做越好吧。