周末吃了个非常好吃的自助--温野菜,强烈推荐。
基于上一章,本章将介绍CAS Server如何基于JwtToken,进行身份验证。
首先需要了解一下CAS Server如何开启JWT Token认证支持,可以参考官方指南:
https://apereo.github.io/cas/5.3.x/installation/JWT-Authentication.html
复制
其实,比较简单,大概的步骤如下:
1. 引入Jar包,开启支持。
2. 设置CAS Properties。
3. 在服务注册表中配置服务。
4. 在之前自定义的Handler中实现自定义认证逻辑。
基于之前的代码,在pom.xml文件中增加:
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-support-token-core</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-support-token-webflow</artifactId>
<version>${cas.version}</version>
</dependency>复制
在application.properties文件中增加:
# JWT认证
cas.authn.token.name=token
cas.authn.token.crypto.encryptionEnabled=true
cas.authn.token.crypto.signingEnabled=true复制
新注册服务,在resources/service中新增文件Jwt-0000001.json:
{
"@class" : "org.apereo.cas.services.RegexRegisteredService",
"serviceId" : "^(https|http|imaps)://.*",
"name" : "JwtService",
"id" : 1,
"properties" : {
"@class" : "java.util.HashMap",
"jwtSigningSecret" : {
"@class" : "org.apereo.cas.services.DefaultRegisteredServiceProperty",
"values" : [ "java.util.HashSet", [ "12345678901234567890123456789012345678901" ] ]
},
"jwtSigningSecretAlg" : {
"@class" : "org.apereo.cas.services.DefaultRegisteredServiceProperty",
"values" : [ "java.util.HashSet", [ "HS256" ] ]
}
}
}复制
改造一下之前的UsernamePasswordCaptchaAuthenticationHandler,代码如下:
public class UsernamePasswordCaptchaAuthenticationHandler extends QueryDatabaseAuthenticationHandler {
private final String sql;
public UsernamePasswordCaptchaAuthenticationHandler(String name, ServicesManager servicesManager, PrincipalFactory principalFactory, Integer order, DataSource dataSource, String sql, String fieldPassword, String fieldExpired, String fieldDisabled, Map<String, Object> attributes) {
super(name, servicesManager, principalFactory, order, dataSource, sql, fieldPassword, fieldExpired, fieldDisabled, attributes);
this.sql = sql;
}
@Override
public boolean supports(Credential credential) {
//判断传递过来的Credential 是否是自己能处理的类型
return credential instanceof UsernamePasswordCredential || credential instanceof TokenCredential;
}
@Override
protected AuthenticationHandlerExecutionResult doAuthentication(Credential credential) throws GeneralSecurityException, PreventedException {
if (credential instanceof UsernamePasswordCaptchaCredential) {
return doLoginRequestAuthentication(credential);
} else if (credential instanceof TokenCredential) {
return doTokenAuthentication(credential);
}
throw new FailedLoginException("没有匹配的Handler");
}
private AuthenticationHandlerExecutionResult doLoginRequestAuthentication(Credential credential) throws GeneralSecurityException, PreventedException {
UsernamePasswordCaptchaCredential thisCredential = (UsernamePasswordCaptchaCredential) credential;
//从Session中读取验证码
String vcode;
try {
HttpSession httpSession = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession();
Object object = httpSession.getAttribute(ContextConstant.VALIDAT_CODE_KEY);
httpSession.removeAttribute(ContextConstant.VALIDAT_CODE_KEY);
vcode = null == object ? null : object.toString();
} catch (Exception e) {
throw new FailedLoginException("无法获取验证码");
}
//比对验证码
if (StrUtil.isNotBlank(thisCredential.getCaptcha())
&& thisCredential.getCaptcha().equals(vcode)) {
super.doAuthentication(credential);
return createHandlerResult(
thisCredential,
principalFactory.createPrincipal(thisCredential.getUsername(), new HashMap<>()),
new ArrayList<>()
);
}
throw new FailedLoginException("验证码错误");
}
private AuthenticationHandlerExecutionResult doTokenAuthentication(Credential credential) throws FailedLoginException {
TokenCredential tokenCredential = (TokenCredential) credential;
Map<String, Object> dbFields = this.getJdbcTemplate().queryForMap(this.sql, tokenCredential.getId());
if (MapUtil.isNotEmpty(dbFields)) {
return createHandlerResult(
tokenCredential,
principalFactory.createPrincipal(tokenCredential.getId(), new HashMap<>()),
new ArrayList<>()
);
}
throw new FailedLoginException("用户验证错误");
}
}复制
通过Postman请求如下地址:
POST /login?service=http://localhost:8081/&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIyMDE4MTQzMiIsImlzcyI6ImNlcyJ9.-43ymRRDLKHtm5TJehVXK4kMCMgtn6IVBUSiS7HNAsA
HTTP/1.1
Host: localhost:8080复制
会获得请求中service的ST凭据。
至于JWT的相关知识,还需要自行了解,或者后面单独开一章介绍一下。
以上,如有错误,欢迎指正。
觉的不错?可以关注我的公众号↑↑↑
文章转载自字痕随行,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
2025年4月中国数据库流行度排行榜:OB高分复登顶,崖山稳驭撼十强
墨天轮编辑部
1557次阅读
2025-04-09 15:33:27
2025年3月国产数据库大事记
墨天轮编辑部
792次阅读
2025-04-03 15:21:16
2025年3月国产数据库中标情况一览:TDSQL大单622万、GaussDB大单581万……
通讯员
568次阅读
2025-04-10 15:35:48
征文大赛 |「码」上数据库—— KWDB 2025 创作者计划启动
KaiwuDB
480次阅读
2025-04-01 20:42:12
数据库,没有关税却有壁垒
多明戈教你玩狼人杀
449次阅读
2025-04-11 09:38:42
国产数据库需要扩大场景覆盖面才能在竞争中更有优势
白鳝的洞穴
430次阅读
2025-04-14 09:40:20
最近我为什么不写评论国产数据库的文章了
白鳝的洞穴
356次阅读
2025-04-07 09:44:54
天津市政府数据库框采结果公布!
通讯员
334次阅读
2025-04-10 12:32:35
【活动】分享你的压箱底干货文档,三篇解锁进阶奖励!
墨天轮编辑部
286次阅读
2025-04-17 17:02:24
优炫数据库成功入围新疆维吾尔自治区行政事业单位数据库2025年框架协议采购!
优炫软件
285次阅读
2025-04-18 10:01:22