Spring OAuth2和JWT身份验证信息

时间:2016-02-02 03:48:04

标签: spring-mvc spring-security spring-boot jwt spring-oauth2

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

SecurityContext sc = SecurityContextHolder.getContext();
Authentication a = sc.getAuthentication(); //OR OAuth2Authentication oa = (OAuth2Authentication)a;
Object p = a.getPrincipal();
如果我将IDP放在令牌中,

和p将保存client_id的名称。

isClientOnly()返回true。为什么呢?

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

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

Spring Boot很棒,你怎么能这么做才能让一些东西跑起来,但与此同时,我不知道从哪里开始,或者在第一次开始时甚至是什么地方...

我的application.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();
}

2 个答案:

答案 0 :(得分: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可以给出更详细的解释:)

答案 1 :(得分:0)

令牌存储部分让我分道扬..似乎我的问题在于我使用Keycloak并返回openid连接令牌,其中字段名称大多不同。我对某些字段进行了硬编码,例如' user_name'在Keycloak令牌中,突然之间可以获得一个主要对象,尽管其中没有太多信息。

所以我错误地认为Spring的OAuth2 JWT会自动与任何JWT合作。开始使用keycloak适配器。