SSO 单点登录、CAS、OAuth2、系统登录
JeeSite 支持登录方式如下:
1、SSO 简单登录 接口,实现快速登录系统
2、Apereo CAS 服务器集成,快速实现系统登录(个人版)
3、OAuth2 第三方登录,如:微信、QQ、支付宝、等等(专业版)
4、无条件登录,无需密码,仅允许通过 Java 内部调用,保证系统安全
# 简单登录接口
# 系统登录接口
1、设置 application.yml
(v4.0.x:jeesite.yml
)的 shiro.sso.secretKey 快速登录安全Key,若不设置将无法使用该接口。
shiro:
# 简单 SSO 登录相关配置
sso:
# 如果启用/sso/{username}/{token}单点登录,请修改此安全key并与单点登录系统key一致。
# 安全KEY,随便写,写一个您自己的安全秘钥
secretKey: thinkgem
# 是否加密单点登录安全Key
encryptKey: true
2
3
4
5
6
7
8
2、举例调用地址如下,调用完成后自动登录系统:
http://localhost/project/sso/{username}/{token}?url=/sys/user/list?p1=v1%26p2=v2&relogin=true
- username: 登录名,数据库中的 login_code 字段。
- token: 登录令牌,根据yml里配置的登录安全Key生产的密码。
- url: 登录之后要跳转的地址,如果url中携带参数,请使用转义字符,如“&”号,使用“%26”转义。
token生成方式:
String username = "system"; // 登录系统名
String secretKey = "thinkgem"; // yml 中设置的 shiro.sso.secretKey 参数值。
String token = Md5Utils.md5(secretKey + username + DateUtils.getDate("yyyyMMdd"));
// 如果 shiro.sso.encryptKey 为 true,则 secretKey 会自动加密。
// 如果在本系统获取,则 secretKey 已经加密了,也可以通过下面这个简便方法获取。
String token = UserUtils.getSsoToken(username);
2
3
4
5
6
7
该接口源码(提供参考):
/modules/core/src/main/java/com/jeesite/modules/sys/web/SsoController.java
# 系统退出接口
http://127.0.0.1:8980/js/a/logout?__ajax=json&__sid=5fe9c7c45ded4425b03eff8f78179637
注意:无 cookie 环境下,必须要指定要退出的 sessionid
返回JSON数据:
{"result":"true","message":"退出成功!"}
# Apereo CAS 集成
# 客户端配置方法
CAS 客户端配置非常简单,开启如下配置,设置好服务于客户端跳转地址即可:
shiro:
# Apereo CAS 相关配置(标准版)
casServerUrl: http://127.0.0.1:8981/cas
casClientUrl: http://127.0.0.1:8980/js
loginUrl: ${shiro.casServerUrl}?service=${shiro.casClientUrl}${adminPath}/login-cas
logoutUrl: ${shiro.casServerUrl}/logout?service=${shiro.loginUrl}
successUrl: ${shiro.casClientUrl}${adminPath}/index
2
3
4
5
6
7
注意:此功能是标准版功能,只有标准版以上版本才能使用。
# 分离版 CAS 配置方法
首先保证后端接口和前端页面在一个域名下,否则前后不能会话共享
1、后端配置 application.yml
shiro:
# Apereo CAS 相关配置(标准版)
casServerUrl: http://127.0.0.1:8981/cas
casClientUrl: http://127.0.0.1:3100/js
loginUrl: ${shiro.casServerUrl}?service=${shiro.casClientUrl}${adminPath}/login-cas
logoutUrl: ${shiro.casServerUrl}/logout?service=${shiro.loginUrl}
successUrl: ${shiro.casClientUrl}/../
2
3
4
5
6
7
提示:shiro.casClientUrl
为前端访问后端的接口地址,shiro.successUrl
为前端地址首页地址。
2、找到文件 /src/views/sys/login/Login.vue
全部内容替换为:
<script lang="ts" setup>
window.location.href = '/js/a/login';
</script>
2
3
提示:/js
为后端接口,根据您项目情况前缀对应配置
3、找到文件 src/store/modules/user.ts
的 confirmLoginOut
方法替换为:
async confirmLoginOut() {
window.location.href = '/js/a/logout';
},
2
3
提示:地址为调用后端接口退出,此接口会直接调用 cas 服务端的 logout。
# 同时支持内部账号登录
可以通过 CAS 登录,也可以使用内部系统账号登录,操作如下:
1、修改 LoginController.java
@RequestMapping(value = "login")
// 修改为:
@RequestMapping(value = {"login", "login2"})
2
3
2、修改 sysLogin.html
在 <#form:form ...
标签内部添加:
<input type="hidden" name="__login" value="true">
3、修改 application.yml
添加 login2 的无需登录的访问权限
shiro:
filterChainDefinitions: |
${adminPath}/login2 = anon
${adminPath}/** = user
2
3
4
4、登录测试
访问登录页:http://127.0.0.1:8980/js/a/login2 (opens new window)
# OAuth2 第三方登录
集成史上最全的第三方登录的开源库 JustAuth。目前已支持Github、Gitee、微博、钉钉、百度、Coding、腾讯云开发者平台、OSChina、支付宝、QQ、微信、淘宝、Google、Facebook、抖音、领英、小米、微软、今日头条、Teambition、StackOverflow、Pinterest、人人、华为、企业微信、酷家乐、Gitlab、美团、饿了么和推特等第三方平台的授权登录。
该模块提供完善的通用接口扩展,若上述没说到的,也可以自己方便扩展。
# 使用方法配置:
1、打开 web 的 pom.xml,加入如下模块依赖代码
<!-- 第三方账号登录 -->
<dependency>
<groupId>com.jeesite</groupId>
<artifactId>jeesite-module-oauth2</artifactId>
<version>${project.parent.version}</version>
</dependency>
2
3
4
5
6
注意:v4.2.1+ 专业版提供,此模块依赖,请向售后人员索取。
2、配置参数:
# 第三方系统认证
oauth2:
# 码云
gitee:
clientId: xxxxxx
clientSecret: xxxxxx
redirectUri: http://127.0.0.1:8980/js/oauth2/callback/gitee
# 腾讯QQ
qq:
clientId: xxxxxx
clientSecret: xxxxxx
redirectUri: http://127.0.0.1:8980/js/oauth2/callback/qq
unionid: xxxxxx
# 微信开放平台
weixin:
clientId: xxxxxx
clientSecret: xxxxxx
redirectUri: http://127.0.0.1:8980/js/oauth2/callback/weixin
# 微信公众平台
weixin_mp:
clientId: xxxxxx
clientSecret: xxxxxx
redirectUri: http://127.0.0.1:8980/js/oauth2/callback/weixin_mp
# 企业微信
weixin_qy:
clientId: xxxxxx
clientSecret: xxxxxx
redirectUri: http://127.0.0.1:8980/js/oauth2/callback/weixin_qy
agentId: xxxxxx
# 钉钉
ding_talk:
clientId: xxxxxx
clientSecret: xxxxxx
redirectUri: http://127.0.0.1:8980/js/oauth2/callback/ding_talk
# JeeSite OAuth2 Server 统一认证中心
jeesite:
clientId: jeesite
clientSecret: jeesite
redirectUri: http://127.0.0.1:8980/js/oauth2/callback/jeesite
serverUrl: http://127.0.0.1:9999/js
# 自定义(v4.3.0)
custom:
clientId: xxxxxx
clientSecret: xxxxxx
redirectUri: http://127.0.0.1:8980/js/oauth2/callback/custom
className: com.jeesite.modules.oauth2.request.AuthCustomRequest
# 授权成功后的跳转地址 v5.3.0
successUrl: ${shiro.successUrl}
# 授权失败后的跳转地址
failureUrl: ${adminPath}/login
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
上述等等,不一一列举,具体可以打开 Oauth2UserService
的 getAuthRequest
方法查看并扩展
若是 Vue 分离版,只需配置 oauth2.successUrl
为您的分离端前端地址即可。
如果您的版本为 5.3.0 之前版本,可同步更新 Gitee 源码仓库里 FormFilter.java
文件的 successUrl
部分。
v4.2.1 之前版本,因为使用了秘钥登录,所以还需要配置以下参数,新版本无需配置
shiro:
# 简单 SSO 登录相关配置
sso:
# 如果启用/sso/{username}/{token}单点登录,请修改此安全key并与单点登录系统key一致。
# 安全KEY,随便写,写一个您自己的安全秘钥
secretKey: thinkgem
# 是否加密单点登录安全Key
encryptKey: true
2
3
4
5
6
7
8
# 系统登录地址:
地址格式:
http://127.0.0.1:8980/js/oauth2/login/第三方唯一标识
举例如下:
Gitee登录:http://127.0.0.1:8980/js/oauth2/login/gitee
QQ账号登录:http://127.0.0.1:8980/js/oauth2/login/qq
微信账号登录:http://127.0.0.1:8980/js/oauth2/login/weixin
JeeSite账号登录:http://127.0.0.1:8980/js/oauth2/login/jeesite
2
3
4
5
6
7
8
# 授权回调地址:
地址格式:
http://127.0.0.1:8980/js/oauth2/callback/第三方唯一标识
举例如下:
Gitee登录回调地址:http://127.0.0.1:8980/js/oauth2/callback/gitee
QQ账号登录回调地址:http://127.0.0.1:8980/js/oauth2/callback/qq
微信账号登录回调地址:http://127.0.0.1:8980/js/oauth2/callback/weixin
JeeSite账号登录回调地址:http://127.0.0.1:8980/js/oauth2/callback/jeesite
2
3
4
5
6
7
8
# 无条件登录接口
无条件也就是只需要用户名,无需密码去登录系统。该登录方法只允许通过 Java 内部调用登录,保证系统安全。
v4.3.0+ 版本(重命名 FormAuthenticationFilter 类名为 FormFilter):
HttpServletRequest request = ServletUtils.getRequest();
HttpServletResponse response = ServletUtils.getResponse();
try {
// FormToken 构造方法的三个参数:登录名、是否内部登录无条件、请求对象
UserUtils.getSubject().login(new FormToken(username, true, request));
System.out.println("登录成功,__sid=" + UserUtils.getSession().getId());
FormFilter.onLoginSuccess(request, response);
} catch (AuthenticationException e) {
FormFilter.onLoginFailure(e, request, response);
}
return null;
2
3
4
5
6
7
8
9
10
11
v4.2.2 增加内部登录方法,无需定义 SSO 秘钥,并优化输出信息:
HttpServletRequest request = ServletUtils.getRequest();
HttpServletResponse response = ServletUtils.getResponse();
try {
// FormToken 构造方法的三个参数:登录名、是否内部登录无条件、请求对象
UserUtils.getSubject().login(new FormToken(username, true, request));
System.out.println("登录成功,__sid=" + UserUtils.getSession().getId());
FormAuthenticationFilter.onLoginSuccess(request, response);
} catch (AuthenticationException e) {
FormAuthenticationFilter.onLoginFailure(e, request, response);
}
return null;
2
3
4
5
6
7
8
9
10
11
v4.2.1 及之前版本,需要通过 SSO 登录方式,步骤如下:
1、设置 application.yml
(v4.0.x:jeesite.yml
)的 shiro.sso.secretKey 快速登录安全Key:
shiro:
# 简单 SSO 登录相关配置
sso:
# 如果启用/sso/{username}/{token}单点登录,请修改此安全key并与单点登录系统key一致。
# 安全KEY,随便写,写一个您自己的安全秘钥
secretKey: thinkgem
# 是否加密单点登录安全Key
encryptKey: true
2
3
4
5
6
7
8
2、调用登录方法
try {
String username = "admin";
FormToken formToken = new FormToken();
formToken.setUsername(username);
formToken.setSsoToken(UserUtils.getSsoToken(username));
//formToken.setParams(ServletUtils.getExtParams(request));
UserUtils.getSubject().login(formToken);
String sid = UserUtils.getSession().getId().toString();
System.out.println("登录成功,__sid=" + sid);
} catch (AuthenticationException e) {
if (!e.getMessage().startsWith("msg:")){
throw new AuthenticationException("msg:登录失败,请联系管理员。", e);
}
throw e; // 登录失败,抛出异常
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 手机 APP 登录
详见:系统登录接口