起因
有接触若依,目前是前后端分离版本是用的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呢?同样会对初学者参考时造成困扰。
总结
以上就是吐槽点,若依系统本身还是不错的,而且每个作者都有自己的想法,希望越做越好吧。