一般的登陆只需要校验账号和密码两个要素
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(
user.getAccNum(), user.getPasswd());
try {
subject.login(usernamePasswordToken);
} catch (UnknownAccountException uae) {
return result.failed("账号或密码错误");
} catch (IncorrectCredentialsException ice) {
return result.failed("账号或密码错误");
} catch (LockedAccountException lae) {
return result.failed("账号被冻结");
} catch (RuntimeException re) {
return result.failed(re.getMessage());
}
如上,默认的UsernamePasswordToken
就能满足需求
现有需求,不仅需要账号和密码,还需要附带一个组织id来校验用户信息,解决方案,自行重写token
一、定义token
package cn.com.suntree.treeback.config;
import org.apache.shiro.authc.AuthenticationToken;
public class MyAuthenticationToken implements AuthenticationToken {
private String companyId;//新增的校验因子
/**
* The username
*/
private String username;
/**
* The password, in char[] format
*/
private char[] password;
public void setCompanyId(String companyId){
this.companyId = companyId;
}
public String getCompanyId(){
return companyId;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(char[] password) {
this.password = password;
}
public Object getPrincipal() {
return getUsername();
}
public Object getCredentials() {
return getPassword();
}
public char[] getPassword() {
return password;
}
public String getUsername() {
return username;
}
public MyAuthenticationToken() {
}
public MyAuthenticationToken(final String username, final char[] password,
final String companyId) {
this.username = username;
this.password = password;
this.companyId = companyId;
}
}
二、复写supports
方法
在自定义realm
中复写supports
方法,使之能识别自定义token
@Override
public boolean supports(AuthenticationToken token){
return token != null && token instanceof MyAuthenticationToken;
}
三、改造身份认证方法doGetAuthenticationInfo
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
MyAuthenticationToken token = (MyAuthenticationToken)authenticationToken;//强转为自定义token
SysUserBack u = new SysUserBack();
u.setAccNum(token.getUsername());
u.setCompanyId(token.getCompanyId());
SysUserBack user = userBackService.getUserByAcc(u);
System.err.println(user);
if (user == null) {
throw new UnknownAccountException();
} else if ("0".equals(user.getIsLock())) {
throw new LockedAccountException(); // 帐号冻结,非正常
} else {
SimpleAuthenticationInfo simpleAuthenticationInfo =
new SimpleAuthenticationInfo(user, user.getBackPasswd(), this.getName());
return simpleAuthenticationInfo;
}
}
三、修改login
使用自定义的token
Subject subject = SecurityUtils.getSubject();
subject.getSession().setTimeout(28800000);
MyAuthenticationToken usernamePasswordToken = new MyAuthenticationToken(
sysUserBack.getAccNum(), sysUserBack.getBackPasswd().toCharArray(),companyId);
try {
subject.login(usernamePasswordToken);
} catch (UnknownAccountException uae) {
return result.failed("账号或密码错误");
} catch (IncorrectCredentialsException ice) {
return result.failed("账号或密码错误");
} catch (LockedAccountException lae) {
return result.failed("账号被冻结");
} catch (RuntimeException re) {
return result.failed(re.getMessage());
}
搞定~
补充一个完整的realm
/**
* 自定义 - 数据域
*/
public class MyShiroRealm extends AuthorizingRealm {
@Autowired
@Lazy
private SysUserBackService userBackService;
/**
* @param principalCollection
* @return
* @implNote 功能授权
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SysUserBack user = (SysUserBack) principalCollection.getPrimaryPrincipal();
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
user = userBackService.getUserDetailInfoByUserId(user.getUserID(), user.getCompanyId());
List<Role> roleList = user.getRoleList();
for (Role role : roleList) {
authorizationInfo.addRole(role.getRoleName());
if (CommonUtil.check(role.getPowerList())) {
for (Power permission : role.getPowerList()) {
authorizationInfo.addStringPermission(permission.getUrl());
}
}
}
return authorizationInfo;
}
/**
* @param authenticationToken
* @return
* @throws AuthenticationException
* @implNote 身份认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
MyAuthenticationToken token = (MyAuthenticationToken)authenticationToken;
SysUserBack u = new SysUserBack();
u.setAccNum(token.getUsername());
u.setCompanyId(token.getCompanyId());
SysUserBack user = userBackService.getUserByAcc(u);
System.err.println(user);
if (user == null) {
throw new UnknownAccountException();
} else if ("0".equals(user.getIsLock())) {
throw new LockedAccountException(); // 帐号冻结,非正常
} else {
SimpleAuthenticationInfo simpleAuthenticationInfo =
new SimpleAuthenticationInfo(user, user.getBackPasswd(), this.getName());
return simpleAuthenticationInfo;
}
}
@Override
public boolean supports(AuthenticationToken token){
return token != null && token instanceof MyAuthenticationToken;
}
}