项目场景:
使用CAS5实现单点登录,同时需要集成其他OAuth认证方式。对外提供OAuth2.0和OIDC服务,支持Client_ID及secret的动态管理,同时与业务系统进行关联。
问题描述
# 默认值false,设定true后,下面的principalAttributeId=email将作为类似主键替代ID
cas.authn.pac4j.typedIdUsed=true
#appid
cas.authn.pac4j.oauth2[0].id=
#分配秘钥
cas.authn.pac4j.oauth2[0].secret=
#授权接口
cas.authn.pac4j.oauth2[0].authUrl=
#token获取接口
cas.authn.pac4j.oauth2[0].tokenUrl=
#用户信息接口
cas.authn.pac4j.oauth2[0].profileUrl=
#返回ID的字段
cas.authn.pac4j.oauth2[0].profileAttrs.id=preferred_username
#自定义委托认证名称
cas.authn.pac4j.oauth2[0].clientName=Group4A
cas.authn.pac4j.oauth2[0].profileVerb=POST
cas.authn.pac4j.oauth2[0].usePathBasedCallbackUrl=false
#
cas.authn.pac4j.oauth2[0].principalAttributeId=id
只有typedIdUsed 设置为false,才可以正常使用。又因为返回的ID加了类名,故修改源代码:
AbstractPac4jAuthenticationHandler.java
private String typePrincipalId(final String id, final UserProfile profile) {
/* if (isTypedIdUsed) {
return profile.getClass().getName() + UserProfile.SEPARATOR + id;
}*/
return id;
}
同时修改:
解决方案:
credentials.setTypedIdUsed(isTypedIdUsed);
int n = id.indexOf( UserProfile.SEPARATOR);
LOGGER.warn(" id=[{}] ",id);
if(n>0) {
if (profile.getAttributes() != null && profile.getAttributes().size() > 0) {
String tmp = (String) profile.getAttributes().get("id");
LOGGER.warn(" tmp= [{}]",tmp);
if (StringUtils.isNotBlank(tmp))
id = tmp;
}
else {
id = id.substring(n+1);
}
}
LOGGER.warn("after, id= [{}]",id);