一般的登陆只需要校验账号和密码两个要素
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; } }