Shiro整合SSO单点登录系统
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_37797991/article/details/78529096
前言
shiro是一个非常强大的权限管理框架,关于shiro与cas整合的示例有很多,但是我们平时开发的时候,很多公司并不是使用cas来做SSO的,而是自己公司会用自己开发的。本文就主要针对这种方式的整合。
新增SSO相关的properties
#sso服务器登录地址,service参数表示登录成功后要跳转的地址
ssoServiceUrl=http://www.authserver.com/auth/login?service=http://www.client.com/user/login
#sso的token的校验地址
tokenValidateUrl=http://www.authserver.com:9999/auth/validatetoken
#应用名称标识
microServiceId=app
#redis相关信息
JedisUrl=198.168.1.101
JedisPort=6379
JedisPassword=666666
1
2
3
4
5
6
7
8
9
10
11
12
13
修改spring-shiro.xml
<bean id="shiroSecurityFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="${ssoServiceUrl}" />
<!-- <property name="successUrl" value="/user/index" /> -->
<property name="filters">
<map>
<entry key="authc" value-ref="ssoFilter"/>
</map>
</property>
<property name="filterChainDefinitions">
<value>
/kaptcha.jpg=anon
/assets/** = anon
/images/** = anon
/javascripts/** = anon
/stylesheets/** = anon
/user/login = anon
/httpserver/* = anon
/** = authc
</value>
</property>
</bean>
<bean id="ssoFilter" class="com.demo.web.sso.SSOFilter"/>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
自定义ssoFilter
/**
* sso自定义过滤器
*/
public class SSOFilter implements Filter{
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
{
HttpServletRequest request = (HttpServletRequest)servletRequest;
HttpServletResponse response = (HttpServletResponse)servletResponse;
String token = request.getParameter("token");
PropertiesTool propertiesTool = PropertiesTool.getInstance();
String ssoServiceUrl = propertiesTool.getValue("ssoServiceUrl");
String tokenValidateUrl = propertiesTool.getValue("tokenValidateUrl");
if(null == token) {
Cookie cookie = CookieUtil.getCookieByName(request, "token");
if(null != cookie) {
token = cookie.getValue();
}
}
if(null == token) {
//没有token,重定向至sso server登录页
response.sendRedirect(ssoServiceUrl);
}else {
String urlString = request.getRequestURI();
if(urlString.endsWith("/logout")) {
String JedisUrl = propertiesTool.getValue("JedisUrl");
String JedisPort = propertiesTool.getValue("JedisPort");
Jedis jedis = new Jedis(JedisUrl, Integer.parseInt(JedisPort));
jedis.del(token.getBytes());
jedis.close();
SecurityUtils.getSubject().logout();
response.sendRedirect(ssoServiceUrl);//重定向至sso server登录页
return;
}
//有token,去sso server验证token的有效性
Map<String, String> map = new HashMap<>();
map.put("token", token);
String result = HttpClientUtil.doGet(tokenValidateUrl, map);
if(StringUtils.isNotBlank(result)){//验证成功,跳转至首页,并从redis中获取权限
SystemSession.setUser(SSOTokenUtil.getToken(request));//设置系统session(把用户信息保存在ThreadLocal中)
Cookie cookie = new Cookie("token", token);
cookie.setPath("/");
response.addCookie(cookie);
filterChain.doFilter(request, response);
} else{
response.sendRedirect(ssoServiceUrl);//验证失败,重定向至sso server登录页
}
}
}
}
public void destroy() {
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
自定义shiro的realm
在spring-shiro.xml中添加:
<bean id="myRealm" class="com.demo.web.realm.MyRealm"/>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myRealm" />
</bean>
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
<bean
class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager" />
</bean>
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
</bean>
1
2
3
4
5
6
7
8
9
10
11
12
realm类:
public class MyRealm extends AuthorizingRealm{
public MyRealm() {
setName("myRealm");
HashedCredentialsMatcher hcm = new HashedCredentialsMatcher();
//使用SHA-512 加密
hcm.setHashAlgorithmName(Sha512Hash.ALGORITHM_NAME);
setCredentialsMatcher(hcm);
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
SysUser user = SystemSession.getUser();
if (user != null) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
List<Menu> list = user.getRoles().get(0).getMenuList();
for (Menu menu : list){
if (StringUtils.isNotBlank(menu.getPermission())) {
// 添加基于Permission的权限信息
for (String permission : StringUtils.split(menu.getPermission(),",")){
info.addStringPermission(permission);
}
}
}
// 添加用户权限
info.addStringPermission("user");
// 添加用户角色信息
for (SysRole role : user.getRoles()) {
info.addRole(role.getEnglishName());
}
return info;
} else {
return null;
}
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authcToken) throws AuthenticationException {
//获取user信息
SysUser user = SystemSession.getUser();
if (user != null) {
if (user.getIsEnable()!=1) {
throw new AuthenticationException("msg:该帐号已禁止登录.");
}
return new SimpleAuthenticationInfo(new Principal(user), Constants.CREDENTIALS, getName());
}
return null;
}
public static class Principal implements Serializable {
private static final long serialVersionUID = 1L;
private String id; // 编号
private String loginName; // 登录名
private String name; // 姓名
private List<String> roleIdList;
public List<String> getRoleIdList() {
return roleIdList;
}
public void setRoleIdList(List<String> roleIdList) {
this.roleIdList = roleIdList;
}
public Principal(SysUser user) {
this.id = user.getId();
this.loginName = user.getUsername();
this.name = user.getCharacterName();
this.roleIdList=user.getRoleIdList();
}
public String getId() {
return id;
}
public String getLoginName() {
return loginName;
}
public String getName() {
return name;
}
@Override
public String toString() {
return id;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
由于shrio权限要做登录校验,但我们的登录已交给sso处理,这里只需要保证shiro的前后校验能通过就行,把password改成常量,并取消原来的加盐。CREDENTIALS=”6bf968f0c7b39ddbb7c8aa836b74d092060ed9b85b620a7fb088ecc48c6b3efd696bbd820f74c14f66c80c86c557c4bfda51b8a3743d3d568cc5c08410b7bb6a”;
修改index
@RequestMapping("index")
public String index(ModelMap model, String mainFrame, HttpServletRequest request) {
SysUser currentUser = SSOTokenUtil.getToken(request);
List<Menu> menus = currentUser.getRoles().get(0).getMenuList();
List<Menu> sysMenus = new ArrayList<>();
for(Menu menu : menus){
if(currentUser.getRemarks().equals(menu.getSysCode())){
sysMenus.add(menu);
}
}
//设置用户登录信息
UsernamePasswordToken token = new UsernamePasswordToken(
currentUser.getUsername(), Constants.PASSWORD);
SecurityUtils.getSubject().login(token);
model.addAttribute("menus", sysMenus);
model.addAttribute("currentUser", currentUser);
return "index";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
PASSWORD= “lvadmin”,是CREDENTIALS对应的明文。
文中所用到的一些SSOFilter,SystemSession,SSOTokenUtil等原码,以附件的形式提供下载。
Shiro整合SSO单点登录系统工具类下载
————————————————
版权声明:本文为CSDN博主「MrCao杰罗尔德」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_37797991/article/details/78529096
Shiro整合SSO单点登录系统相关推荐
- SpringBoot+MyBatis+Redis实现SSO单点登录系统(二)
SpringBoot+MyBatis+Redis实现SSO单点登录系统(二) 三.代码 配置文件配置数据库,redis等相关的信息. # See http://docs.spring.io/sprin ...
- SpringBoot+MyBatis+Redis实现SSO单点登录系统(一)
SpringBoot+MyBatis+Redis实现SSO单点登录系统(一) 一.SSO系统概述 SSO英文全称Single Sign On,单点登录.SSO是在多个应用系统中,用户只需要登录一次就可 ...
- sso单点登录系统(解决session共享)
场景:假设一个用户将自己的登录信息提交到后台,如果session保存的信息分布在多台机器上,并且不共享,那么可能导致用户的登录信息出现短暂的丢失,为什么这样讲,因为用户访问服务器中间还要经过负载均衡服 ...
- 互联网分布式微服务云平台规划分析--SSO单点登录系统
介绍 鸿鹄云架构[SSO单点登录系统]为所有微服务提供统一的用户认证服务,系统本身属于微服务模式,使用JWT+Redis分布式存储方案,确保不同微服务.系统之间的安全通讯和统一用户校验.认证.在整个服 ...
- 手撕一套sso(单点登录)系统之原理篇1
在手撕之前,你首先要了解一些原理,我写的案例成品可以访问zauth,语言是Java8. 目录 1.关于Http 2.用户信息怎么存?存什么?存在哪? 2.1 使用前端存储技术Storage或index ...
- JWT实战 Spring Security Oauth2整合JWT 整合SSO单点登录
文章目录 一.JWT 1.1 什么是JWT 1.2 JWT组成 头部(header) 载荷(payload) 签名(signature) 如何应用 1.3 JJWT 快速开始 创建token toke ...
- SSO单点登录系统的实战运用
通用介绍 单点登录系统,简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.任何SSO框架都需要创建统一的认 ...
- sso单点登录系统的理解
单点登录有两种方式,一种是跨域,一种是不跨域. 一:在不跨域的情况下, 只需要将cookie设置为顶域状态,即可以实现cookie的共享. 二:跨域登录 用户访问app系统,app系统是需要登录的,但 ...
- 基于cookie的SSO单点登录系统
利用COOKIE实现单点登录功能 近期公司要求帮一个项目实现单点登录功能,在综合考量下决定采用cookie实现,大概的流程如下图所: 转载于:https://www.cnblogs.com/bugge ...
最新文章
- 0x66.图论 - Tarjan算法与无向图连通性
- 关于java中的各种流
- wxWidgets随笔(13)-wxBoxSizer类Basic Box Sizer(2)
- 朱林北京大学计算机学院,北大、清华状元谈英语学习经验-20210411145045.docx-原创力文档...
- 基于CSMA -CA协议的无线星型网络的应用案例介绍
- 【JSTL】<c:if test=“”>没有else的解决方法
- 跟我一起学docker(九)--持续系统集成了解下git
- php和vue实现智商在线测试题
- ubuntu系统firefox浏览器无法播放音视频
- 不在同一局域网?组建家庭局域网的方案和踩坑
- 想成为游戏原画师需要哪些系统的学习?
- 马云说过的计算机名言,马云说过最洗脑10名言 马云经典语录大全
- 重磅公开!集14位名师教案的《最全高中数学解题思想方法汇编》
- linux命令vi编辑文件注释掉某一行,请问linux的vi命令进入文本编辑后怎么去删除一行?...
- Scrape Center爬虫平台之spa8案例
- 如何提升测试人员在公司的地位
- 唯一能够胜过对手的,只有你的学习能力
- 实验八 页面置换模拟程序设计
- linux怎么添加拼音输入法,ubuntu如何安装中文输入法
- 搜索引擎搜索特定网站的方法 :site
热门文章
- Spring Cloud Config 配置的加密解密
- 如何在Mac电脑上取消Apple Music订阅?
- 深度共建产业学院项目合作协议-某真实案例
- iOS16.1开发者预览版Beta3发布:优化壁纸功能
- b01lers CTF web 复现
- 透视色轮(超赞的设计色彩研究)
- android 电脑屏幕扩展,Windows 有一个自带功能,帮你轻松实现大屏、小屏无线扩展...
- word如何弄成两竖列_在Word中怎么将文字改成竖排显示?
- 笔记本扬声器无声音,必须断电重启问题
- java文件服务器出售,java文件服务器