简单实现Shiro单点登录(自定义Token令牌)
1. MVC Controller 映射 sso 方法。
/**
* 单点登录(如已经登录,则直接跳转)
* @param userCode 登录用户编码
* @param token 登录令牌,令牌组成:sso密钥+用户名+日期,进行md5加密,举例:
* String secretKey = Global.getConfig("shiro.sso.secretKey");
* String token = Digests.md5(secretKey + userCode + DateUtils.getDate("yyyyMMdd"));
* @param url 登录成功后跳转的url地址。
* @param relogin 是否重新登录,需要重新登录传递true
* 例如:http://localhost/project/sso/{token}?url=xxx&relogin=true
*/
@RequestMapping(value = "sso/{userCode}/{token}")
public String sso(@PathVariable String userCode, @PathVariable String token,
@RequestParam(required=true) String url, String relogin, Model model) {
Principal principal = SecurityUtils.getSubject().getPrincipal();
// 如果已经登录
if(principal != null){
// 如果设置强制重新登录,则重新登录
if (BooleanUtils.toBoolean(relogin)){
SecurityUtils.getSubject().logout();
}
// 否则,直接跳转到目标页
else{
return "redirect:" + Encodes.urlDecode2(url);
}
}
// 进行单点登录
if (token != null){
UsernamePasswordToken upt = new UsernamePasswordToken();
try {
upt.setUsername(userCode); // 登录用户名
upt.setPassword(token.toCharArray()); // 密码组成:sso密钥+用户名+日期,进行md5加密,举例: Digests.md5(secretKey+username+20150101))
upt.setParams(upt.toString()); // 单点登录识别参数,see: AuthorizingRealm.assertCredentialsMatch
} catch (Exception ex){
if (!ex.getMessage().startsWith("msg:")){
ex = new AuthenticationException("msg:授权令牌错误,请联系管理员。");
}
model.addAttribute("exception", ex);
}
try {
SecurityUtils.getSubject().login(upt);
return "redirect:" + Encodes.urlDecode2(url);
} catch (AuthenticationException ae) {
if (!ae.getMessage().startsWith("msg:")){
ae = new AuthenticationException("msg:授权错误,请检查用户配置,若不能解决,请联系管理员。");
}
model.addAttribute("exception", ae);
}
}
return "error/403";
}
2. 重载org.apache.shiro.realm.AuthorizingRealm类的assertCredentialsMatch方法
/**
* 认证密码匹配调用方法
*/
@Override
protected void assertCredentialsMatch(AuthenticationToken authcToken,
AuthenticationInfo info) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
// 若单点登录,则使用单点登录授权方法。
if (token.toString().equals(token.getParams())){
// sso密钥+用户名+日期,进行md5加密,举例: Digests.md5(secretKey+username+20150101))
String secretKey = Global.getConfig("shiro.sso.secretKey");
String password = Digests.md5(secretKey + token.getUsername() + DateUtils.getDate("yyyyMMdd"));
if (password.equals(String.valueOf(token.getPassword()))){
return;
}
}
super.assertCredentialsMatch(token, info);
}
3. 实现Shiro无状态访问,如通过传递sessionid参数即可实现会话访问
这里需要自定义Shiro的SessionManager类,方法是继承org.apache.shiro.web.session.mgt.DefaultWebSessionManager类,重载getSessionId方法,如下:
public class SessionManager extends DefaultWebSessionManager {
public SessionManager() {
super();
}
@Override
protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
// 如果参数中包含“__sid”参数,则使用此sid会话。 例如:http://localhost/project?__sid=xxx&__cookie=true
// 其实这里还可以使用如下参数:cookie中的session名称:如:JSESSIONID=xxx,路径中的 ;JESSIONID=xxx,但建议还是使用 __sid参数。
String sid = request.getParameter("__sid");
if (StringUtils.isNotBlank(sid)) {
// 是否将sid保存到cookie,浏览器模式下使用此参数。
if (WebUtils.isTrue(request, "__cookie")){
HttpServletRequest rq = (HttpServletRequest)request;
HttpServletResponse rs = (HttpServletResponse)response;
Cookie template = getSessionIdCookie();
Cookie cookie = new SimpleCookie(template);
cookie.setValue(sid); cookie.saveTo(rq, rs);
}
// 设置当前session状态
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,
ShiroHttpServletRequest.URL_SESSION_ID_SOURCE); // session来源与url
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, sid);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
return sid;
}else{
return super.getSessionId(request, response);
}
}
}
简单实现Shiro单点登录(自定义Token令牌)的更多相关文章
- shiro 单点登录原理 实例
原创 2017年02月08日 17:39:55 4006 Shiro 1.2开始提供了Jasig CAS单点登录的支持,单点登录主要用于多系统集成,即在多个系统中,用户只需要到一个中央服务器登录一次即 ...
- 使用 JSONP 实现简单的 SSO 单点登录
SSO 即 Single Sign On(单点登录). 一.二级域名之间的单点登录 不需要用到JSONP 或者 p3p 协议,直接使用 COOKIE 就行了,因为顶级域名相同就能实现 COOKIE ...
- 也谈SSO,一个简单实用的单点登录Demo
关于SSO(单点登录),百度百科解释如下 : “SSO英文全称Single Sign On,单点登录.SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.它包括可以将这次主要 ...
- cas 单点登录 --自定义审计日记@Audit()
错误信息: org.springframework.webflow.execution.ActionExecutionException: Exception thrown executing [An ...
- 简单实现web单点登录
主要参考文档:http://blog.csdn.net/jimmy609/article/details/18605781 1.工程总体结构: 2.修改C:\Windows\System32\driv ...
- (四)SSO之CAS框架单点登录,自定义验证登录方式
应需求的变化,在登录cas的时候,默认根据用户名和密码进行验证,如果加上用户名,密码和一个系统标识进行验证呢?该如何做呢? 我们知道cas默认的登录界面中,输入的用户名和密码,再配置一下deploye ...
- SSO单点登录PHP简单版
前面做了一个新项目,需要用户资源可以需要共享.由于之前没有做过这样的东西,回家之后,立马网站百度"单点登录".帖子很多,甄别之后,这里列几篇认为比较有营养. http://blog ...
- 初探系列 — Pharbers用于单点登录的权限架构
一. 前言 就职公司 法伯科技是一家以数据科技为驱动, 专注于医药健康领域的循证咨询公司. 以数据科学家身份, 赋能医药行业. 让每位客户都能享受数据带来的价值, 洞察业务, 不止于数据, 让决策更精 ...
- 最准确的单点登录SSO图示和讲解(有代码范例)|手把手教做单点登录(SSO)系列之二
写第一篇博客<手把手教做单点登录(SSO)系列之一:概述与示例>,就获得了园子里朋友们热情的评论和推荐,感谢各位. 我那篇文章同时发了CSDN和博客园.对比一下,更感受到博客园童鞋们的技术 ...
随机推荐
- 20180706模拟赛T3——神经衰弱
文件名: card 题目类型: 传统题 时间限制: 1秒 内存限制: 128MB 编译优化: 无 题目描述 天然少女小雪非常喜欢玩一个叫做神经衰弱的游戏. 游戏规则是,有若干种牌,每种牌有若干对,开始 ...
- day36_8_20数据库3外键
一.一对多 在数据库使用数据中经常遇到一对多的情况,以公司员工为例. 一张完整的员工表有以下字段: id name gender dep_name dep_desc . 以此建表得: id n ...
- opencv归一化图像
cv::normalize(src, dst, 0.0, 255.0, cv::NORM_MINMAX);
- 使用opencv320演示window平台cmake的使用方法以及一个使用CNN识别字符的例子 20180408
cmake是干啥的: 本来是Linux平台的一个编译工具. window平台上,cmake可以生成一个可以用vs(可以指定)打开的工程,然后使用 vs 编译相关的 lib.dll 或者 exe以供使用 ...
- JavaEE开发环境配置
JavaEE开发环境配置 Tomcat的下载和安装 1.登录Tomcat 站点,下载Tomcat最新版本http://tomcat.apache.org/Windows平台下载ZIP包,LInux平台 ...
- 你真的了解FastClick吗?
你真的了解FastClick吗? 前段时间在做公司官网手机端菜单部分的时候,遇到一些很诡异的点击问题.比如菜单点击无效/双击才有效.在手指滑动的时候会触发点击事件.以及同样的事件处理在微信跟浏览器会有 ...
- git npm包管理
#Node # node 一.安装nodejs 下载地址:http://nodejs.cn/download/ 二.安装git 下载地址:https://git-scm.com/download/wi ...
- 其它 dev是什么意思
原文:https://blog.csdn.net/zsl131557/article/details/80886114 原文:https://blog.csdn.net/LYmahang123/art ...
- ESP8266 AT指令开发(基于STC89C52单片机): 硬件使用说明
实物图 硬件说明 开发板板载说明: 1.主控芯片: STC89C52 2.Wi-Fi模块: ESP8266 3.温湿度传感器: DHT11 4.液晶屏: IIC OLED 5.继电器: 220V 10 ...
- appium--多进程启动多设备
前戏 在前面我们都是使用一个机器进行测试,在做app自动化的时候,我们要测不同的机型,也就是兼容性测试,如果一台一台设备去执行,那就显的太麻烦了.所以经常需要我们启动多个设备,同时跑自动化测试用例,要 ...