<>();
if (authenticationToken instanceof SSOToken) {
// 单点登录方式选择SSORealm
for (Realm realm : realms) {
if (realm.getName().contains(LoginType.SSO.toString())) {
typeRealms.add(realm);
}
}
} else if (authenticationToken instanceof UsernamePasswordToken) {
//用户名密码方式登录,选择UserRealm
for (Realm realm : realms) {
if (realm.getName().contains(LoginType.USERNAME.toString())) {
typeRealms.add(realm);
}
}
}
if (typeRealms.size() == 1) {
return doSingleRealmAuthentication(typeRealms.iterator().next(), authenticationToken);
}
return doMultiRealmAuthentication(typeRealms, authenticationToken);
}
}
四、编写配置文件
完成上述工作后,多realm配置基本完成了,不过由于用到了BearToken,还需要对shiro的配置类进行一些改造
@Configuration
public class ShiroConfig {
@Autowired
private ModularRealmAuthenticator customModularRealmAuthenticator;
/**
* 自定义Realm
*/
@Bean
public UserRealm userRealm() {
UserRealm userRealm = new UserRealm();
return userRealm;
}
@Bean
public SSORealm ssoRealm() {
SSORealm userRealm = new SSORealm();
userRealm.setAuthenticationTokenClass(BearerToken.class);
return userRealm;
}
/**
* 安全管理器
*/
@Bean
public DefaultWebSecurityManager securityManager(Collection realms) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//设置多realm识别
securityManager.setAuthenticator(customModularRealmAuthenticator);
// 设置realm.
securityManager.setRealms(realms);
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// Shiro的核心安全接口,这个属性是必须的
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 身份认证失败,则跳转到登录页面的配置
shiroFilterFactoryBean.setLoginUrl("/login");
// 权限认证失败,则跳转到指定页面
shiroFilterFactoryBean.setUnauthorizedUrl("/unauth");
// Shiro连接约束配置,即过滤链的定义
LinkedHashMap filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/normal", "anon");
filterChainDefinitionMap.put("/sso", "anon");
filterChainDefinitionMap.put("/**", "authc");
Map filters = new LinkedHashMap();
shiroFilterFactoryBean.setFilters(filters);
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
}
五、总结
至此,单点登录的多realm实现基本完成了,由于项目原因,贴出的代码基本都是示例,读者可以按需进行修改,需要新增的就是realm、自定义身份验证器,还有就是需要对shiro config进行一些调整,全部的代码示例已经上传到github,如有需要可以自行下载。