gpt4 book ai didi

Spring Webflux OAuth 2 资源服务器

转载 作者:行者123 更新时间:2023-12-04 00:29:28 25 4
gpt4 key购买 nike

我有一个基于 Spring Boot 1.5 (Spring Security v4) 的 Spring OAuth 2 服务器,它生成自定义 token 和一些与此授权服务器通信的资源服务器,使用 /oauth/check_token通过配置 RemoteTokenServices 端点。所有与在授权服务器端存储/检索 token 相关的逻辑都是使用 JdbcTokenStore 完成的。

我正在构建一个新的 Spring Boot 2 应用程序,该应用程序是使用 Spring webflux 模块构建的,并尝试使用 Spring Security 5.1.1 通过现有授权服务器实现 client_credentials 流。我发现在 5.1.0.RC1 ( https://spring.io/blog/2018/08/21/spring-security-5-1-0-rc1-released#oauth2-resource-servers ) 中添加了对资源服务器的支持,并在 5.1.0.RC2 ( https://spring.io/blog/2018/09/10/spring-security-5-1-0-rc2-released#oauth2-resource-server ) 中进行了更新,但看起来只能使用 JWT 支持来配置它。

我可能在这里弄乱了概念,但正在寻找更多信息以及一种将所有这些组件配置在一起的方法。

最佳答案

我的情况和你一样。我用下一个方法解决这个问题,也许它可以帮助你:

spring-boot-starter-parent.version:2.1.1

spring-cloud-dependencies.version:Greenwich.R1

安全配置:

@EnableWebFluxSecurity
public class SecurityConfig {

@Autowired
private ReactiveAuthenticationManager manager; //custom implementation

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
return http
.authorizeExchange()
.pathMatchers("/role").hasRole("ADMIN")
.pathMatchers("/test").access(new HasScope("server")) //custom implementation
.anyExchange().authenticated()
.and()
.httpBasic().disable()
.oauth2ResourceServer()
.jwt()
.authenticationManager(manager)
.and().and()
.build();
}
}

ReactiveAuthorizationManager (HasScope) 实现:允许在身份验证对象中搜索范围的助手

public class HasScope implements ReactiveAuthorizationManager<AuthorizationContext> {

public HasScope(String...scopes) {
this.scopes = Arrays.asList(scopes);
}

private final Collection<String> scopes;

@Override
public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, AuthorizationContext object) {
return authentication
.flatMap(it -> {
OAuth2Authentication auth = (OAuth2Authentication) it;
Set<String> requestScopes = auth.getOAuth2Request().getScope();
boolean allow = requestScopes.containsAll(scopes);
return Mono.just(new AuthorizationDecision(allow));
});
}
}

ReactiveAuthenticationManager 实现:

这是配置中创建OAuth2Authentication的主要组件。错误access_token的响应有问题,它只返回状态码而没有正文响应。

@Component
public class ReactiveAuthenticationManagerImpl implements ReactiveAuthenticationManager {

private final ResourceServerProperties sso;
private final WebClient.Builder webClient;
private final ObjectMapper objectMapper;
private AuthoritiesExtractor authoritiesExtractor = new FixedAuthoritiesExtractor();

public ReactiveAuthenticationManagerImpl(ResourceServerProperties sso,
@Qualifier("loadBalancedWebClient") WebClient.Builder webClient, ObjectMapper objectMapper) {
this.sso = sso;
this.webClient = webClient;
this.objectMapper = objectMapper;
}

@Override
public Mono<Authentication> authenticate(Authentication authentication) {
return Mono.just(authentication)
.cast(BearerTokenAuthenticationToken.class)
.flatMap(it -> getMap(it.getToken()))
.flatMap(result -> Mono.just(extractAuthentication(result)));
}

private OAuth2Authentication extractAuthentication(Map<String, Object> map) {
Object principal = getPrincipal(map);
OAuth2Request request = getRequest(map);
List<GrantedAuthority> authorities = authoritiesExtractor.extractAuthorities(map);
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(principal, "N/A", authorities);
token.setDetails(map);
return new OAuth2Authentication(request, token);
}

private Object getPrincipal(Map<String, Object> map) {
if (map.containsKey("principal")) {
try {
//that is the case for user authentication
return objectMapper.convertValue(map.get("principal"), UserPrincipal.class);
} catch (IllegalArgumentException ex) {
//that is the case for client authentication
return objectMapper.convertValue(map.get("principal"), String.class);
}
}
return null;
}

@SuppressWarnings({"unchecked"})
private OAuth2Request getRequest(Map<String, Object> map) {
Map<String, Object> request = (Map<String, Object>) map.get("oauth2Request");

String clientId = (String) request.get("clientId");
Set<String> scope = new LinkedHashSet<>(request.containsKey("scope") ?
(Collection<String>) request.get("scope") : Collections.emptySet());

return new OAuth2Request(null, clientId, null, true, new HashSet<>(scope),
null, null, null, null);
}

private Mono<Map<String, Object>> getMap(String accessToken) {
String uri = sso.getUserInfoUri();
return webClient.build().get()
.uri(uri)
.accept(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer " + accessToken)
.exchange()
.flatMap(it -> it.bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {}))
.onErrorMap(InvalidTokenException.class, mapper -> new InvalidTokenException("Invalid token: " + accessToken));
}

关于Spring Webflux OAuth 2 资源服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53509457/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com