玩过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);}@Overrideprotected 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());} }}@Overridepublic boolean supports(Credential credential) {return credential instanceof UserPwdCredential;}
}
这里代码其实很简单就是把用户信息查询出来然后全部都返回了, 但是有一个问题, 注意看线面重写的一个方法, 他返回的是一个boole类型的数据, 这就是它的策略模式, 这里的问题涉及到请求信息, 目前这篇文章还不涉及, 这个将在后续文章中继续研究