Shiro登录身份认证(从SecurityUtils.getSubject().login(token))到Realm的doGetAuthenticationInfo
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;
}
Shiro登录身份认证(从SecurityUtils.getSubject().login(token))到Realm的doGetAuthenticationInfo的更多相关文章
- Python学习之for循环--输出1-100中的偶数和登录身份认证
输出1-100中的偶数 效果图: 实现代码: for i in range(2,101,2): print(i,end = '\t') if(i == 34): print('\n') if (i = ...
- Shiro之身份认证、与spring集成(入门级)
目录 1. Shro的概念 2. Shiro的简单身份认证实现 3. Shiro与spring对身份认证的实现 前言: Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在 JavaSE 环境 ...
- SpringBoot学习:整合shiro(身份认证和权限认证),使用EhCache缓存
项目下载地址:http://download.csdn.NET/detail/aqsunkai/9805821 (一)在pom.xml中添加依赖: <properties> <shi ...
- springboot集成shiro实现身份认证
github地址:https://github.com/peterowang/shiro pom文件 <dependencies> <dependency> <group ...
- asp.net core 登录身份认证(Cookie)
asp.net core 2最简单的登录功能 源代码在此 创建asp.net core Web Mvc项目 配置下选项 项目目录结构 在Models文件夹下新建两个实体类 public class T ...
- springboot+mybatis+shiro——登录认证和权限控制
转载:https://z77z.oschina.io/ 一.引入依赖 shiro-all包含shiro所有的包.shiro-core是核心包.shiro-web是与web整合.shiro-spring ...
- shiro登录认证过程讲解
先粘出登录的代码 1. 可以看到已经获取到了username和password ,为了接下来的认证过程,我们需要获取subject对象,也就是代表当前登录用户,并且要将username和passw ...
- spring-boot整合shiro作权限认证
spring-shiro属于轻量级权限框架,即使spring-security更新换代,市场上大多数企业还是选择shiro 废话不多说 引入pom文件 <!--shiro集成spring--& ...
- Apache shiro集群实现 (三)shiro身份认证(Shiro Authentication)
Apache shiro集群实现 (一) shiro入门介绍 Apache shiro集群实现 (二) shiro 的INI配置 Apache shiro集群实现 (三)shiro身份认证(Shiro ...
随机推荐
- matplotlib学习(1)
1.基本学习(1)1.1 代码: import matplotlib.pyplot as plt import numpy as np x=np.linspace(-1,1,50) #从-1到1,共5 ...
- 吴裕雄 python 神经网络——TensorFlow 花瓣识别2
import glob import os.path import numpy as np import tensorflow as tf from tensorflow.python.platfor ...
- NAT-T和PAT(IPSec)
¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥NAT-T技术介绍¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥ 为什么TCP和UDP不能穿越:TCP和UDP有一个IP头的尾部校验(校验头部和负载 ...
- Windowserver2012服务器激活方法(亲测可用)---转载
Windowserver2012服务器激活方法(亲测可用)原创꧁刘向洋꧂ 最后发布于2019-03-12 14:46:45 阅读数 5124 收藏展开激活方式 slmgr /ipk D2N9P-3P ...
- 解决sublime不能安装packages的问题
问题如下:该问题产生的原因是因为默认的配置中无法访问 "https://packagecontrol.io/channel_v3.json"该文件造成的 解决: 1.下载 chan ...
- 编译安装nginx错误解决!
编译安装执行 ./configure --prefix=/root/web/nginx --sbin-path=/root/web/nginx/sbin/nginx --conf-path=/root ...
- php 基础 PHP保留两位小数的几种方法
$num = 10.4567; //第一种:利用round()对浮点数进行四舍五入 echo round($num,2); //10.46 //第二种:利用sprintf格式化字符串 $format_ ...
- Tensorflow机器学习入门——ModuleNotFoundError: No module named 'tensorflow.keras'
这个bug的解决办法: # from tensorflow.keras import datasets, layers, models from tensorflow.python.keras imp ...
- Python 文件和目录操作学习
文件与文件路径 文件有两个关键属性:文件名和路径. 路径指明了文件在计算机上的位置. 文件名中,最后一个句点之后的部分称为文件的"扩展名",它指出了文件的类型 目录也叫文件夹,文件 ...
- js学习:基本语法结构
语句 JavaScript 程序的执行单位为行(line),也就是一行一行地执行.一般情况下,每一行就是一个语句. 语句(statement)是为了完成某种任务而进行的操作,比如下面就是一行赋值语句. ...