java - Keycloak 错误 token 响应,当用户不具有 Offline_access 角色时 error=not_allowed

标签 java tomcat keycloak openid-connect pac4j

我们有一个在 tomcat 9 上运行的 JSF 应用程序,并且我们使用 keycloak (v10.0.2) 进行登录。

因为keycloak deprecated their tomcat-adapter我们想从 keycloak tomcat-adapter 切换到 pac4j .

所以我创建了以下配置。

import org.pac4j.core.client.Clients;
import org.pac4j.core.config.Config;
import org.pac4j.core.config.ConfigFactory;
import org.pac4j.oidc.client.KeycloakOidcClient;
import org.pac4j.oidc.config.KeycloakOidcConfiguration;

import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;

public class SecurityConfigFactory implements ConfigFactory {

  @Override
  public Config build(final Object... parameters) {
    System.out.print("Building Security configuration...\n");

    final KeycloakOidcConfiguration keycloak = new KeycloakOidcConfiguration();
    keycloak.setBaseUri("http://localhost:8180/auth");
    keycloak.setRealm("testRealm");
    keycloak.setClientId("local-test");
    keycloak.setSecret("abc-xyz");
    keycloak.setClientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
    keycloak.setLogoutUrl("http://localhost:8180/auth/realms/testRealm/protocol/openid-connect/logout");
    final KeycloakOidcClient keycloakClient = new KeycloakOidcClient(keycloak);
    keycloakClient.setName("keycloakClient");

    final String callbackUrl = "http://localhost:8080/callback";
    final Clients clients = new Clients(callbackUrl, keycloakClient/* , new AnonymousClient() */);

    final Config config = new Config(clients);
    return config;
  }

}

并将以下内容添加到我的 web.xml

<filter>
    <filter-name>callbackFilter</filter-name>
    <filter-class>org.pac4j.j2e.filter.CallbackFilter</filter-class>
    <init-param>
        <param-name>defaultUrl</param-name>
        <param-value>/</param-value>
    </init-param>
    <init-param>
        <param-name>renewSession</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>multiProfile</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>saveInSession</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>callbackFilter</filter-name>
    <url-pattern>/callback</url-pattern>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>


<filter>
    <filter-name>OidcFilter</filter-name>
    <filter-class>org.pac4j.j2e.filter.SecurityFilter</filter-class>
    <init-param>
        <param-name>configFactory</param-name>
        <param-value>abc.xyz.SecurityConfigFactory</param-value>
    </init-param>
    <init-param>
        <param-name>clients</param-name>
        <param-value>keycloakClient</param-value>
    </init-param>
    <init-param>
        <param-name>authorizers</param-name>
        <param-value>securityHeaders</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>OidcFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

所以现在我的问题是,当用户具有offline_access角色时,他可以登录keycloak。 但是,一旦我删除 offline_access 角色,如果我单击 keycloak 上的登录按钮,就会出现此异常。

2022-12-14 10:19:11,304 DEBUG [http-nio-8080-exec-10]  - authenticator.OidcAuthenticator.validate - Token response: status=400, content={"error":"not_allowed",
"error_description":"Offline tokens not allowed for the user or client"}
...
org.pac4j.core.exception.TechnicalException: Bad token response, error=not_allowed
    at org.pac4j.oidc.credentials.authenticator.OidcAuthenticator.validate(OidcAuthenticator.java:147)
    at org.pac4j.oidc.credentials.authenticator.OidcAuthenticator.validate(OidcAuthenticator.java:35)
    at org.pac4j.core.client.BaseClient.retrieveCredentials(BaseClient.java:71)
    at org.pac4j.core.client.IndirectClient.getCredentials(IndirectClient.java:140)
    at org.pac4j.core.engine.DefaultCallbackLogic.perform(DefaultCallbackLogic.java:89)
    at org.pac4j.j2e.filter.CallbackFilter.internalFilter(CallbackFilter.java:84)
    at org.pac4j.j2e.filter.AbstractConfigFilter.doFilter(AbstractConfigFilter.java:84)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

所以我认为我必须告诉配置不要使用离线 token ,或者他们明显缺少我的东西?

在 keycloak 中我看到以下事件 enter image description here

我的 Pom.xml 包括(我们使用的是 Java 8,我无法编译更新的 pac4j 版本)

   <dependency>
        <groupId>org.pac4j</groupId>
        <artifactId>j2e-pac4j</artifactId>
        <version>4.1.0</version>
    </dependency>
    <dependency>
        <groupId>org.pac4j</groupId>
        <artifactId>pac4j-oidc</artifactId>
        <version>3.9.0</version>
    </dependency>

最佳答案

在“客户端”下,导航到“客户端范围”,检查 分配的默认客户端范围中是否存在offline_access。如果存在,请将其更改为可用客户端范围这将解决此问题。

关于java - Keycloak 错误 token 响应,当用户不具有 Offline_access 角色时 error=not_allowed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74796180/

相关文章:

java - (高中Java作业帮助)英文字母转摩尔斯电码的困惑

java - NOT 表达式的正则表达式帮助

tomcat - web.xml 中的 jsp 文件在 tomcat 中不起作用

keycloak - 如何注册Keycloak密码哈希服务提供商SPI

java - 从 Spring Boot 应用程序检查密码是否在 Keycloak 中有效

java - Eclipse开普勒启动报错 "NoClassDefFoundError: org/eclipse/swt/widgets/Display"

java - Maven 程序集 : how package only imported/used dependencies for each execution

maven - 在 Tomcat 中部署 Maven 项目

tomcat - struts 中的 JMS 队列连接工厂

freemarker - Freemarker 模板中的 Keycloak 访问 cookie 和/或 url 查询参数