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
相关产品推荐
相关产品推荐

