对于学习一门新技术,不去学习技术的源码,很容易会忘记,说白了就相当于没学,在学会使用后,再去学习源码能够更好的帮助我们了解技术的使用过程,更好的扩展与使用。初次学习shiro框架,总结一下
一,shiro认识
Apache Shiro™是一个强大且易用的Java安全框架,执行身份验证、授权、密码学和会话管理。
(对于某些环节不清楚的请自行学习)
shiro实现的功能包含:
(1)用户身份验证登录:通过将web传递的信息存储在一个特有的UsernamePasswordToken对象中,然后通过subject.login(token);方法后从数据库中查找数据,并开始验证,当然,验证过程(数据查询)交给Realm去解决。
(2)用户角色权限管理:验证某个已认证的用户是否拥有某个角色。subject.hasRole()方法判断是否含有某个角色,subject.checkPermission()判断用户拥有什么角色。
(3)加密方式: MD5,SHA1等加密算法
(4)web支持,支持与spring整合实现用户管理
(5)会话的支持,shiro支持原生的session管理,可以将其存储到redis方便使用
(6)缓存管理:一次登陆后,授权信息将在缓存中获取
二,shiro与spring整合(主页介绍大概运行流程)
1.shiro与spring整合时需要引入核心过滤
<filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
2.查看过滤器DelegatingFilterProxy类中的doFilter,通过获取spring容器,然后会初始化认证信息(delegate就是spring容器中定义的ShiroFilterFactoryBean过滤器)
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException { // Lazily initialize the delegate if necessary. Filter delegateToUse = this.delegate; if (delegateToUse == null) { //1.判断当前是否存在过滤器 synchronized (this.delegateMonitor) { if (this.delegate == null) { //2.获取application容器,用于执行bean容器中的ShiroFilterFactoryBean(这就是为什么可以在bean中配置过滤) WebApplicationContext wac = findWebApplicationContext(); if (wac == null) { throw new IllegalStateException("No WebApplicationContext found: " + "no ContextLoaderListener or DispatcherServlet registered?"); } this.delegate = initDelegate(wac); //3.初始化过滤器 } delegateToUse = this.delegate; } } // Let the delegate perform the actual doFilter operation. invokeDelegate(delegateToUse, request, response, filterChain); //4.实际上就是调用delegate.doFilter }
1.invokeDelegate方法
protected void invokeDelegate(
Filter delegate, ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
delegate.doFilter(request, response, filterChain); //5.上述第4步代码的最后
}
2.initDelegate (web中的filter-name 与 bean容器需要一样 initFilterBean()初始化时定义了getFilterName()可以自行查看)
protected Filter initDelegate(WebApplicationContext wac) throws ServletException { Filter delegate = wac.getBean(getTargetBeanName(), Filter.class); if (isTargetFilterLifecycle()) { delegate.init(getFilterConfig()); } return delegate; }
getTargetBeanName()方法的作用是返回bean容器中定义的名称,也就是之前web.xml中filter中的name值,获取名称为shiroFilter的类(filter中自己定义的name),也就是在spring中配置的ShiroFilterFactoryBean的id,这个由名称就可以知道,这个类为一个过滤器,交给这个过滤器去完成过滤,这就好像是web.xml中配置的DelegatingFilterProxy方法最终交给ShiroFilterFactoryBean实现,完成代理。个人猜测是为了方便Spring容器的配置,上边的delegate就是下面这个过滤器
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"></property> <property name="loginUrl" value="login.html"></property> <property name="unauthorizedUrl" value="403.html"></property> <property name="filterChainDefinitions" > <value> /login.html=anon /subLogin=anon /*=authc </value> </property> </bean>绕了一圈,还要看spring中的ShiroFilterFactoryBean。接下来,我们看看(下片文章继续介绍)