简体   繁体   English

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

[英]Use Keycloak and JWT Statelessly in Spring Boot

I need to use Keycloak and prefer to use stateless JWT tokens with my Spring Boot application.我需要使用 Keycloak,并且更喜欢在我的 Spring 引导应用程序中使用无状态 JWT 令牌。 I can get it to run OK with sessions, but when converting this I need help我可以让它在会话中正常运行,但是在转换它时我需要帮助

  • Forcing Spring Boot Security to check for logins强制 Spring 引导安全检查登录
  • Allow a /logout URL (that goes to Keycloak)允许 /logout URL(进入 Keycloak)

My code "runs", but when I hit the initial page, I'm seeing log messages that seem to suggest it did not detect any sign of being logged in. When this happens, I'd like to force Spring Boot to redirect to the login page just like it would have had this been a stateful application.我的代码“运行”,但是当我点击初始页面时,我看到的日志消息似乎表明它没有检测到任何登录迹象。发生这种情况时,我想强制 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
    

Here's my HttpSecurity snippet:这是我的 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();

    }

I know I'm missing something, but I thought Keycloak provided a lot of these things OOTB.我知道我遗漏了一些东西,但我认为 Keycloak 提供了很多这样的东西 OOTB。 The initial URL is /.初始 URL 是 /。 I had hoped the.authenticated() would force it to authenticate against all patterns not permitted, but I'm likely wrong.我曾希望 the.authenticated() 会强制它针对所有不允许的模式进行身份验证,但我可能错了。 What am I missing?我错过了什么?

Please note, the internet is awash with examples of Spring Boot + Keycloak (a few are even good).请注意,互联网上充斥着 Spring Boot + Keycloak 的示例(有些甚至还不错)。 It also has a lot of Spring Boot + OAuth + Stateless JWT.它还有很多 Spring Boot + OAuth + Stateless JWT。 It does not have (that I can tell) a lot of Spring Boot + Keycloak + Stateless JWT.它没有(我可以说)很多 Spring Boot + Keycloak + Stateless JWT。 I got the little that I could find from this JHipster repo, but I feel like I'm missing some grand magical step.我从这个 JHipster repo 中得到了一点我可以找到的东西,但我觉得我错过了一些伟大的神奇步骤。

You will need spring-security and keycloak-adapters This guid has full explanation how to setup and secure it您将需要 spring-security 和 keycloak-adapters 这个指南有完整的解释如何设置和保护它

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

Resource-server should return 401 (unauthorized) when authentication is missing or invalid (expired, wrong issuer, etc.) and client should handle redirection to authorization-server .当身份验证丢失或无效(过期、错误的颁发者等)时,资源服务器应返回 401(未经授权),并且客户端应处理重定向到授权服务器

Things get messy when you try to merge different OAuth2 actors (client, resource-server and authorization-server) into a single application.当您尝试将不同的 OAuth2 参与者(客户端、资源服务器和授权服务器)合并到单个应用程序中时,事情会变得一团糟。

Are you sure you want a Spring client (and not an Angular / React / Vue / Flutter / whatever client-side rendering framework)?你确定你想要一个 Spring客户端(而不是 Angular / React / Vue / Flutter / 任何客户端渲染框架)?

If yes, maybe should you start by splitting client (presenting login, logout and Thymeleaf or whatever pages) and resource-server (REST API) apps.如果是,也许您应该首先拆分客户端(显示登录、注销和 Thymeleaf 或任何页面)和资源服务器(REST API)应用程序。 You'll better understand spring-security conf you write (and can assert it works as expected individually).您将更好地理解您编写的 spring-security conf(并且可以断言它单独按预期工作)。

Resource-server configuration (REST API)资源服务器配置 (REST API)

Be aware that Keycloak adapters for spring are deprecated .请注意,不推荐使用 spring 的 Keycloak 适配器

Easiest solution is here (support multi-tenancy, stateless by default, CORS configuration from properties, easy Keycloak roles mapping to Spring authorities and more).最简单的解决方案在这里(支持多租户,默认情况下无状态,CORS 从属性配置,简单的 Keycloak 角色映射到 Spring 权限等等)。

You can also work directly with spring-boot-starter-oauth2-resource-server , but it requires more java conf .您也可以直接使用spring-boot-starter-oauth2-resource-server ,但它需要更多 java conf

Client configuration (pages including login & logout)客户端配置(包括登录和注销的页面)

  • if keeping Spring, refer to spring-boot documentation: it's clear and always up to date (as opposed to most tutorials)如果保留 Spring,请参阅 spring-boot 文档:它很清楚并且始终是最新的(与大多数教程相反)
  • if using a "modern" client-side framework, find a lib from certified list如果使用“现代”客户端框架,请从认证列表中找到一个库

I have a complete sample (Ionic-Angular UI with spring RESTful API) there , but it might be a little complicated as starter.我有一个完整的示例(带有 spring RESTful API 的 Ionic-Angular UI) 但作为初学者可能有点复杂。

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

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