Автор оригинала: Eugen Paraschiv.
1. Обзор
В этом уроке мы обсудим, как заставить нашу реализацию Spring Security OAuth2 использовать веб-токены JSON.
Мы также продолжаем развивать предыдущую статью в этой серии OAuth.
Прежде чем мы начнем – одно важное замечание. Имейте в виду, что команда Spring Security core находится в процессе внедрения нового стека OAuth2 – некоторые аспекты уже разработаны, а некоторые все еще находятся в процессе разработки.
Для версии этой статьи, использующей новый стек Spring Security 5, ознакомьтесь с нашей статьей, использующей JWT с Spring Security OAuth .
Хорошо, давайте сразу перейдем к делу.
2. Конфигурация Maven
Во-первых, нам нужно добавить spring-security-jwt зависимость к вашему pom.xml :
org.springframework.security spring-security-jwt
Обратите внимание, что нам нужно добавить spring-security-jwt зависимость как для Сервера авторизации, так и для Сервера ресурсов.
3. Сервер авторизации
Затем мы настроим наш сервер авторизации для использования JwtTokenStore – следующим образом:
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.tokenStore(tokenStore())
.accessTokenConverter(accessTokenConverter())
.authenticationManager(authenticationManager);
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("123");
return converter;
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
}Обратите внимание, что мы использовали симметричный ключ в нашем JwtAccessTokenConverter для подписи наших токенов, что означает, что нам нужно будет использовать тот же самый точный ключ и для сервера ресурсов.
4. Сервер ресурсов
Теперь давайте взглянем на конфигурацию нашего Сервера ресурсов, которая очень похожа на конфигурацию Сервера авторизации:
@Configuration
@EnableResourceServer
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer config) {
config.tokenServices(tokenServices());
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("123");
return converter;
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
return defaultTokenServices;
}
}Имейте в виду, что мы определяем эти два сервера как совершенно отдельные и независимо развертываемые. Вот почему нам нужно снова объявить некоторые из тех же компонентов здесь, в новой конфигурации.
5. Пользовательские утверждения в токене
Теперь давайте настроим некоторую инфраструктуру, чтобы иметь возможность добавлять несколько пользовательских утверждений в маркер доступа . Стандартные утверждения, предоставляемые фреймворком, все хороши и хороши, но в большинстве случаев нам понадобится дополнительная информация в токене для использования на стороне клиента.
Мы определим TokenEnhancer для настройки нашего токена доступа с помощью этих дополнительных утверждений.
В следующем примере мы добавим дополнительное поле ” organization ” к нашему маркеру доступа – с помощью этого CustomTokenEnhancer :
public class CustomTokenEnhancer implements TokenEnhancer {
@Override
public OAuth2AccessToken enhance(
OAuth2AccessToken accessToken,
OAuth2Authentication authentication) {
Map additionalInfo = new HashMap<>();
additionalInfo.put(
"organization", authentication.getName() + randomAlphabetic(4));
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(
additionalInfo);
return accessToken;
}
} Затем мы подключим это к нашему Серверу авторизации конфигурации – следующим образом:
@Override
public void configure(
AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(
Arrays.asList(tokenEnhancer(), accessTokenConverter()));
endpoints.tokenStore(tokenStore())
.tokenEnhancer(tokenEnhancerChain)
.authenticationManager(authenticationManager);
}
@Bean
public TokenEnhancer tokenEnhancer() {
return new CustomTokenEnhancer();
}С этой новой конфигурацией и запущенной – вот как будет выглядеть полезная нагрузка токена токена:
{
"user_name": "john",
"scope": [
"foo",
"read",
"write"
],
"organization": "johnIiCh",
"exp": 1458126622,
"authorities": [
"ROLE_USER"
],
"jti": "e0ad1ef3-a8a5-4eef-998d-00b26bc2c53f",
"client_id": "fooClientIdPassword"
}5.1. Используйте Маркер доступа в Клиенте JS
Наконец, мы хотим использовать информацию о токенах в нашем клиентском приложении Angularjs. Для этого мы будем использовать библиотеку angular-jwt .
Итак, что мы собираемся сделать, так это использовать утверждение ” организация ” в вашем index.html :