玩过cas的小伙伴都知道CAS-Server本身是支持CAS和OAuth2.0两种协议的, 之前写过一篇使用OAuth2.0协议获取用户信息的文章,今天来介绍一下CAS协议怎么获取更多的用户信息
分析
OAuth2.0协议的用户信息是接口返回的, 因此我们修改接口的实现就可以, CAS获取用户信息都是从session中获取的, 这样我们就得想办法在用户请求登录的时候想办法把用户信息放到session中
操作步骤
引入依赖
<!-- Json Service Registry -->
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-support-json-service-registry</artifactId>
<version>${cas.version}</version>
</dependency>
<!-- Authentication Attributes -->
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-core-authentication-attributes</artifactId>
<version>${cas.version}</version>
</dependency>
修改json文件
返回所有用户信息
{
"@class" : "org.apereo.cas.services.RegexRegisteredService",
"serviceId" : "^(https|imaps|http)://test.cas.com.*",
"name" : "测试客户端app1",
"id" : 1000,
"description" : "123456",
"evaluationOrder" : 10,
"theme" : "app1",
"attributeReleasePolicy" : {
"@class" : "org.apereo.cas.services.ReturnAllAttributeReleasePolicy"
}
}
返回部分用户信息
{
"@class" : "org.apereo.cas.services.RegexRegisteredService",
"serviceId" : "^(https|imaps|http)://test.cas.com.*",
"name" : "测试客户端app2",
"id" : 1001,
"description" : "123456",
"evaluationOrder" : 11,
"theme" : "app2",
"attributeReleasePolicy" : {
"@class" : "org.apereo.cas.services.ReturnAllowedAttributeReleasePolicy"
"allowedAttributes" : [ "java.util.ArrayList", [ "name", "phone" ] ]
}
}
这里有一个下需要注意的点: servuceId这个属性一定要配置正确, 最好不要有默认匹配所有url的配置, 因为如果有那个配置得话, 默认不一定会走这个json配置, 每一个json配置文件都相当于一种实现, 他里面使用的是策略模式这样会有多个满足条件的情况, 所以会有问题
重写实现类
/**
* 自定义登录拦截器
*
* @author zzt
* @version v1.0.0
* @date 2024/7/17
*/
@Setter
public class MyAuthenticationHandler extends AbstractPreAndPostProcessingAuthenticationHandler {
private SysUserService sysUserService;
public MyAuthenticationHandler(String name,
ServicesManager servicesManager,
PrincipalFactory principalFactory,
Integer order) {
super(name, servicesManager, principalFactory, order);
}
@Override
protected AuthenticationHandlerExecutionResult doAuthentication(Credential credential) throws GeneralSecurityException, PreventedException {
//查询用户信息
SysUser sysUser = sysUserService.getBaseMapper().selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUserName, username));
if (ObjectUtils.isNotEmpty(sysUser)) {
if (StringUtils.equals(username, sysUser.getUserName()) &&
StringUtils.equals(PasswordUtil.getPassword(password, sysUser.getSalt()), sysUser.getPassword())) {
if (Objects.equals(sysUser.getPhone(), phone) && StringUtils.isNotBlank(smsVerifyCode)) {
return createHandlerResult(credential,
this.principalFactory.createPrincipal(username), Collections.emptyList());
}
}
}
@Override
public boolean supports(Credential credential) {
return credential instanceof UserPwdCredential;
}
}
这里代码其实很简单就是把用户信息查询出来然后全部都返回了, 但是有一个问题, 注意看线面重写的一个方法, 他返回的是一个boole类型的数据, 这就是它的策略模式, 这里的问题涉及到请求信息, 目前这篇文章还不涉及, 这个将在后续文章中继续研究