Spring OAuth2 和 JWT 认证信息
Spring OAuth2 and JWT Authentication information
我有一个 Spring Boot (1.3.x) 应用程序充当资源服务器,我可以在授权 header 中从 Keycloak 传递 JWT 令牌并被清除访问一些端点。我遇到的问题 运行 是我无法在授权 object 中获取我的 JWT 令牌中的信息。
SecurityContext sc = SecurityContextHolder.getContext();
Authentication a = sc.getAuthentication(); //OR OAuth2Authentication oa = (OAuth2Authentication)a;
Object p = a.getPrincipal();
和 p 将保留 client_id 的名称,如果我让 IDP 将其放入令牌中的话。
isClientOnly() returns 正确。为什么?
我希望能够获得我的用户名和资助,但 none 已找到。
如果我没有 client_id,它实际上是空的。
我试图了解我是否必须以某种方式配置一些关于 JWT 令牌在验证后如何处理的信息,以便正确的信息进入身份验证 object,但我完全感到困惑。我怎样才能做到这一点?
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();
}
您可能对原理感到困惑....据我所知,您可以像其他 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 可以给出更详细的解释:)
令牌存储部分让我分道扬镳...看来我的问题在于我正在使用 Keycloak 并且它返回字段名称大部分不同的 openid 连接令牌。我在 Keycloak 令牌中硬编码了一些字段,例如 'user_name' ,突然间可以获得一个主体对象,尽管其中没有太多信息。
所以我错误地认为 Spring 的 OAuth2 JWT 东西会自动与任何 JWT 一起工作。开始使用 keycloak 适配器。
我有一个 Spring Boot (1.3.x) 应用程序充当资源服务器,我可以在授权 header 中从 Keycloak 传递 JWT 令牌并被清除访问一些端点。我遇到的问题 运行 是我无法在授权 object 中获取我的 JWT 令牌中的信息。
SecurityContext sc = SecurityContextHolder.getContext();
Authentication a = sc.getAuthentication(); //OR OAuth2Authentication oa = (OAuth2Authentication)a;
Object p = a.getPrincipal();
和 p 将保留 client_id 的名称,如果我让 IDP 将其放入令牌中的话。
isClientOnly() returns 正确。为什么?
我希望能够获得我的用户名和资助,但 none 已找到。 如果我没有 client_id,它实际上是空的。
我试图了解我是否必须以某种方式配置一些关于 JWT 令牌在验证后如何处理的信息,以便正确的信息进入身份验证 object,但我完全感到困惑。我怎样才能做到这一点?
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();
}
您可能对原理感到困惑....据我所知,您可以像其他 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 可以给出更详细的解释:)
令牌存储部分让我分道扬镳...看来我的问题在于我正在使用 Keycloak 并且它返回字段名称大部分不同的 openid 连接令牌。我在 Keycloak 令牌中硬编码了一些字段,例如 'user_name' ,突然间可以获得一个主体对象,尽管其中没有太多信息。
所以我错误地认为 Spring 的 OAuth2 JWT 东西会自动与任何 JWT 一起工作。开始使用 keycloak 适配器。