1.实现多realm分开验证 授权
(1)继承 token 添加一个识别用户类型的标识符
(2) 继承 ModularRealmAuthenticato
重写 doAuthenticate 判断用户类型 来确认使用哪个Realm
(3)继承ModularRealmAuthorizer
重写
isPermitted(PrincipalCollection principals,String permission)
isPermitted(PrincipalCollection principals,Permission permission)
hasRole(PrincipalCollection principals,String roleIdentifier)
(4)配置
①继承UsernamePasswordToken 实现其方法 添加用户标识符属性
public class UserToken extends UsernamePasswordToken implements Serializable {
private String loginType;
public UserToken(String user, String password, String loginType){
super(user,password);
this.loginType=loginType;
}
public String getLoginType() {
return loginType;
}
public void setLoginType(String loginType) {
this.loginType = loginType;
}
}
②继承 ModularRealmAuthenticator 重写doAuthenticate 判断用户类型 来确认使用哪个Realm
public class CarWashModularRealmAuthenticator extends ModularRealmAuthenticator {
@Override
protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken)
throws AuthenticationException {
assertRealmsConfigured();
// 强制转换回自定义的UserToken
UserToken userToken = (UserToken) authenticationToken;
// 登录类型
String loginType = userToken.getLoginType();
// 所有Realm
Collection<Realm> realms = getRealms();
// 登录类型对应的所有Realm
Collection<Realm> typeRealms = new ArrayList<>();
for (Realm realm : realms) {
//判断是否为loginType类型的Realm
if (realm.getName().contains(loginType))
typeRealms.add(realm);
}
// 判断是单Realm还是多Realm
if (typeRealms.size() == 1) {
return doSingleRealmAuthentication(((ArrayList<Realm>) typeRealms).get(0), userToken);
} else {
return doMultiRealmAuthentication(typeRealms, userToken);
}
}
}
③重写授权
public class CarWashModularRealmAuthorizer extends ModularRealmAuthorizer {
@Override
public boolean isPermitted(PrincipalCollection principals, String permission) {
assertRealmsConfigured();
Set<String> realmNames = principals.getRealmNames();
//获取realm的名字
String realmName = realmNames.iterator().next();
log.info("realmName is",realmName);
for (Realm realm : getRealms()) {
if (!(realm instanceof Authorizer)) continue;
//匹配名字
if(realmName.equals(LoginType.ADMIN.toString())) {
if (realm instanceof AdminRealm) {
return ((AdminRealm) realm).isPermitted(principals, permission);
}
}
if(realmName.equals(LoginType.USER.toString())) {
if (realm instanceof WxAuthcRealm) {
return ((WxAuthcRealm) realm).isPermitted(principals, permission);
}
}
}
return false;
}
@Override
public boolean isPermitted(PrincipalCollection principals, Permission permission) {
assertRealmsConfigured();
Set<String> realmNames = principals.getRealmNames();
//获取realm的名字
String realmName = realmNames.iterator().next();
log.info("realmName is",realmName);
for (Realm realm : getRealms()) {
if (!(realm instanceof Authorizer)) continue;
//匹配名字
if(realmName.equals(LoginType.ADMIN.toString())) {
if (realm instanceof AdminRealm) {
return ((AdminRealm) realm).isPermitted(principals, permission);
}
}
if(realmName.equals(LoginType.USER.toString())) {
if (realm instanceof WxAuthcRealm) {
return ((WxAuthcRealm) realm).isPermitted(principals, permission);
}
}
}
return false; }
@Override
public boolean hasRole(PrincipalCollection principals, String roleIdentifier) {
assertRealmsConfigured();
Set<String> realmNames = principals.getRealmNames();
//获取realm的名字
String realmName = realmNames.iterator().next();
log.info("realmName is",realmName);
for (Realm realm : getRealms()) {
if (!(realm instanceof Authorizer)) continue;
//匹配名字
if(realmName.equals(LoginType.ADMIN.toString())) {
if (realm instanceof AdminRealm) {
return ((AdminRealm) realm).isPermitted(principals, roleIdentifier);
}
}
if(realmName.equals(LoginType.USER.toString())) {
if (realm instanceof WxAuthcRealm) {
return ((WxAuthcRealm) realm).isPermitted(principals, roleIdentifier);
}
}
}
return false;
}
}
④配置
@Bean
public ModularRealmAuthenticator modularRealmAuthenticator(){
CarWashModularRealmAuthenticator modularRealmAuthenticator=
new CarWashModularRealmAuthenticator();
modularRealmAuthenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
return modularRealmAuthenticator;
}
@Bean
public AdminRealm getcustomRealm() {
AdminRealm customRealm = new AdminRealm();
customRealm.setCredentialsMatcher(credentialsMatcher());
return customRealm;
}
@Bean
public WxAuthcRealm wxAuthcRealm(){
WxAuthcRealm wxAuthcRealm=new WxAuthcRealm();
return wxAuthcRealm;
}
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setSessionManager(sessionManager());
securityManager.setAuthenticator( modularRealmAuthenticator());
List<Realm> list=new ArrayList<>();
list.add(getcustomRealm());
list.add(wxAuthcRealm());
securityManager.setRealms(list);
CarWashModularRealmAuthorizer authorizer = new CarWashModularRealmAuthorizer();
authorizer.setRealms(list);
securityManager.setAuthorizer(authorizer);
return securityManager;
}
realm
public class AdminRealm extends AuthorizingRealm {
@Autowired
private AuthcService authcService;
/**
* 角色 权限 获取
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
AccountDto accountDto = (AccountDto) principalCollection.getPrimaryPrincipal();
Role roleSet = authcService.findAllRole(accountDto.getAccountId());
List<String> roles = new ArrayList<>();
List<String> permissions = new ArrayList<>();
if (roleSet!=null) {
roles.add(roleSet.getRoleName());
List<Permission> permission =authcService.findAllPermission(roleSet.getRoleId());
accountDto.setPermission(RoleToRightTree.createRightTree(permission));
for (Permission permission1:permission){
permissions.add(permission1.getPermissionName());
}
}
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
simpleAuthorizationInfo.addRoles(roles);
simpleAuthorizationInfo.addStringPermissions(permissions);
return simpleAuthorizationInfo;
}
/**
* 用户认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//1.从主体传过来的认证信息中,获取用户名
String username = (String) authenticationToken.getPrincipal();
//2.通过用户名到数据库获取凭证
Account account = authcService.findAccountByUsername(username);
if (account == null)
return null;
AccountDto accountDto=new AccountDto();
BeanUtils.copyProperties(account,accountDto);
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(accountDto, account.getPassword(), LoginType.ADMIN.toString());
authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(Constant.SALT));
return authenticationInfo;
}
}
使用
@Override
public Boolean login(String username, String password) {
Subject subject = SecurityUtils.getSubject();
try {
UserToken usernamePasswordToken =
new UserToken(username, password, LoginType.ADMIN.toString());
log.info("username is {} password is {}", username, password);
subject.login(usernamePasswordToken);
// RemoveOtherLoginedUser.removeOtherLoginUser(subject);
} catch (Exception e) {
return false;
}
subject.checkPermission("main");
return true; }
2.单用户登录 删除注释
RemoveOtherLoginedUser.removeOtherLoginUser(subject);
public class RemoveOtherLoginedUser {
public static void removeOtherLoginUser(Subject currentUser) {
SessionsSecurityManager securityManager =
(SessionsSecurityManager) SecurityUtils.getSecurityManager();
StatelessSessionManager sessionManager =
(StatelessSessionManager) securityManager.getSessionManager();
Collection<Session> sessions =
sessionManager.getSessionDAO().getActiveSessions();//获取当前已登录的用户session列表 AccountDto loginUser = (AccountDto) currentUser.getPrincipal();
for (Session session : sessions) {
/** 获取session保存的用户信息 (我是用户对象保存 ) */
Object obj = session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
SimplePrincipalCollection coll = (SimplePrincipalCollection) obj;
if (coll != null) {
AccountDto accountDto = (AccountDto) coll.getPrimaryPrincipal();
/**判断session是否保存有相同的信息 */
if (loginUser.getUsername().equals(String.valueOf(accountDto.getUsername()))) {
/**清楚其他用户登录的session */
if (!session.getId().toString().equals(currentUser.getSession().getId().toString())) {
/** 删除session信息*/
sessionManager.getSessionDAO().delete(session);
}
}
}
}
}
}