shiro安全认证源码解读(一)

对于学习一门新技术,不去学习技术的源码,很容易会忘记,说白了就相当于没学,在学会使用后,再去学习源码能够更好的帮助我们了解技术的使用过程,更好的扩展与使用。初次学习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。接下来,我们看看(下片文章继续介绍)

猜你喜欢

转载自blog.csdn.net/qq_34816825/article/details/80249453