Я использую Keycloak в качестве сервера авторизации OAuth2, и я настроил сервер ресурсов OAuth2 для работы с несколькими арендаторами, следуя этому официальному примеру на GitHub . Текущий Арендатор разрешается с учетом поля Эмитент токена JWT . Следовательно, токен проверяется на соответствие JWKS на соответствующей OpenID Connect известной конечной точке.
Это моя конфигурация безопасности:
@EnableWebSecurity
@RequiredArgsConstructor
@EnableAutoConfiguration(exclude = UserDetailsServiceAutoConfiguration.class)
public class OrganizationSecurityConfiguration extends WebSecurityConfigurerAdapter {
private final TenantService tenantService;
private List<Tenant> tenants;
@PostConstruct
public void init() {
this.tenants = this.tenantService.findAllWithRelationships();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests().anyRequest().authenticated()
.and()
.oauth2ResourceServer()
.authenticationManagerResolver(new MultiTenantAuthenticationManagerResolver(this.tenants));
}
}
и это мой пользовательский AuthenticationManagerResolver :
public class MultiTenantAuthenticationManagerResolver implements AuthenticationManagerResolver<HttpServletRequest> {
private final AuthenticationManagerResolver<HttpServletRequest> resolver;
private List<Tenant> tenants;
public MultiTenantAuthenticationManagerResolver(List<Tenant> tenants) {
this.tenants = tenants;
List<String> trustedIssuers = this.tenants.stream()
.map(Tenant::getIssuers)
.flatMap(urls -> urls.stream().map(URL::toString))
.collect(Collectors.toList());
this.resolver = new JwtIssuerAuthenticationManagerResolver(trustedIssuers);
}
@Override
public AuthenticationManager resolve(HttpServletRequest context) {
return this.resolver.resolve(context);
}
}
Теперь, из-за дизайна org.springframework.security.oauth2.server.resource.authentication.JwtIssuerAuthenticationManagerResolver.TrustedIssuerJwtAuthenticationManagerResolver
, который является приватным , единственный способ, которым я могу думать в Чтобы извлечь пользовательский принципал, нужно переопределить все, что следует:
- TrustedIssuerJwtAuthenticationManagerResolver
- возвращенный AuthenticationManager
- AuthenticationConverter
- CustomAuthenticationToken , который расширяет JwtAuthenticationToken
- CustomPrincipal
Мне кажется, что переизобретается колесо , где моя единственная потребность - иметь собственного Принципала.
Примеры, которые я нашел, не подходят мой случай с тех пор Они ссылаются на OAuth2Client или не рассчитаны на Multitenancy.
Действительно ли мне нужно переопределить все такие классы / межфаймы или есть более разумный подход?