Spring OAuth2 和 JWT 认证信息

Posted

技术标签:

【中文标题】Spring OAuth2 和 JWT 认证信息【英文标题】:Spring OAuth2 and JWT Authentication information 【发布时间】:2016-05-10 17:45:57 【问题描述】:

我有一个 Spring Boot (1.3.x) 应用程序充当资源服务器,我可以在 Authorization 标头中从 Keycloak 传递一个 JWT 令牌,并且可以访问某些端点。我遇到的问题是我无法获取授权对象中我的 JWT 令牌中的信息。

SecurityContext sc = SecurityContextHolder.getContext();
Authentication a = sc.getAuthentication(); //OR OAuth2Authentication oa = (OAuth2Authentication)a;
Object p = a.getPrincipal();

如果我将 IDP 放入令牌中,p 将保存 client_id 的名称。

isClientOnly() 返回真。为什么?

我希望能够获得我的用户名和授权,但没有找到。 如果我没有client_id,它实际上是空的。

我试图了解是否必须以某种方式配置有关在验证后如何处理 JWT 令牌以便正确信息进入 Authentication 对象的内容,但我完全感到困惑。我怎样才能做到这一点?

Spring Boot 非常棒,您可以做这么少的事情来运行某些东西,但与此同时,我不知道从哪里开始,甚至一开始就设置了什么......

我的应用程序.yml:

server:
  servlet-path: /*

security:
  oauth2:
    resource:
      jwt:
        keyValue:
          -----BEGIN PUBLIC KEY-----
          MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmFbcU2Q6WZwUjEBvsZP8kIiE5mmctTGq1SOrPN5U4MkaTVs/zs2cWf+fhIE4WQ+dF9xTPxrJCGkwCMMXEhReFadOvzW8S3VdKdhng/j2GUbleU1QLSOGLhXu2+ODxeToZGpXIxtJiK2wE0JI9T6UwAe9j/stp4pMUzQubkG9acA+lpA5+zaCylLHysNFlSO1cTgzTdIZpXQGu5nkmyz7xT6vq8n2qAsD5GG5JRpBAac6L10Hnvl1YbwnPfi1T+IZSq7FdSpGJmYeOiPhJF0j7qYOMcaQgOfzoQGBhXslIHZeeaBIuUM6QFgZacJsVxdQoRvMronuuacnS+bngMEVDQIDAQAB
          -----END PUBLIC KEY-----
logging:
  level:
    org:
      springframework:
        security: DEBUG

我的 SecurityConfig.java:

package com.something.me;

import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;

@Configuration
@EnableOAuth2Sso
@EnableResourceServer
public class SecurityConfig extends WebSecurityConfigurerAdapter 

    @Override
    public void configure(HttpSecurity http) throws Exception 

        //TODO add scope and role restrictions...
        http.authorizeRequests().anyRequest().authenticated();

【问题讨论】:

【参考方案1】:

你可能对这个原理感到困惑......据我所知,你可以像其他 bean 一样注入它......或者像这样在控制器操作中访问它

@Controller
class MyController 
  @RequestMapping("/greeting") 
  public Principal greeting(Principal user) 
    return user;
  

除此之外,我在您的代码中看不到任何 JwtConfiguration 以及令牌存储 bean....

你必须配置这样的东西(假设你的密钥保存在资源目录的 public.cert 中)

@Configuration
public class JwtConfiguration 
    @Autowired
    JwtAccessTokenConverter jwtAccessTokenConverter;


    @Bean
    @Qualifier("tokenStore")
    public TokenStore tokenStore() 

        System.out.println("Created JwtTokenStore");
        return new JwtTokenStore(jwtAccessTokenConverter);
    

    @Bean
    protected JwtAccessTokenConverter jwtTokenEnhancer() 
        JwtAccessTokenConverter converter =  new JwtAccessTokenConverter();
        Resource resource = new ClassPathResource("public.cert");
        String publicKey = null;
        try 
            publicKey = new String(FileCopyUtils.copyToByteArray(resource.getInputStream()));
         catch (IOException e) 
            throw new RuntimeException(e);
        
        converter.setVerifierKey(publicKey);
        return converter;
    

希望我能帮上忙。也许my article可以给出更详细的解释:)

【讨论】:

【参考方案2】:

令牌存储部分让我有所作为......看来我的问题在于我正在使用 Keycloak 并且它返回的字段名称大多不同的 openid 连接令牌。我在 Keycloak 令牌中硬编码了一些字段,如“user_name”,突然之间可以获得一个主体对象,尽管其中没有太多信息。

所以我误以为 Spring 的 OAuth2 JWT 东西会自动与任何 JWT 一起工作。开始使用 keycloak 适配器。

【讨论】:

以上是关于Spring OAuth2 和 JWT 认证信息的主要内容,如果未能解决你的问题,请参考以下文章

spring security oauth2 jwt 认证和资源分离的配置文件(java类配置版)

使用JWT的OAuth2的SSO分析

Spring Boot 2 和 OAuth2/JWT

Oauth2 + jwt 和 spring boot

基于Spring Security OAuth2搭建的Spring Cloud 认证中心

用Spring Cloud OAuth2和JWT保护微服务