shiro的doGetAuthorizationInfo授权方法始终进不去

本文讲述了作者在学习Java Shiro框架时遇到的问题,即doGetAuthorizationInfo授权方法未被调用。通过分析,发现授权不是主动调用,而是需要在检查权限时触发。在尝试各种解决方案并查看源码后,作者发现授权的ModularRealmAuthorizer类没有配置realm导致报错。最终,通过将realm注入ModularRealmAuthorizer解决了问题,强调了解决问题时独立思考的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

感慨:大二刚开始学java,只顾埋头照着敲,什么语法什么意思通通不知道,敲完运行看看效果正确就洋洋得意一番。后来慢慢懂了基本语法,基本意思,想实现什么功能就百度一下,面向对象编程成了面向百度编程。开始了抄,第一阶段直接抄,代码实现错误就是辣鸡答案。第二阶段,看看代码的基本如何实现,对它进行一些更改达到自己的预期效果。第三阶段,抄它的思想,从它的思想中获得灵感。到了这个阶段,觉得自己好像什么都会,又好像什么都不会。万一没得抄呢?道友们,开始看源码吧,也不是自己从头到尾看源码,这要弄点东西还不得头发都白了。百度百度博客,看看人家写的它的基本运行过程,看看你卡在哪一步,然后去看看源码哪里错了,再去思考为什么,最后去解决问题。

public class BaseLoginRealm extends AuthorizingRealm {

@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		System.out.println("进入用户登录");
		// 获取用户名
		String userName = (String) token.getPrincipal();
		// 通过用户名获取用户对象
		PersonInfo personInfo = personInfoService.findById(userName);

		if (personInfo == null) {
			return null;
		}

		SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userName, personInfo.getPassword(), this.getName());

		return info;
	}


@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		System.out.println("进入角色授权");
		String userName = (String) getAvailablePrincipal(principals);
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		PersonInfo personInfo = personInfoService.findById(userName);
		if (personInfo.getRoles().size() > 0) {
			Set<String> roleIds=new HashSet<String>();
			for (Role role : personInfo.getRoles()) {
				roleIds.add(role.getRoleId());
				if(role.getAuthoritys().size()>0) {
					Set<String> handleMappings=new HashSet<String>();
					for(Authority authority:role.getAuthoritys()) 
						handleMappings.add(authority.getHandleMapping());
					info.setStringPermissions(handleMappings);
				}
			}
			info.setRoles(roleIds);
		}
		return info;
	}

}

doGetAuthenticationInfo在你认证身份的时候就会进去,doGetAuthorizationInfo授权却始终不进去。

首先,doGetAuthorizationInfo授权不是主动调用的,你得去校验是否有权限时才会去授权。

代码方式使用Subject对象的isPermitted等类似方法去调用,还可以使用注解,具体百度。但我的它会报错:

java.lang.IllegalStateException: Configuration error:  No realms have been configured!  One or more realms must be present to execute an authorization operation.
    at org.apache.shiro.authz.ModularRealmAuthorizer.assertRealmsConfigured(ModularRealmAuthorizer.java:210)
    at org.apache.shiro.authz.ModularRealmAuthorizer.isPermitted(ModularRealmAuthorizer.java:220)
    at org.apache.shiro.mgt.AuthorizingSecurityManager.isPermitted(AuthorizingSecurityManager.java:113)
    at org.apache.shiro.subject.support.DelegatingSubject.isPermitted(DelegatingSubject.java:162)
    at com.tczs.util.MyIntercpetor.preHandle(MyIntercpetor.java:35)

查看源码

/**
     * Used by the {@link Authorizer Authorizer} implementation methods to ensure that the {@link #setRealms realms}
     * has been set.  The default implementation ensures the property is not null and not empty.
     *
     * @throws IllegalStateException if the <tt>realms</tt> property is configured incorrectly.
     */
    protected void assertRealmsConfigured() throws IllegalStateException {
        Collection<Realm> realms = getRealms();
        if (realms == null || realms.isEmpty()) {
            String msg = "Configuration error:  No realms have been configured!  One or more realms must be " +
                    "present to execute an authorization operation.";
            throw new IllegalStateException(msg);
        }
    }

realms为null,但我看别人的不都是这样配置realms的吗

<!-- 配置多个Realm -->
    <bean id="authenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
        <property name="realms">
            <list>
            	<ref bean="employeeLoginRealm"/>
                <ref bean="baseLoginRealm"/>
            </list>
        </property>
    </bean>
    <!-- 配置 Shiro 的 SecurityManager Bean. -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
         <property name="authenticator" ref="authenticator"/>
    </bean>

对,是别人的,我也不知道他为什么不报错,我的问题还是要解决的,百度一番,都不可行,还是看源码吧,首先我把自己两个realm都注入到DefaultWebSecurityManager这个类里了,为什么它报null呢,查看DefaultWebSecurityManager类源码,发现他的方法都是和认证有关的,也就是doGetAuthenticationInfo能进去,因为我把我的realm注入到这个类了。现在想来,当时我已经发现这个问题了,但我为什么还花了这么多时间去解决,原因还是太过依赖别人,总想着别人都这样配置的,反而忘了问题的原因。我们认证注入了realm,授权应该也有个类要注入realm,就是我们报错的提示类ModularRealmAuthorizer。

查看源码

public class ModularRealmAuthorizer implements Authorizer, PermissionResolverAware, RolePermissionResolverAware {

    /**
     * The realms to consult during any authorization check.
     */
    protected Collection<Realm> realms;

    /**
     * A PermissionResolver to be used by <em>all</em> configured realms.  Leave <code>null</code> if you wish
     * to configure different resolvers for different realms.
     */
    protected PermissionResolver permissionResolver;

    /**
     * A RolePermissionResolver to be used by <em>all</em> configured realms.  Leave <code>null</code> if you wish
     * to configure different resolvers for different realms.
     */
    protected RolePermissionResolver rolePermissionResolver;

果然有realms这个属性,我们再和开始注入认证类时一样注入就行了

 <!-- 配置多个Realm -->
    <bean id="authenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
        <property name="realms">
            <list>
            	<ref bean="employeeLoginRealm"/>
                <ref bean="baseLoginRealm"/>
            </list>
        </property>
    </bean>
    <!-- 配置多个Realm -->
    <bean id="authorizer" class="org.apache.shiro.authz.ModularRealmAuthorizer">
        <property name="realms">
            <list>
            	<ref bean="employeeLoginRealm"/>
                <ref bean="baseLoginRealm"/>
            </list>
        </property>
    </bean>
    <!-- 配置 Shiro 的 SecurityManager Bean. -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
         <property name="authenticator" ref="authenticator"/>
         <property name="authorizer" ref="authorizer"/>
    </bean>

我的问题已经解决

进入用户登录
Hibernate: select personinfo0_.personId as personId1_10_0_, personinfo0_.createTime as createTi2_10_0_, personinfo0_.employeeId as employee3_10_0_, personinfo0_.password as password4_10_0_, personinfo0_.version as version5_10_0_ from PersonInfo personinfo0_ where personinfo0_.personId=?
进入角色授权
Hibernate: select personinfo0_.personId as personId1_10_0_, personinfo0_.createTime as createTi2_10_0_, personinfo0_.employeeId as employee3_10_0_, personinfo0_.password as password4_10_0_, personinfo0_.version as version5_10_0_ from PersonInfo personinfo0_ where personinfo0_.personId=?
Hibernate: select roles0_.personId as personId2_11_0_, roles0_.roleId as roleId1_11_0_, role1_.roleId as roleId1_15_1_, role1_.createTime as createTi2_15_1_, role1_.remark as remark3_15_1_, role1_.roleName as roleName4_15_1_, role1_.version as version5_15_1_ from PersonMapperRole roles0_ inner join Role role1_ on roles0_.roleId=role1_.roleId where roles0_.personId=?
Hibernate: select authoritys0_.roleId as roleId4_16_0_, authoritys0_.authorityId as authorit2_16_0_, authority1_.authorityId as authorit1_0_1_, authority1_.authorityName as authorit2_0_1_, authority1_.createTime as createTi3_0_1_, authority1_.handleMapping as handleMa4_0_1_, authority1_.iconCls as iconCls5_0_1_, authority1_.iconName as iconName6_0_1_, authority1_.menuId as menuId7_0_1_, authority1_.menuName as menuName8_0_1_, authority1_.version as version9_0_1_ from RoleMapperAuthority authoritys0_ inner join Authority authority1_ on authoritys0_.authorityId=authority1_.authorityId where authoritys0_.roleId=?

 个人网站

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

3wtczs93点抗母

钱癌晚期

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值