6.Shiro授权_前提

1.前提:前边学多realm的时候,使用一个认证器 authenticator,同时该认证器会配置到securityManager的bean下,代码如下:
<bean id="securityManager"  class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="authenticator" ref="authenticator"/>
</bean>
<!-- 多realm认证器 -->
     <bean id="authenticator"  class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
           <property name="realms">
                <list>
                     <ref bean="jdbcRealm"/>
                     <ref bean="secondRealm"/>
                </list>
           </property>
           <!-- 修改认证策略 -->
           <property name="authenticationStrategy">
                <bean  class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy"/>
           </property>
     </bean>
 
但是我们在做授权的时候需要从securityManager中获取realms,所以这里我们需要修改一下realms属性的配置代码如下:
<bean id="securityManager"  class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <--authenticator需要配置在realms之前-->
    <property name="authenticator" ref="authenticator"/>
    <property name="realms">
        <list>
            <ref bean="jdbcRealm"/>
            <ref bean="secondRealm"/>
        </list>
    </property>
</bean>
<!-- 多realm认证器 -->
<bean id="authenticator"  class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
    <!-- 修改认证策略 -->
    <property name="authenticationStrategy">
        <bean  class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy"/>
    </property>
</bean>
 
 
这里有几个问题需要我们知道:
问题1:为什么要使用这种方式?
回答:因为授权时需要从securityManager中获取realms,所以一般使用此方式配置多realm
问题2:为什么这种方式使用没问题?
回答:参考问题3
问题3:实际调用是使用的是SecurityManager的realms,还是ModularRealmAuthenticator的realms?
回答: 在自定义realm中打断点,当程序停下时向上翻到DefaultWebSecurityManager是可以看到, 在SecurityManager认证时调用的是 ModularRealmAuthenticator 的authenticator()方法, 需要用到realms的时候,调realms的是ModularRealmAuthenticator 在IOC容器中注入时realms是配给SecurityManager的,而没有配给ModularRealmAuthenticator,但是为什么ModularRealmAuthenticator的realms会有值? 原因就在于在启动项目时,AuthenticatingSecurityManager的afterRealmsSet()方法 把SecurityManager的authenticator属性里面的值set到ModularRealmAuthenticator的realms里。
代码: ((ModularRealmAuthenticator)authenticator).setRealms(getRealms());
简单的理解就是SecurityManager获取到(ModularRealmAuthenticator)authenticator属性和(Collection)realms属性, 在SecurityManager的一个方法中(afterRealmsSet)再把realms放到 (ModularRealmAuthenticator) authenticator的realms里
 
问题4:为什么authenticator属性要配置在realms之前?
回答:因为这涉及是先 setAuthenticator()还是 setRealms()的问题,
正常应该先 setAuthenticator()setRealms(),这是因为 setAuthenticator()方法注入的是上面配置的 多realm认证器,在IOC容器中我们可以看到此时realms已经不在这里配置了,所以 ModularRealmAuthenticator的 realms属性为null,下面代码debug中也可以看到。
所以先配置 authenticator setAuthenticator()方法中realms属性为null
后配置 realmssetRealms()的中会把realms属性设置回来。
如果配置相反,则配置了realms属性之后, setAuthenticator() 方法中又把realms属性置为null
因此导致异常:
java.lang.IllegalStateException: Configuration error:  No realms have been configured!  One or more realms must be present to execute an authentication attempt.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SLF4J: No SLF4J providers were found. SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See https://www.slf4j.org/codes.html#noProviders for further details. Exception in thread "main" org.apache.shiro.config.ConfigurationException: Unable to instantiate class [org.apache.shiro.web.mgt.DefaultWebSecurityManager] for object named 'securityManager'. Please ensure you've specified the fully qualified class name correctly. at org.apache.shiro.config.ReflectionBuilder.createNewInstance(ReflectionBuilder.java:309) at org.apache.shiro.config.ReflectionBuilder$InstantiationStatement.doExecute(ReflectionBuilder.java:927) at org.apache.shiro.config.ReflectionBuilder$Statement.execute(ReflectionBuilder.java:887) at org.apache.shiro.config.ReflectionBuilder$BeanConfigurationProcessor.execute(ReflectionBuilder.java:765) at org.apache.shiro.config.ReflectionBuilder.buildObjects(ReflectionBuilder.java:260) at org.apache.shiro.config.IniSecurityManagerFactory.buildInstances(IniSecurityManagerFactory.java:167) at org.apache.shiro.config.IniSecurityManagerFactory.createSecurityManager(IniSecurityManagerFactory.java:130) at org.apache.shiro.config.IniSecurityManagerFactory.createSecurityManager(IniSecurityManagerFactory.java:108) at org.apache.shiro.config.IniSecurityManagerFactory.createInstance(IniSecurityManagerFactory.java:94) at org.apache.shiro.config.IniSecurityManagerFactory.createInstance(IniSecurityManagerFactory.java:46) at org.apache.shiro.config.IniFactorySupport.createInstance(IniFactorySupport.java:123) at org.apache.shiro.util.AbstractFactory.getInstance(AbstractFactory.java:47) at com.xiu.Quickstart.main(Quickstart.java:26) Caused by: org.apache.shiro.util.UnknownClassException: Unable to load class named [org.apache.shiro.web.mgt.DefaultWebSecurityManager] from the thread context, current, or system/application ClassLoaders. All heuristics have been exhausted. Class could not be found. at org.apache.shiro.util.ClassUtils.forName(ClassUtils.java:152) at org.apache.shiro.util.ClassUtils.newInstance(ClassUtils.java:168) at org.apache.shiro.config.ReflectionBuilder.createNewInstance(ReflectionBuilder.java:302) ... 12 more
06-10

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值