shiro多realm配置(可区分不同类型用户)

由于项目中需要用到shiro,但是用户来自不同的三张表,需要根据token判断不同类型的用户,但是shiro得token不支持带类型的参数,所以需要重写token及认证器

1.自定义token

/**
 * 自定义带用户类型token
 * @author Sunny
 */
public class UsernamePasswordByUserTypeToken extends UsernamePasswordToken {
	private static final long serialVersionUID = -7638434498222500528L;

	/*
	 * 用户类型
	 * 1:积分后台用户(后台管理员)
	 * 2:积分兑换端用户(店长店员)
	 * 3:积分验证端用户(第三方合作店铺)
	 */
	private String userType;

	public String getUserType() {
		return userType;
	}

	public void setUserType(String userType) {
		this.userType = userType;
	}

	public UsernamePasswordByUserTypeToken(String username, String password, String userType) {
		super(username, password);
		this.userType = userType;
	}
}

2.自定义认证器

/**
 * 自定义认证器
 * 
 * @author Sunny
 */
public class PointRealmAuthenticator extends ModularRealmAuthenticator {
	/**
	 * 存放realm
	 */
	private Map<String, Object> definedRealms;

	public void setDefinedRealms(Map<String, Object> definedRealms) {
		this.definedRealms = definedRealms;
	}

	/**
	 * 根据用户类型判断使用哪个Realm
	 */
	@Override
	protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken)
			throws AuthenticationException {
		super.assertRealmsConfigured();
		Realm realm = null;
		// 使用自定义Token
		UsernamePasswordByUserTypeToken token = (UsernamePasswordByUserTypeToken) authenticationToken;
		// 判断用户类型
		if ("1".equals(token.getUserType())) {
			realm = (Realm) this.definedRealms.get("pointSysShiroDbRealm");
		} else if ("2".equals(token.getUserType())) {
			realm = (Realm) this.definedRealms.get("pointExchangeShiroDbRealm");
		} else if ("3".equals(token.getUserType())) {
			realm = (Realm) this.definedRealms.get("pointValidShiroDbRealm");
		}
		return this.doSingleRealmAuthentication(realm, authenticationToken);
	}
}

3.配置shiro xml文件

<!-- 配置 Shiro 的 SecurityManager 实例 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
	<property name="authenticator" ref="pointRealmAuthenticator" />
	<!-- 单Realm配置废弃 -->
	<!-- <property name="realm" ref="shiroDbRealm" /> -->
	<!-- 多Realm注入 -->
	<property name="realms">
		<list>
			<ref bean="pointSysShiroDbRealm" />
			<ref bean="pointExchangeShiroDbRealm" />
			<ref bean="pointValidShiroDbRealm" />
		</list>
	</property>
	<property name="cacheManager" ref="shiroEhcacheManager" />
</bean>

<!-- 项目自定义Authenticator -->
<bean id="pointRealmAuthenticator"
	class="org.zmshop.common.shiro.authenticator.PointRealmAuthenticator">
	<!-- realmMap -->
	<property name="definedRealms">
		<map>
			<entry key="pointSysShiroDbRealm" value-ref="pointSysShiroDbRealm" />
			<entry key="pointExchangeShiroDbRealm" value-ref="pointExchangeShiroDbRealm" />
			<entry key="pointValidShiroDbRealm" value-ref="pointValidShiroDbRealm" />
		</map>
	</property>
</bean>

<!-- 项目自定义的Realm -->
<!-- 积分后台用户(后台管理员)Realm -->
<bean id="pointSysShiroDbRealm" class="org.zmshop.common.shiro.realm.PointSysShiroDbRealm">
	<property name="maUserService" ref="maUserServiceImpl" />
	<property name="baUserGradeService" ref="baUserGradeServiceImpl" />
</bean>
<!-- 积分兑换端用户(店长店员)Realm -->
<bean id="pointExchangeShiroDbRealm" class="org.zmshop.common.shiro.realm.PointExchangeShiroDbRealm">
	<property name="baUserService" ref="baUserServiceImpl" />
	<property name="baUserSubService" ref="baUserSubServiceImpl" />
	<property name="stClerkService" ref="stClerkServiceImpl" />
	<property name="baUserGradeService" ref="baUserGradeServiceImpl" />
	<property name="stMainService" ref="stMainServiceImpl" />
</bean>
<!-- 积分验证端用户(第三方合作店铺)Realm -->
<bean id="pointValidShiroDbRealm" class="org.zmshop.common.shiro.realm.PointValidShiroDbRealm">
	<property name="ebtPointEmployeeService" ref="ebtPointEmployeeServiceImpl" />
	<property name="baUserGradeService" ref="baUserGradeServiceImpl" />
</bean>

4.Realm文件需注意事项
public class PointExchangeShiroDbRealm extends AuthorizingRealm {
	/**
	 * 身份验证回调函数,登录时调用
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
			throws AuthenticationException {
		//具体登录判断逻辑
		return xxx;
	}

	/**
	 * 授权查询回调函数,进行鉴权但缓存中无用户的授权信息时调用
	 * 多realm该方法会在多个realm之间调用,所以需要判断当前用户是否是当前类中的shirouser对象[其他realm一样]
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		// 判断是否是当前用户登录的对象
		if (principals == null || !(principals.getPrimaryPrincipal() instanceof ShiroUser)) {
			return null;
		}
		return xxx;
	}

	/**
	 * 自定义Authentication对象,使得Subject除了携带用户的登录名外还可以携带更多信息.
	 */
	public class ShiroUser implements Serializable {
		private static final long serialVersionUID = 7240137316895366700L;
	}
}

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值