繁体   English   中英

在 Spring 引导中无状态地使用 Keycloak 和 JWT

[英]Use Keycloak and JWT Statelessly in Spring Boot

我需要使用 Keycloak,并且更喜欢在我的 Spring 引导应用程序中使用无状态 JWT 令牌。 我可以让它在会话中正常运行,但是在转换它时我需要帮助

  • 强制 Spring 引导安全检查登录
  • 允许 /logout URL(进入 Keycloak)

我的代码“运行”,但是当我点击初始页面时,我看到的日志消息似乎表明它没有检测到任何登录迹象。发生这种情况时,我想强制 Spring Boot 重定向到登录页面就像这是一个有状态的应用程序一样。

org.springframework.web.servlet.FrameworkServlet: Failed to complete request: java.lang.NullPointerException: Cannot invoke "org.springframework.security.authentication.AbstractAuthenticationToken.getName()" because "authenticationToken" is null
org.springframework.security.web.context.HttpSessionSecurityContextRepository$SaveToSessionResponseWrapper: Did not store anonymous SecurityContext
org.springframework.security.web.context.SecurityContextPersistenceFilter: Cleared SecurityContextHolder to complete request
org.apache.juli.logging.DirectJDKLog: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException: Cannot invoke "org.springframework.security.authentication.AbstractAuthenticationToken.getName()" because "authenticationToken" is null] with root cause
java.lang.NullPointerException: Cannot invoke "org.springframework.security.authentication.AbstractAuthenticationToken.getName()" because "authenticationToken" is null
    

这是我的 HttpSecurity 片段:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http
        .csrf()
//      .disable().exceptionHandling().accessDeniedPage("/access-denied")
        .and()
        .authorizeRequests()
        .antMatchers("/sso/**").permitAll()
        .antMatchers("/error/**").permitAll()
        .antMatchers("/css/**","/contact-us","/actuator/**","/isalive/**").permitAll()
        .anyRequest().authenticated()
        .and()
        .oauth2Login()
        .defaultSuccessUrl("/myfirstpage",true)
        .and().exceptionHandling().authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
        .and()
        .oauth2ResourceServer().jwt();

    }

我知道我遗漏了一些东西,但我认为 Keycloak 提供了很多这样的东西 OOTB。 初始 URL 是 /。 我曾希望 the.authenticated() 会强制它针对所有不允许的模式进行身份验证,但我可能错了。 我错过了什么?

请注意,互联网上充斥着 Spring Boot + Keycloak 的示例(有些甚至还不错)。 它还有很多 Spring Boot + OAuth + Stateless JWT。 它没有(我可以说)很多 Spring Boot + Keycloak + Stateless JWT。 我从这个 JHipster repo 中得到了一点我可以找到的东西,但我觉得我错过了一些伟大的神奇步骤。

您将需要 spring-security 和 keycloak-adapters 这个指南有完整的解释如何设置和保护它

https://keepgrowth.in/java/springboot/keycloak-with-spring-boot-1-configure-spring-security-with-keycloak/

当身份验证丢失或无效(过期、错误的颁发者等)时,资源服务器应返回 401(未经授权),并且客户端应处理重定向到授权服务器

当您尝试将不同的 OAuth2 参与者(客户端、资源服务器和授权服务器)合并到单个应用程序中时,事情会变得一团糟。

你确定你想要一个 Spring客户端(而不是 Angular / React / Vue / Flutter / 任何客户端渲染框架)?

如果是,也许您应该首先拆分客户端(显示登录、注销和 Thymeleaf 或任何页面)和资源服务器(REST API)应用程序。 您将更好地理解您编写的 spring-security conf(并且可以断言它单独按预期工作)。

资源服务器配置 (REST API)

请注意,不推荐使用 spring 的 Keycloak 适配器

最简单的解决方案在这里(支持多租户,默认情况下无状态,CORS 从属性配置,简单的 Keycloak 角色映射到 Spring 权限等等)。

您也可以直接使用spring-boot-starter-oauth2-resource-server ,但它需要更多 java conf

客户端配置(包括登录和注销的页面)

  • 如果保留 Spring,请参阅 spring-boot 文档:它很清楚并且始终是最新的(与大多数教程相反)
  • 如果使用“现代”客户端框架,请从认证列表中找到一个库

我有一个完整的示例(带有 spring RESTful API 的 Ionic-Angular UI) 但作为初学者可能有点复杂。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM