登录后带有 Spring 'Invalid credentials' 的 Keycloak

Posted

技术标签:

【中文标题】登录后带有 Spring \'Invalid credentials\' 的 Keycloak【英文标题】:Keycloak with Spring 'Invalid credentials' after login登录后带有 Spring 'Invalid credentials' 的 Keycloak 【发布时间】:2021-07-06 21:06:12 【问题描述】:

我没有用 Keycloak 独立设置简单的 Spring 网关 + oauth2 客户端。它的密钥锁部分工作正常。 Wireshark 显示正确生成的令牌。

网关安全配置如下。我仍然不确定是否需要 permitAll() 登录回调 url。一些指南建议应该是这种情况,而另一些则不建议。我怀疑 oauth 提供者在幕后管理这部分。尽管如此,无论是否使用“/login/*”路径的 permitAll,结果都是一样的。

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig 
    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) 
        http.authorizeExchange(e -> e.anyExchange().authenticated());
        http.oauth2Login(Customizer.withDefaults());
        http.csrf().disable();
        return http.build();
    

登录后重定向到 https://localhost:9000/login 似乎不正确,它应该重试原始 url,例如 https://localhost:9000/test-service/v1/listall/


编辑

为了排除任何错误配置,甚至尝试了最简单的网关和 api 资源(未经身份验证)并在 keyclock 中设置最简单的 relam。结果没有改变:(有几十篇文章在做完全相同的事情。

有什么建议和想法吗? 非常感谢

【问题讨论】:

【参考方案1】:

根据官方文档(位于https://www.keycloak.org/docs/latest/securing_apps/#_spring_security_adapter),您应该使用

@KeycloakConfiguration 公共类 SecurityConfig 扩展 KeycloakWebSecurityConfigurerAdapter

【讨论】:

作为一个OAuth授权服务器,应该可以在没有适配器的情况下与spring集成。我不希望使用任何供应商特定的适配器。【参考方案2】:

我想通了,这是一个不正确的用户名属性。正确的值是

user-name-attribute: preferred_username

出于某种原因,我将其设置为preferred_name。如果只有 spring oauth 写入实际错误而不是通用的 invalid_grant,它将节省大量调试时间。

【讨论】:

【参考方案3】:

首先,对于任何对 Spring Security 进行故障排除的人,我建议通过在 application.properties 或 application.yml 文件中设置日志记录级别来启用调试日志记录。

application.properties 格式:

logging.level.org.springframework.security=DEBUG

application.yml 格式:

logging:
    level:
        org:
            springframework:
                security: DEBUG

我在使用 OAuth2 和 Spring Session 时遇到了类似的问题。即使在使用 Keycloak 成功进行身份验证后,只要我的 Spring Session 过期,我也会收到此登录错误。

我不容忍弄乱身份验证流程,但我能够通过在 ServerHttpSecurity 上设置自己的身份验证入口点来解决此问题:

http.exceptionHandling().authenticationEntryPoint(new RedirectServerAuthenticationEntryPoint("/oauth2/authorization/keycloak"));

然后我必须在我的控制器中处理对“/login”页面的任何请求。对我来说,我只是重定向到我的默认登录页面以获取根请求:

@Controller
@RequestMapping("/")
public class RootController 
    
    @GetMapping("", "login")
    public Mono<String> index() 
        return Mono.just("redirect:/myLandingPage");
    

【讨论】:

【参考方案4】:

即使我已经完成了所有配置,包括“创建客户端”、“创建范围”和使用此范围创建“用户”。我又遇到了这个问题。

对我有用的唯一解决方案是将 scope :openid 添加到 application.yaml

您可以从这里参考 application.yaml 安全 OAuth 配置:

 security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://$keycloak.base.url/auth/realms/$realm
      client:
        registration:
          gateway:
            provider: keycloak
            client-id: $client id
            client-secret:$client secret
            scope: openid
        provider:
          keycloak:
            user-name-attribute: preferred_username
            issuer-uri: https://$keycloak.base.url/auth/realms/$realm 

【讨论】:

以上是关于登录后带有 Spring 'Invalid credentials' 的 Keycloak的主要内容,如果未能解决你的问题,请参考以下文章

Spring security invalid-session-url 的坑(配了permitAll仍然跳转到登录页)

通过带有 Spring Boot 后端的 Google Sign-In 登录 Android

spring security 使用自定义的AuthenticationFilter,提示Invalid remember-me cookie,自动登录失败的解决方法

Grails OAuth2 登录密码凭据授予返回 invalid_client

Spring security:注销时始终重定向到 invalid-session-url

cas-client登录后报INVALID_PROXY_CALLBACK