起因
有接觸若依,目前是前后端分離版本是用的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
呢?同樣會對初學者參考時造成困擾。
總結
以上就是吐槽點,若依系統本身還是不錯的,而且每個作者都有自己的想法,希望越做越好吧。