首先自定义一个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,毕竟是多个分割成单个去校验,还请大家多多指教。