CAS 5.3.X授权第三方(码云)登录

针对单点登录的配置,可以看我上一篇:CAS 5.3.x 单点登录https://blog.csdn.net/Coder_Knight/article/details/120720018

Cas作为国外的 项目,所有集成了外网的很多第三方,github 、goole 等,但是国内的第三方需要自己去配置,Cas也确实提供了配置,下面就去实现该功能吧

# cas.authn.pac4j.oauth2[0].authUrl=
# cas.authn.pac4j.oauth2[0].tokenUrl=
# cas.authn.pac4j.oauth2[0].profileUrl=
# cas.authn.pac4j.oauth2[0].profilePath=
# cas.authn.pac4j.oauth2[0].profileVerb=GET|POST
# cas.authn.pac4j.oauth2[0].profileAttrs.attr1=path-to-attr-in-profile
# cas.authn.pac4j.oauth2[0].customParams.param1=value1
# cas.authn.pac4j.oauth2[0].usePathBasedCallbackUrl=false
# cas.authn.pac4j.oauth2[0].principalAttributeId=

第三方设置

如图,现在我以码云(gitee)为例,本来想用CSND的,但是找不到CSDN的配置

首先:登录码云

打开设置->第三方应用

 

 创建以后出现以下页面

Cas Server设置

添加cas-server-support-pac4j-webflow依赖

<dependency>
    <groupId>org.apereo.cas</groupId>
    <artifactId>cas-server-support-pac4j-webflow</artifactId>
    <version>${cas.version}</version>
</dependency>

设置WEB-INF/classess/application.properties的配置,

#gitee
cas.authn.pac4j.oauth2[0].id=c556cb01c02ddd50e369468284304a4a2625c3e907f8a0fbb378bb3ea375186f
cas.authn.pac4j.oauth2[0].secret=ecdac017645beb7eb38bad298067c03505453303ecb1a8aa1ebe9473676a20c1
cas.authn.pac4j.oauth2[0].clientName=gitee
cas.authn.pac4j.oauth2[0].authUrl=https://gitee.com/oauth/authorize
cas.authn.pac4j.oauth2[0].tokenUrl=https://gitee.com/oauth/token
cas.authn.pac4j.oauth2[0].profileUrl=https://gitee.com/api/v5/user
cas.authn.pac4j.oauth2[0].profileVerb=GET
cas.authn.pac4j.oauth2[0].usePathBasedCallbackUrl=false
cas.authn.pac4j.oauth2[0].principalAttributeId=id
#cas.authn.pac4j.oauth2[0].customParams.scope=user_info
#cas.authn.pac4j.oauth2[0].autoRedirect=false
#cas.authn.pac4j.oauth2[0].profilePath=#GitHubProfile#

重新启动Cas Server 

可以看到已经多了一个Gitee的连接了,点击以后出现码云的登录页面,输入你自己的用户名密码登录以后,哎,出现错误了吧。。。

无效的登录回调地址,可以看一下URL,明细路径不对呀

 原来Cas的配置文件中设置了服务地址和服务前缀,需要自定义自己的地址

在WEB-INF/classess/application.properties添加配置

#覆盖默认路径
cas.server.name=https://sso.test.com
cas.server.prefix=https://sso.test.com/cas

重启访问,这样才对

 然后,出错了。。。

其实到这里已经成功了大部分,但是就是这个小部分的错误,导致我止步不前好多天

然后通过debug发现了问题所在,虽然这里只有几句话,但是调查超级费事。。。

首先错误出现的位置在cas-server-support-pac4j-authentication这个jar包中AbstractPac4jAuthenticationHandler中的createResult方法如下

    protected AuthenticationHandlerExecutionResult createResult(final ClientCredential credentials, final UserProfile profile, final BaseClient client) throws GeneralSecurityException {
        if (profile == null) {
            throw new FailedLoginException("Authentication did not produce a user profile for: " + credentials);
        } else {
            String id = this.determinePrincipalIdFrom(profile, client);
            if (StringUtils.isBlank(id)) {
                throw new FailedLoginException("No identifier found for this user profile: " + profile);
            } else {
                credentials.setUserProfile(profile);
                credentials.setTypedIdUsed(this.isTypedIdUsed);
                Principal principal = this.principalFactory.createPrincipal(id, new LinkedHashMap(profile.getAttributes()));
                LOGGER.debug("Constructed authenticated principal [{}] based on user profile [{}]", principal, profile);
                return this.createHandlerResult(credentials, principal, new ArrayList(0));
            }
        }
    }

可以看到有一个id为空的判断,默认取值来自pac4j的UserProfile中的id,但是该熟悉的默认值来自于org.pac4j.oauth.profile.generic.GenericOAuth20ProfileDefinition的方法extractUserProfile

    @Override
    public OAuth20Profile extractUserProfile(final String body) {
        final OAuth20Profile profile = new OAuth20Profile();
        final JsonNode json = JsonHelper.getFirstNode(body, getFirstNodePath());
        if (json != null) {
            if (getProfileId() != null) {
                profile.setId(ProfileHelper.sanitizeIdentifier(profile, JsonHelper.getElement(json, getProfileId())));
            } 
            for (final String attribute : getPrimaryAttributes()) {
                convertAndAdd(profile, PROFILE_ATTRIBUTE, attribute, JsonHelper.getElement(json, attribute));
            }
            for (final String attribute : getSecondaryAttributes()) {
                convertAndAdd(profile, PROFILE_ATTRIBUTE, attribute, JsonHelper.getElement(json, attribute));
            }
            for (final Map.Entry<String, String> entry : getProfileAttributes().entrySet()) {
                final String key = entry.getKey();
                final String value = entry.getValue();
                convertAndAdd(profile, PROFILE_ATTRIBUTE, key, JsonHelper.getElement(json, value));
            }

        } else {
            raiseProfileExtractionJsonError(body);
        }
        return profile;
    }

因为pac4j需要设定属性profileId,但是CAS提供的对外熟悉不存在该字段无法直接赋值ID,以我现在使用的Gitee为例,返回用户属性中ID作为唯一性区分字段,不太好设置,其实cas提供了另外的设置方式

# 默认值false,设定true后,下面的principalAttributeId=email将作为类似主键替代ID
cas.authn.pac4j.typedIdUsed=true
#gitee
cas.authn.pac4j.oauth2[0].id=c556cb01c02ddd50e369468284304a4a2625c3e907f8a0fbb378bb3ea375186f
cas.authn.pac4j.oauth2[0].secret=ecdac017645beb7eb38bad298067c03505453303ecb1a8aa1ebe9473676a20c1
cas.authn.pac4j.oauth2[0].clientName=gitee
cas.authn.pac4j.oauth2[0].authUrl=https://gitee.com/oauth/authorize
cas.authn.pac4j.oauth2[0].tokenUrl=https://gitee.com/oauth/token
cas.authn.pac4j.oauth2[0].profileUrl=https://gitee.com/api/v5/user
cas.authn.pac4j.oauth2[0].profileVerb=GET
cas.authn.pac4j.oauth2[0].usePathBasedCallbackUrl=false
cas.authn.pac4j.oauth2[0].principalAttributeId=email
#cas.authn.pac4j.oauth2[0].profileAttrs.created_at=created_at
#cas.authn.pac4j.oauth2[0].profileAttrs.updated_at=updated_at
#cas.authn.pac4j.oauth2[0].profileAttrs.name=name
#cas.authn.pac4j.oauth2[0].customParams.scope=user_info
#cas.authn.pac4j.oauth2[0].autoRedirect=false
#cas.authn.pac4j.oauth2[0].profilePath=#GitHubProfile#

如上设置以后,重新登录

发现已经可以登录了,这算是比较简便的方式了,麻烦的方式就是自己去改源码。。。

后续如果有其他发现,继续追加 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值