Java学习笔记——Shiro框架

shiro的url配置采用第一次匹配优先的原则,则从上往下匹配

DelegatingFilterProxy类存在与spring-web包中,其作用就是一个filter的代理,用这个类的好处是可以通过spring容器来管理filter的生命周期,还有就是,可以通过spring注入的形式,来代理一个filter执行,如shiro。

	<!-- 
		配置shiro的 shiro Filter
		1.DelegatingFilterProxy类是Spring的一个filter的代理对象
	 -->
	<filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
            <param-name>targetFilterLifecycle</param-name>
            <param-value>true</param-value>
        </init-param>
<!--         可以用targetBeanName初始化参数来指定filter名 -->
        <init-param>
            <param-name>targetBeanName</param-name>
            <param-value>shiroFilter1</param-value>
        </init-param>
    </filter>

初始化时,自动调用init方法。

Shiro认证思路。

//Handler类
@Controller
@RequestMapping("/shiro")
public class ShiroHandle {
	
	@RequestMapping("/login")
	public String login(@RequestParam("username")String username,@RequestParam("password")String password){
		Subject currentUser = SecurityUtils.getSubject();
		
        
	       if (!currentUser.isAuthenticated()) {
	            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
	            System.out.println(token.hashCode());
	            token.setRememberMe(true);
	            try {
	                currentUser.login(token);
	            } 
	            catch (AuthenticationException ae) {
	            	ae.printStackTrace();
	            }
	        }
		return "";
	}
}
//shiroRealm类
public class ShiroRealm extends AuthenticatingRealm {

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		System.out.println("doAuthentication"+token.hashCode());
		return null;
	}

}

Handler类中执行的login方法传入的token值会被传到shiroRealm类里面。两个token实为同一个对象。

Shiro密码的比对是由 AuthenticatingRealm 类的assertCredentialsMatch方法使用CredentialsMatcher来进行比对的。

    <!-- 
        配置realm
    	实现Realm接口
     -->
    <bean id="jdbcRealm" class="com.jun.shiro.ShiroRealm">
    <!--
    	因为shiro是使用AuthenticatingRealm的credentialsMatcher属性来进行密码比对,
    	而此Realm是继承了AuthenticatingRealm,所以把credentialsMatcher属性注入到bean里面,
    	这里使用其实现类HashedCredentialsMatcher,并指定加密算法为MD5,加密次数为1024次
    -->
    	<property name="credentialsMatcher">
    		<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
    			<!-- 指定加密算法 -->
    			<property name="hashAlgorithmName" value="MD5"></property>
    			<!-- 指定加密次数 -->
    			<property name="hashIterations" value="1024"></property>
    		</bean>
    	</property>
    </bean>

shiro默认的认证策略是AllLeastOneSuccessfulStrategy。

若需要实现多realm认证的话,需要在spring中注册ModularRealmAuthenticator类,并且作为参数赋给securityManager。

    <!-- 
			配置securityManager
     -->
    <bean id="securityManager"         
          class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="cacheManager" ref="cacheManager"/>
<!--         <property name="realm" ref="jdbcRealm"/> -->
	<property name="authenticator" ref="authenticator"></property>
    </bean>	

<!-- 多realm认证器 -->
	<bean class="org.apache.shiro.authc.pam.ModularRealmAuthenticator" 
          id="authenticator">
		<property name="realms">
			<list>
				<ref bean="jdbcRealm"/>
				<ref bean="secondRealm"/>
			</list>
		</property>
		<!-- 配置多Realm认证策略 -->
		<property name="authenticationStrategy">
			<bean class="org.apache.shiro.authc.pam.AllSuccessfulStrategy"></bean>
		</property>
	</bean>

但在实际生产中,我们是从securityManager读取realm的,所以把realms从securityManager注入。那为什么可以这样做呢?是因为在securityManager初始化的时候,会判断authenticator属性对象是否属于ModularRealmAuthenticator类,如果是,会将自身realms属性赋予authenticator属性对象。

    <!-- 
			配置    securityManager
     -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="cacheManager" ref="cacheManager"/>
<!--         <property name="realm" ref="jdbcRealm"/> -->
		<property name="authenticator" ref="authenticator"></property>
		
		<property name="realms">
			<list>
				<ref bean="jdbcRealm"/>
				<ref bean="secondRealm"/>
			</list>
		</property>
    </bean>

	<!-- 多realm认证器 -->
	<bean class="org.apache.shiro.authc.pam.ModularRealmAuthenticator" id="authenticator">
		<!-- 配置多Realm认证策略 -->
		<property name="authenticationStrategy">
			<bean class="org.apache.shiro.authc.pam.AllSuccessfulStrategy"></bean>
		</property>
	</bean>

AuthenticatingRealm-------->若只需要认证的话,只继承AuthenticatingRealm就可

AuthorizingRealm--------->用于授权和认证的realm一般使用这个

AuthorizingRealm继承于AuthenticatingRealm但是没有实现父类的doGetAuthenticationInfo方法

若为多realm授权认证的话,shiro会调用ModularRealmAuthorizer类来进行认证(从源码中可以看到,只要有一个Realm通过就返回true),但是实际进行授权认证的还是AuthorizingRealm,因为在源码374行中调用的hasRole方法会继续调用AuthorizingRealm授权认证。

 sessionDAO

     

 sessionDao可以讲session进行序列号并存到数据库中,进行增删改查。在单机应用中,作用可以是在service层也可以通过shiro拿到session。而在集群分布式中作用就会比较大,共享session很有必要,因为当同一个用户发起请求时,可能被调度到不同的机器上访问(负载均衡),这时就可能同一个用户的求情会被当成是多个用户的请求,session共享就很有必要了。

の 面试题

  1. shiro的优点

  • 与Spring Security相比,Spring Security需要依赖与Spring环境,而shiro组件化,简单易用,不用依赖其他框架。
  • 简单的身份认证(登录),支持多种数据源(LDAP,JDBC,Kerberos,ActiveDirectory 等)
  • 内置的基于 POJO 企业会话管理,适用于 Web 以及非 Web 的环境
  • 对角色的简单的签权(访问控制),支持细粒度的签权
  • 支持一级缓存,以提升应用程序的性能

     2.为什么shiro的注解一般都加在control层,而不是在service层。

       因为一般在项目中我们会在service层会加上@Transactional 事务注解,这个时候service层对象已经是个代理对象了,在加上shiro权限注解的话,代理的代理,会在注入的时候发生异常。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值