Как извлечь информацию из входящего JWT, созданного внешней службой?( Okta )
Мне нужно выполнить поиск в базе данных пользовательской информации на основе одного из полей в JWT.(Мне также нужна защита на уровне метода, основанная на области действия JWT.)
Секрет заключается в использовании от AccessTokenConverter
до extractAuthentication()
, а затем использовать его для поиска UserDetails
.Я застрял, потому что каждый пример, который я могу найти, включает в себя настройку сервера авторизации, которого у меня нет, и я не могу сказать, будет ли JwtAccessTokenConverter
работать на сервере ресурсов.
Мой сервер ресурсовзапускает и обрабатывает запросы, но мой пользовательский JwtAccessTokenConverter
никогда не вызывается во время входящих запросов;Все мои запросы приходят с принципалом anonymousUser.
Я использую Spring 5.1.1.
Моя конфигурация сервера ресурсов
@Configuration
@EnableResourceServer
public class OauthResourceConfig extends ResourceServerConfigurerAdapter {
@Value("${oauth2.audience}")
String audience;
@Value("${oauth2.baseUrl}/v1/keys")
String jwksUrl;
@Override
public void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.authorizeRequests()
.anyRequest().authenticated()
.antMatchers("/api/**").permitAll();
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources
.tokenServices(tokenServices())
.resourceId(audience);
}
@Primary
@Bean
public DefaultTokenServices tokenServices() throws Exception {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenStore(tokenStore());
return tokenServices;
}
@Bean
public TokenStore tokenStore() {
return new JwkTokenStore(jwksUrl, accessTokenConverter());
}
@Bean
public AccessTokenConverter accessTokenConverter() {
return new CustomJwtAccessTokenConverter();
}
}
Мой токен пользовательского доступаКонвертер
public class CustomJwtAccessTokenConverter extends JwtAccessTokenConverter {
@Override
public OAuth2Authentication extractAuthentication(Map<String, ?> map) {
OAuth2Authentication authentication = super.extractAuthentication(map);
Authentication userAuthentication = authentication.getUserAuthentication();
if (userAuthentication != null) {
LinkedHashMap userDetails = (LinkedHashMap) map.get("userDetails");
if (userDetails != null) {
... Do the database lookup here ...
Collection<? extends GrantedAuthority> authorities = userAuthentication.getAuthorities();
userAuthentication = new UsernamePasswordAuthenticationToken(extendedPrincipal,
userAuthentication.getCredentials(), authorities);
}
}
return new OAuth2Authentication(authentication.getOAuth2Request(), userAuthentication);
}
}
И мой ресурс
@GET
@PreAuthorize("#oauth2.hasScope('openid')")
public Response getRecallsByVin(@QueryParam("vin") String vin,
@QueryParam("page") Integer pageNumber,
@QueryParam("pageSize") Integer pageSize) {
List<VehicleNhtsaCampaign> nhtsaCampaignList;
List<OpenRecallsDto> nhtsaCampaignDtoList;
SecurityContext securityContext = SecurityContextHolder.getContext();
Object principal = securityContext.getAuthentication().getPrincipal();
... More irrelevant code follows ...
Прежде всего, аннотация @PreAuthorize
ничего не делает.Если я изменю его на @PreAuthorize("#oauth2.hasScope('FooBar')")
, он все равно пропустит запрос.
Во-вторых, мне нужно извлечь другую информацию из JWT, чтобы я мог выполнить поиск пользователя в моей базе данных.Я думал, что, добавив accessTokenConverter()
в конфигурацию сервера ресурсов, JWT будет проанализирован и помещен в ответ securityContext.getAuthentication()
.Вместо этого все, что я получаю, это «anonymousUser».
ОБНОВЛЕНИЕ: позже я узнал, что мне нужны данные, поступающие в пользовательский заголовок, поэтому мне не нужно ничего извлекать из JWT.Я так и не смог подтвердить ни один из предложенных ответов.