Shiro多个Realm认证及授权

解决方案如下:

 首先自定义一个DefaultUsernamepasswordToken.java,继承Shiro自带的UsernamePasswordToken,在DefaultUsernamepasswordToken中新加一个属性 

private String loginType;  而后生成getter setter;

public class DefaultUsernamepasswordToken extends UsernamePasswordToken {

	/**
	 * 判断登录类型
	 */
	private String loginType;

	public String getLoginType() {
		return this.loginType;
	}

	public void setLoginType(String loginType) {
		this.loginType = loginType;
	}

	/**
	 * Shiro 构造方法
	 * 
	 * @author : tanzhen
	 * @date :2016年7月28日
	 */
	public DefaultUsernamepasswordToken(String username, String password) {
		super(username, password);
	}

	public DefaultUsernamepasswordToken() {

	}
}


然后自定义一个DefautModularRealm.java,继承 ModularRealmAuthenticator,重写doMultiRealmAuthentication、doSingleRealmAuthentication、doAuthenticate、assertRealmsConfigured四个方法,还需要定义一个变量,

用来接收传进来的多个Realm。

      

public class DefaultModularRealm extends ModularRealmAuthenticator {
	private Map<String, Object> definedRealms;

	/**
	 * 多个realm实现
	 */
	@Override
	protected AuthenticationInfo doMultiRealmAuthentication(
			Collection<Realm> realms, AuthenticationToken token) {
		return super.doMultiRealmAuthentication(realms, token);
	}

	/**
	 * 调用单个realm执行操作
	 */
	@Override
	protected AuthenticationInfo doSingleRealmAuthentication(Realm realm,
			AuthenticationToken token) {

		// 如果该realms不支持(不能验证)当前token
		if (!realm.supports(token)) {
			throw new ShiroException("token错误!");
		}
		AuthenticationInfo info = null;
		try {
			info = realm.getAuthenticationInfo(token);

			if (info == null) {
				throw new ShiroException("token不存在!");
			}
		} catch (Exception e) {
			throw new ShiroException("用户名或者密码错误!");
		}
		return info;
	}

	/**
	 * 判断登录类型执行操作
	 */
	@Override
	protected AuthenticationInfo doAuthenticate(
			AuthenticationToken authenticationToken)
			throws AuthenticationException {
		this.assertRealmsConfigured();

		Realm realm = null;

		DefaultUsernamepasswordToken token = (DefaultUsernamepasswordToken) authenticationToken;
		if (token.getLoginType().equals("huimai")) {
			realm = (Realm) this.definedRealms.get("defaultJdbcRealm");
		}
		if (token.getLoginType().equals("shiro")) {
			realm = (Realm) this.definedRealms.get("shiroDbRealm");
		}
		if (realm == null) {
			return null;
		}

		return this.doSingleRealmAuthentication(realm, authenticationToken);
	}

	/**
	 * 判断realm是否为空
	 */
	@Override
	protected void assertRealmsConfigured() throws IllegalStateException {
		this.definedRealms = this.getDefinedRealms();
		if (CollectionUtils.isEmpty(this.definedRealms)) {
			throw new ShiroException("值传递错误!");
		}
	}

	public Map<String, Object> getDefinedRealms() {
		return this.definedRealms;
	}

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


   这里需要注意是 其实 流程是:在给DefaultUsernamepasswordToken赋值时,将loginType设置成相应的参数,然后在doAuthenticate时判断,单个调用对应的Realm。然后是xml文件配置:

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
        <!-- 其他配置 -->  
      <property name="authenticator" ref="defineModularRealmAuthenticator" />
      <property name="realms">  
            <list>  
                <ref bean="defaultJdbcRealm" />  
                <ref bean="shiroDbRealm" />  
            </list>  
        </property>
    </bean>  

    <!--  -->
    <bean id="defineModularRealmAuthenticator"  
        class="com.zynsun.platform.realm.DefaultModularRealm">  
        <property name="definedRealms">  
            <map>  
                <entry key="defaultJdbcRealm" value-ref="defaultJdbcRealm" />  
                <entry key="shiroDbRealm" value-ref="shiroDbRealm" />  
            </map>  
        </property>  
        <!-- <property name="authenticationStrategy">  
            <bean class="org.apache.shiro.authc.pam.FirstSuccessfulStrategy" />  
        </property> -->
    </bean> 
    <!--  -->

    <bean id="defaultJdbcRealm" class="com.xxxx.shiro.DefaultRealm">
    </bean>  

    <bean id="shiroDbRealm" class="com.xxx.shiro.ShiroRealm">
           <property name="credentialsMatcher" ref="credentialsMatcher"></property>
    </bean>


利用SecurityManager来进行配置。这样就完成了多个Realm认证,其实这种也只能算是单个Realm,毕竟是多个分割成单个去校验,还请大家多多指教。


发布了9 篇原创文章 · 获赞 11 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/TanZhen_1314/article/details/52121347