原文地址,转载请注明出处: https://blog.csdn.net/qq_34021712/article/details/82285979 ©王赛超
之前测试的时候,我们可以发现单点登录,默认是只返回登录的用户名,不会返回用户其他的信息,假如我们还需要用户的id,手机号之类的信息怎么办? 可以修改cas服务端,返回更多的信息给客户端。
https://apereo.github.io/cas/development/integration/Attribute-Release-Policies.html
比如:客户端A需要姓名和身份证号,客户端B需要昵称和头像这些公开信息,具体规则有如下:
● Return All (所有配置返回的都返回)
● Deny All (配置拒绝的出现则报错)
● Return Allowed(只返回允许的主要属性)
● 自定义Filter(自定义过滤策略)
常用为Return All
、Return Allowed
还记得前面自定义handler处理的时候,在验证成功后,返回的结果,具体代码如下:
只是将用户名放进去了,点进去看看底层代码,不出所料,有一个两个参数的重载方法,如下:
只需要将返回的信息,放入一个map中,return回去就可以了。
关于自定义验证,参考前面的博客,之前已经说过了,自定义验证很重要。
这里演示Return All、Return Allowed 两种情况,
客户端1配置返回所有信息
{
"@class" : "org.apereo.cas.services.RegexRegisteredService",
"serviceId" : "^(https|imaps|http)://app1.cas.com.*",
"name" : "测试客户端app1",
"id" : 1000,
"description" : "这是app1的客户端",
"evaluationOrder" : 10,
"theme" : "app1",
"attributeReleasePolicy" : {
"@class" : "org.apereo.cas.services.ReturnAllAttributeReleasePolicy"
}
}
客户端2配置返回姓名和身份证号
{
"@class" : "org.apereo.cas.services.RegexRegisteredService",
"serviceId" : "^(https|imaps|http)://app2.cas.com.*",
"name" : "测试客户端app2",
"id" : 1001,
"description" : "这是app2的客户端",
"evaluationOrder" : 11,
"theme" : "app2",
"attributeReleasePolicy" : {
"@class" : "org.apereo.cas.services.ReturnAllowedAttributeReleasePolicy"
"allowedAttributes" : [ "java.util.ArrayList", [ "name", "id_card_num" ] ]
}
}
package com.wangsaichao.cas.adaptors.generic;
import com.wangsaichao.cas.exception.CaptchaErrorException;
import com.wangsaichao.cas.exception.MyAccountNotFoundException;
import com.wangsaichao.cas.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apereo.cas.authentication.AuthenticationHandlerExecutionResult;
import org.apereo.cas.authentication.Credential;
import org.apereo.cas.authentication.PreventedException;
import org.apereo.cas.authentication.handler.support.AbstractPreAndPostProcessingAuthenticationHandler;
import org.apereo.cas.authentication.principal.PrincipalFactory;
import org.apereo.cas.services.ServicesManager;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.security.auth.login.AccountLockedException;
import javax.security.auth.login.CredentialExpiredException;
import javax.security.auth.login.FailedLoginException;
import java.security.GeneralSecurityException;
import java.util.Map;
/**
* @author: wangsaichao
* @date: 2018/8/31
* @description:
*/
public class RememberMeUsernamePasswordCaptchaAuthenticationHandler extends AbstractPreAndPostProcessingAuthenticationHandler {
private UserService userService;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public RememberMeUsernamePasswordCaptchaAuthenticationHandler(String name, ServicesManager servicesManager, PrincipalFactory principalFactory, Integer order) {
super(name, servicesManager, principalFactory, order);
}
@Override
protected AuthenticationHandlerExecutionResult doAuthentication(Credential credential) throws GeneralSecurityException, PreventedException {
RememberMeUsernamePasswordCaptchaCredential myCredential = (RememberMeUsernamePasswordCaptchaCredential) credential;
String requestCaptcha = myCredential.getCaptcha();
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
Object attribute = attributes.getRequest().getSession().getAttribute("captcha");
String realCaptcha = attribute == null ? null : attribute.toString();
if(StringUtils.isBlank(requestCaptcha) || !requestCaptcha.toUpperCase().equals(realCaptcha)){
throw new CaptchaErrorException("验证码错误");
}
String username = myCredential.getUsername();
Map user = userService.findByUserName(username);
if(user == null){
throw new MyAccountNotFoundException("用户不存在");
}
//可以在这里直接对用户名校验,或者调用 CredentialsMatcher 校验
if (!user.get("password").equals(myCredential.getPassword())) {
throw new CredentialExpiredException("用户名或密码错误!");
}
//这里将 密码对比 注销掉,否则 无法锁定 要将密码对比 交给 密码比较器 在这里可以添加自己的密码比较器等
//if (!password.equals(user.getPassword())) {
// throw new IncorrectCredentialsException("用户名或密码错误!");
//}
if ("1".equals(user.get("state"))) {
throw new AccountLockedException("账号已被锁定,请联系管理员!");
}
return createHandlerResult(credential, this.principalFactory.createPrincipal(username,user));
}
@Override
public boolean supports(Credential credential) {
return credential instanceof RememberMeUsernamePasswordCaptchaCredential;
}
}
上面的情况是写在json文件中的,还记得我们前面讲过动态注册service,动态注册service的信息是在代码中生成和json文件相似的信息存入到数据库中,假如是动态注册service的情况该怎么办呢?其实前面的代码中也有写,具体代码如下: