Shiro的介绍
说到这里可以先提一下Shiro的介绍和主要架构脉络
—— 全面的蕴含丰富功能的安全框架
介绍:Shiro是一个安全框架,可以做Authentication、Authorization、Session Management、加密
支持WEB、提供了很多WEB的API,缓存、记住我—跨Session的会话保留机制,记住用户的身份
主要架构脉络
主要有主体、SecurityManager、realm,主体是代表当前用户,主体是个抽象的概念,主体会帮到SecurityManager上,与主体的所有交互都会委托给SecurityManager
主体Subject会将登录请求委托给SecurityManager,Subject是个门面,只有SecurityManager才是真正的执行者,见名知意,是个安全管理器,管理了所有的subject,是Shiro的核心,等同于SpringMVC的前端控制器,Realm是域的概念,Shiro从realm中获取安全数据,包括用户、角色、权限,可以把realm理解为DataSource
总而言之,最简单的一个Shiro应用应该是:
subject来进行授权和认证,而subject又委托给SecurityManager,我们需要给Shiro的SecurityManager注入Realm,从而让SecurityManager可以很好的得到用户及其权限进行判断
shiro的登录认证
- 请求打过来,创建一个
UserNamePasswordToken, 登录接口subject.login,里面有用户名和密码,以及是否记住我, Subject的登录将委托给SecurityManager,其利用内置的Authenticator实例,调用AuthenticateToken来进行认证,通常使用ModularRealmAuthenticator的实例,会对一个或多个realm进行适配,如果多个,将采用Authentication Strategy来进行多realm的认证处理- 判断
realm是否支持提到的token,如果支持,将调用getAuthenticationInfo(token),getAuthenticationInfo才是实际的认证处理,我们通过realm覆盖的doGetRealmAuthenticationInfo()方法,编写我们自己的认证处理即可
shiro的授权
- 首先调用
subject.isPermitted()或者subject.hasRole() Subject实例会委托给SecurityManager,而SecurityManager会委托给Authorizer
举个例子:比如我们想查看是否用user的查看权限,perms[user:query],subject.isPermitted()。首先我们会通过permissionResolver把字符串转化为对应的permission实例,进行授权之前,它会调用realm,获取subject对应的角色权限,用于匹配传入的角色权限,最后Authorizer会判断传入的是否和realm的角色权限相匹配,如果有多个realm,会在realm之间循环判断,匹配返回false或者true
权限拦截
Shiro使用了增强的拦截器链PathMatchingFilter,对Servlet容器的拦截器链进行了代理,即shiroFilter在Servlet拦截器链之前执行,通过代理ProxiedFilterChain对Servlet的拦截器链进行了代理,那样会先走Shiro的拦截器链,然后再委托个Servlet的拦截器链。
会话管理
权限缓存
shiro的URL鉴权
普通需求的鉴权
普通的Shiro是通过注解@RequRirePermission和@RequireRoles这两个注解来进行鉴权,但是这种方法的侵入性比较强,不利于维护和动态修改
为了解决这个问题,于是有了URL鉴权
-
自定义拦截器,继承
PathMatchingFilter,- 判断用户有没有登录,
- 从缓存中取出权限-
URL并比对当前isPermitted()或者和自己的set权限集合去比较
- 去权限,跳403
shrioFilterFactory中再注入Filters为自己的拦截器(key: requestURL,value: 自定义拦截器),在shiroFilterFactoryBean中再注入不会被拦截的链接,user,anno,authc, -
shiroFactoryBean.setFilterChainDefinationMap()中的
key,value自己拼接组装放进去即可例如:
/getAdmin perms[getadmin],/getAdmin roles[admin],前面的URL使用后面的拦截器进行处理,
RolesAuthorizationFilter、PermissionAuthorizationFilter
restful的鉴权
因为体现的是Method的不同,所以对请求进行一下处理再放到拦截器链中,方便后续处理
-
重写
PathMatchingFilterChainResolver,加强FilterChainResolver,获取过来的请求的
HTTP方法和URL和,将自己的匹配串pathPattern根据==拆开,然后比较URL和Method,以确定是否让请求通过 -
因为
PathMatchingFilterChainResolver是在ShiroFilterFactoryBean中的createInstance中初始化的,所以同样的套路,继承这个类,记得在shiroConfig中配置它
控制按钮的显示与否,
就是前端事先请求有没有这个权限,然后请求后端