1,问题描述
昨天下午,有位博友在工作中用到了shiro,遇到了自己没有想明白的一个问题,贴聊天记录,^_^
原来这位博友是在疑惑,shiro中的
SecurityUtils.getSubject().getPrincipal()
方法为啥能获取登录用户的基本信息
2,问题分析
①用户登录时进行授权,服务器保存了登录用户的登录信息
我们查看登录接口,最后未找到登录逻辑中与shiro相关的代码。只有在ShiroConfig中配置了
filterMap.put("/v1/user/login", "anon");
这行代码是过滤掉登录的权限认证。
②用户调用接口时,服务端获得用户的传过来的token,获取到了当前登录用户的基本信息
首先shiro的认证是在自定义的Realm中。用过shiro的博友都知道,自定义Realm会必须重写
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
方法。这个就是shiro认证的时候调用的方法。在实现中,我们一般会获取用户的token值,然后根据知己的业务逻辑通过token获取到用户的基本信息,然后封装成SimpleAuthenticationInfo对象并返回。
项目中举例
String accessToken = (String) token.getPrincipal(); //根据项目业务逻辑实现 LoginSuccessVo loginSuccessVo = RequestUtil.getLoginSuccessVo(accessToken); if(loginSuccessVo == null){ throw new IncorrectCredentialsException("token失效,请重新登录"); } SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(loginSuccessVo, accessToken, getName()); return info;
到了这儿,这个问题的答案基本也有个大概了。就是我们通过api调用接口,获取到了token,通过token获取到了用户的基本信息。
那么什么时候会去调用认证的方法呢?
- 就是博友问题所在SecurityUtils.getSubject()。获取Subject()方法时会去执行认证方法。
- 在方法上加@RequiresRoles注解的时候
- 方法认证拦截的时候,这也是登录接口没有执行认证的原因。
3,结语
开始看到这个问题的时候,我想到的只是认证。开始也在纠结为啥登录没有认证,后来代码调试才发现,尴尬。
这位博友也许是第一次接触shiro。同时也暴露了我自己没有理解到shiro的实现原理,工作中只为实现代码功能,没有深纠。下来补网 ̄□ ̄||