Shiro登录身份认证(从SecurityUtils.getSubject().login(token))到Realm的doGetAuthenticationInfo
2024-09-04 07:32:51
ssm框架下,controller接收到登录请求交给Service并开始处理流程:
1.Service的login方法:
@Service
public class SysUserServiceImpl implements SysUserService {
@Autowired
SysUserMapper mapper;
@Override
public LoginResult login(SysUser sysUser) {
LoginResult loginResult = new LoginResult();
try {
List<SysUser> sysUsers = mapper.selectByExample(sysUser.getUsername());
BackUserToken backUserToken=new BackUserToken(sysUser.getUsername(), sysUser.getPwd(),sysUsers);
SecurityUtils.getSubject().login(backUserToken);
loginResult.setStatus(RespMSG.STATUS_SUCCESS);
loginResult.setMsg(RespMSG.MSG_SUCCESS);
loginResult.setSysUser(sysUsers.get(0));
return loginResult;
} catch (UnknownAccountException e) {
loginResult.setStatus(RespMSG.STATUS_NON_EXISTENT);
loginResult.setMsg(RespMSG.MSG_NON_EXISTENT);
return loginResult;
} catch (AccountException e) {
e.printStackTrace();
// loginResult.setStatus(RespMSG.);
// loginResult.setMsg(RespMSG.MSG_NON_EXISTENT);
// return loginResult;
} catch (DeadlineException e) {
loginResult.setStatus(RespMSG.STATUS_OVERDUE);
loginResult.setMsg(RespMSG.MSG_OVERDUE);
return loginResult;
} catch (AccountRepeatException e) {
loginResult.setStatus(RespMSG.STATUS_REPETITION);
loginResult.setMsg(RespMSG.MSG_REPETITION);
return loginResult;
} catch (IncorrectCredentialsException e) {
loginResult.setStatus(RespMSG.STATUS_WRONG_PWD);
loginResult.setMsg(RespMSG.MSG_WRONG_PWD);
return loginResult;
}
loginResult.setMsg(RespMSG.MSG_UNKNOW);
loginResult.setStatus(RespMSG.STATUS_UNKNOW);
return loginResult;
}
}
BackUserToken集成了UsernamePasswordToken,主要是构造参数多了一个List<SysUser>.因为我需要在service中将登录用户的详细
信息返回给客户端,同时将登录用户的信息传递给Realm进行登录验证。
关键方法是:
SecurityUtils.getSubject().login(backUserToken);
其具体实现是:
2.DelegatingSubject implements Subject
public class DelegatingSubject implements Subject {
public void login(AuthenticationToken token) throws AuthenticationException {
...
Subject subject = this.securityManager.login(this, token);
...
}
}
token继续传递:
3.DefaultSecurityManager
public class DefaultSecurityManager extends SessionsSecurityManager {
public Subject login(Subject subject, AuthenticationToken token) throws AuthenticationException {
...
info = this.authenticate(token);
...
return loggedIn;
}
}
向下继续
4.AuthenticatingSecurityManager
public abstract class AuthenticatingSecurityManager extends RealmSecurityManager {
public AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {
return this.authenticator.authenticate(token);
}
}
继续向下
5.AbstractAuthenticator
public abstract class AbstractAuthenticator implements Authenticator, LogoutAware {
public final AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {
...
info = this.doAuthenticate(token);
...
return info;
}
}
}
6.ModularRealmAuthenticator
public class ModularRealmAuthenticator extends AbstractAuthenticator {
protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
this.assertRealmsConfigured();
Collection<Realm> realms = this.getRealms();
return realms.size() == 1 ? this.doSingleRealmAuthentication((Realm)realms.iterator().next(), authenticationToken) : this.doMultiRealmAuthentication(realms, authenticationToken);
}
}
还是在ModularRealmAuthenticator中
protected AuthenticationInfo doSingleRealmAuthentication(Realm realm, AuthenticationToken token) {
...
AuthenticationInfo info = realm.getAuthenticationInfo(token);
...
}
继续
7.AuthenticatingRealm
public abstract class AuthenticatingRealm extends CachingRealm implements Initializable {
public final AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
...
info = this.doGetAuthenticationInfo(token);
...
return info;
}
}
然后进入最后一步,在继承了AuthorizingRealm的自定义的realm中进行处理。
8.自定义realm举例
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) {
BackUserToken token = (BackUserToken) authenticationToken;
List<SysUser> sysUsers = token.getUser();
if (sysUsers == null || sysUsers.size() == 0) {
throw new UnknownAccountException();
}
if (sysUsers.size() > 1) {
//用户重复
throw new AccountRepeatException();
}
if (用户已过期) {
if (sysUsers.get(0).getIsAbleDate() == null||sysUsers.get(0).getIsAbleDate().getTime() < new Date().getTime()) {
//用户过期(自定义异常)
throw new DeadlineException();
}
}
SysUser sysUser = sysUsers.get(0);
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
sysUser,
sysUser.getPwd(),
getName()
);
return authenticationInfo;
}
最新文章
- 我的MYSQL学习心得(二) 数据类型宽度
- Android IOS WebRTC 音视频开发总结(十五)-- 培训课程大纲
- MYSQL外键约束的参照操作
- JAVA日历
- 【转】iOS Provisioning Profile(Certificate)与Code Signing详解 -- 待看
- 使用charles proxy for Mac来抓取手机App的网络包
- 【递归】Vijos P1114 FBI树(NOIP2004普及组第三题)
- hdoj 3549 Flow Problem(最大网络流)
- Android获取SD卡中选中图片的路径(URL)
- Oralce生成前N年的年数据
- java设计模式案例详解:观察者模式
- Anaconda使用
- https----------如何在phpstudy环境下配置apache的https访问以及访问http自动跳转成https
- Mybatis笔记三:全局配置文件
- zsh,oh-my-zsh,antigen使用记录
- DNA sequence open reading frames (ORFs) | DNA序列的开放阅读框ORF预测
- 一个基于DPI技术实现了内网资产识别的应用
- jQuery(七):节点操作
- springboot logback + log4j2日志管理
- Django 之 CBV &; FBV