You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot+Pac4j集成OIDC:如何配置授权取消回调处理?

问题描述

我们的应用基于Spring Boot和Pac4j开发,已集成CAS凭证与ORCID,配置了多用户档案,包含CAS客户端和基础OidcClient(用于ORCID)。目前遇到OIDC回调报错:Bad authentication response, error=access_denied,这是用户拒绝授权导致的。我们希望参考OAuth示例中的setHasBeenCancelledFactory配置来处理该场景,需要了解如何在OIDC Client/Configuration中实现此功能。

现有配置代码

PAC4JConfig.java

public Config config() {
    final OidcConfiguration oidcConfiguration = new OidcConfiguration();
    oidcConfiguration.setClientId(orcidClientId);
    oidcConfiguration.setSecret(orcidClientSecret);
    oidcConfiguration.setUseNonce(true);
    oidcConfiguration.setDiscoveryURI(orcidDiscoveryUrl);
    oidcConfiguration.setScope(orcidClientScope);
    oidcConfiguration.setClientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST);

    final OidcClient oidcClient = new OidcClient(oidcConfiguration);
    oidcClient.setName(Constants.ORCID_CLIENT_NAME);
    oidcClient.setCallbackUrl(callbackUrl);
    oidcClient.setSaveProfileInSession(true);
    oidcClient.setMultiProfile(true);
    
    final CasConfiguration configuration = new CasConfiguration(casLoginUrl);
    final CasClient casClient = new CasClient(configuration);
    casClient.setName(Constants.CAS_CLIENT_NAME);
    casClient.setMultiProfile(true);
    
    final Clients clients = new Clients(callbackUrl, oidcClient, casClient);
    return new Config(clients);
}

OrcidConnectController.java

@RequestMapping("/orcid/forceLogin")
@ResponseBody
public void forceLogin() {
    try {
        final String name = webContext.getRequestParameter(Pac4jConstants.DEFAULT_CLIENT_NAME_PARAMETER)
                .map(String::valueOf).orElse(""); 
        final Client client = config.getClients().findClient(name).get();
        JEESessionStore.INSTANCE.set(webContext, Pac4jConstants.REQUESTED_URL, "/orcid/connect");
        JEEHttpActionAdapter.INSTANCE.adapt(client.getRedirectionAction(new CallContext(webContext, JEESessionStore.INSTANCE)).get(), webContext);
    } catch (final HttpAction e) {
        log.error("Forcelogin error :{}", e.getMessage());
    }
}
解决方案

由于OidcConfiguration继承自OAuthConfiguration,你可以直接使用setHasBeenCancelledFactory方法配置用户拒绝授权后的处理逻辑。该工厂会在回调检测到access_denied错误时触发,可自定义重定向或返回提示信息。

修改后的OIDC配置示例

在PAC4JConfig.java的config()方法中,为OidcConfiguration添加setHasBeenCancelledFactory配置:

public Config config() {
    final OidcConfiguration oidcConfiguration = new OidcConfiguration();
    oidcConfiguration.setClientId(orcidClientId);
    oidcConfiguration.setSecret(orcidClientSecret);
    oidcConfiguration.setUseNonce(true);
    oidcConfiguration.setDiscoveryURI(orcidDiscoveryUrl);
    oidcConfiguration.setScope(orcidClientScope);
    oidcConfiguration.setClientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST);

    // 配置用户拒绝授权的处理逻辑
    oidcConfiguration.setHasBeenCancelledFactory(context -> {
        // 自定义处理:重定向到授权拒绝提示页面
        return RedirectAction.redirect("/orcid/auth-denied");
    });

    final OidcClient oidcClient = new OidcClient(oidcConfiguration);
    oidcClient.setName(Constants.ORCID_CLIENT_NAME);
    oidcClient.setCallbackUrl(callbackUrl);
    oidcClient.setSaveProfileInSession(true);
    oidcClient.setMultiProfile(true);
    
    final CasConfiguration configuration = new CasConfiguration(casLoginUrl);
    final CasClient casClient = new CasClient(configuration);
    casClient.setName(Constants.CAS_CLIENT_NAME);
    casClient.setMultiProfile(true);
    
    final Clients clients = new Clients(callbackUrl, oidcClient, casClient);
    return new Config(clients);
}

补充说明

  • hasBeenCancelledFactory接收WebContext参数,可根据上下文获取请求信息,灵活定制处理逻辑。
  • 示例中返回重定向到/orcid/auth-denied的动作,你可替换为自身的提示页面路径,或返回JSON提示信息(需配合对应HttpActionAdapter)。
  • 该配置仅作用于OIDC客户端,不影响CAS客户端的认证流程。

内容的提问来源于stack exchange,提问作者Vanya Kojuharova

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 01:42:43