Евгений Параскив
Перепечатано из публичного аккаунта: stackgc
1 Обзор
В этом руководстве мы обсудим интеграцию Spring Security OAuth2 с веб-токеном JSON.
Эта статья находится вПредыдущая статья из серии OAuthразработан на основе.
2. Конфигурация Maven
Во-первых, вам нужноpom.xmlдобавлено вspring-security-jwtполагаться:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
</dependency>
Обратите внимание, что нам нужно установить сервер авторизации и сервер ресурсовpom.xml
Чжунду присоединяется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;
}
}
Помните, что два сервера полностью разделены и могут быть развернуты независимо друг от друга, поэтому мы снова объявляем некоторые из тех же bean-компонентов в новой конфигурации.
5. Претензии в пользовательском токене
Затем настройте некоторую инфраструктуру, чтобы иметь возможностьAccess Tokenдобавить некоторые пользовательскиеclaims. Стандартные утверждения, предоставляемые платформой, хороши, но в большинстве случаев нам нужно добавить дополнительную информацию в токен, чтобы использовать его на стороне клиента.
мы определяемTokenEnhancerдля настройки маркера доступа и этих дополнительных утверждений.
В следующем примере мы будем использовать CustomTokenEnhancer, чтобы добавить дополнительное поле в Access Toekn.organization:
public class CustomTokenEnhancer implements TokenEnhancer {
@Override
public OAuth2AccessToken enhance(
OAuth2AccessToken accessToken,
OAuth2Authentication authentication) {
Map<String, Object> 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-клиенте
Наконец, мы будем использовать информацию о токене в клиентском приложении AngualrJS. используется здесьangular-jwtбиблиотека.
существуетindex.html
используется вorganizationтребовать:
<p class="navbar-text navbar-right">{{organization}}</p>
<script type="text/javascript"
src="https://cdn.rawgit.com/auth0/angular-jwt/master/dist/angular-jwt.js">
</script>
<script>
var app = angular.module('myApp', ["ngResource","ngRoute", "ngCookies", "angular-jwt"]);
app.controller('mainCtrl', function($scope, $cookies, jwtHelper,...) {
$scope.organiztion = "";
function getOrganization(){
var token = $cookies.get("access_token");
var payload = jwtHelper.decodeToken(token);
$scope.organization = payload.organization;
}
...
});
6. Пара асимметричных ключей
В предыдущей конфигурации мы использовали симметричный ключ для подписи токена:
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("123");
return converter;
}
Мы также можем использовать асимметричные ключи (открытые и закрытые ключи) для завершения процесса подписи.
6.1. Создание файла JKS Java KeyStore
Сначала используйте инструмент командной строки keytool для генерации ключа, особенно.jksдокумент.
keytool -genkeypair -alias mytest
-keyalg RSA
-keypass mypass
-keystore mytest.jks
-storepass mypass
Эта команда создаст файл с именемmytest.jks, который содержит наши ключи — открытый и закрытый ключи.
Также убедитесь,keypassиstorepassсогласуется.
6.2 Экспорт открытого ключа
Далее вам нужно экспортировать публичный ключ из сгенерированного JKS, вы можете использовать следующую команду:
keytool -list -rfc --keystore mytest.jks | openssl x509 -inform pem -pubkey
может вывести что-то вроде этого:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgIK2Wt4x2EtDl41C7vfp
OsMquZMyOyteO2RsVeMLF/hXIeYvicKr0SQzVkodHEBCMiGXQDz5prijTq3RHPy2
/5WJBCYq7yHgTLvspMy6sivXN7NdYE7I5pXo/KHk4nz+Fa6P3L8+L90E/3qwf6j3
DKWnAgJFRY8AbSYXt1d5ELiIG1/gEqzC0fZmNhhfrBtxwWXrlpUDT0Kfvf0QVmPR
xxCLXT+tEe1seWGEqeOLL5vXRLqmzZcBe1RZ9kQQm43+a9Qn5icSRnDfTAesQ3Cr
lAWJKl2kcWU1HwJqw+dZRSZ1X4kEXNMyzPdPBbGmU6MHdhpywI7SKZT7mX4BDnUK
eQIDAQAB
-----END PUBLIC KEY-----
-----BEGIN CERTIFICATE-----
MIIDCzCCAfOgAwIBAgIEGtZIUzANBgkqhkiG9w0BAQsFADA2MQswCQYDVQQGEwJ1
czELMAkGA1UECBMCY2ExCzAJBgNVBAcTAmxhMQ0wCwYDVQQDEwR0ZXN0MB4XDTE2
MDMxNTA4MTAzMFoXDTE2MDYxMzA4MTAzMFowNjELMAkGA1UEBhMCdXMxCzAJBgNV
BAgTAmNhMQswCQYDVQQHEwJsYTENMAsGA1UEAxMEdGVzdDCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAICCtlreMdhLQ5eNQu736TrDKrmTMjsrXjtkbFXj
Cxf4VyHmL4nCq9EkM1ZKHRxAQjIhl0A8+aa4o06t0Rz8tv+ViQQmKu8h4Ey77KTM
urIr1zezXWBOyOaV6Pyh5OJ8/hWuj9y/Pi/dBP96sH+o9wylpwICRUWPAG0mF7dX
eRC4iBtf4BKswtH2ZjYYX6wbccFl65aVA09Cn739EFZj0ccQi10/rRHtbHlhhKnj
iy+b10S6ps2XAXtUWfZEEJuN/mvUJ+YnEkZw30wHrENwq5QFiSpdpHFlNR8CasPn
WUUmdV+JBFzTMsz3TwWxplOjB3YacsCO0imU+5l+AQ51CnkCAwEAAaMhMB8wHQYD
VR0OBBYEFOGefUBGquEX9Ujak34PyRskHk+WMA0GCSqGSIb3DQEBCwUAA4IBAQB3
1eLfNeq45yO1cXNl0C1IQLknP2WXg89AHEbKkUOA1ZKTOizNYJIHW5MYJU/zScu0
yBobhTDe5hDTsATMa9sN5CPOaLJwzpWV/ZC6WyhAWTfljzZC6d2rL3QYrSIRxmsp
/J1Vq9WkesQdShnEGy7GgRgJn4A8CKecHSzqyzXulQ7Zah6GoEUD+vjb+BheP4aN
hiYY1OuXD+HsdKeQqS+7eM5U7WW6dz2Q8mtFJ5qAxjY75T0pPrHwZMlJUhUZ+Q2V
FfweJEaoNB9w9McPe1cAiE+oeejZ0jq0el3/dJsx3rlVqZN+lMhRJJeVHFyeb3XF
lLFCUGhA7hxn2xf3x1JW
-----END CERTIFICATE-----
Мы используем только открытый ключ, копируем его на ресурсный серверsrc/main/resources/public.txtВ файле:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgIK2Wt4x2EtDl41C7vfp
OsMquZMyOyteO2RsVeMLF/hXIeYvicKr0SQzVkodHEBCMiGXQDz5prijTq3RHPy2
/5WJBCYq7yHgTLvspMy6sivXN7NdYE7I5pXo/KHk4nz+Fa6P3L8+L90E/3qwf6j3
DKWnAgJFRY8AbSYXt1d5ELiIG1/gEqzC0fZmNhhfrBtxwWXrlpUDT0Kfvf0QVmPR
xxCLXT+tEe1seWGEqeOLL5vXRLqmzZcBe1RZ9kQQm43+a9Qn5icSRnDfTAesQ3Cr
lAWJKl2kcWU1HwJqw+dZRSZ1X4kEXNMyzPdPBbGmU6MHdhpywI7SKZT7mX4BDnUK
eQIDAQAB
-----END PUBLIC KEY-----
6.3, конфигурация Maven
Мы не хотим, чтобы процесс фильтрации maven повлиял на файл JKS, поэтому нам нужно убедиться, чтоpom.xmlисключить его в:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>*.jks</exclude>
</excludes>
</resource>
</resources>
</build>
Если вы используете Spring Boot, мы можем использовать плагин Spring Boot MavenaddResourcesДобавьте файл JKS в путь к классам приложения:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
6.4, сервер авторизации
настроитьJwtAccessTokenConverterиспользоватьmytest.jksпара ключей в , как показано ниже:
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
KeyStoreKeyFactory keyStoreKeyFactory =
new KeyStoreKeyFactory(new ClassPathResource("mytest.jks"), "mypass".toCharArray());
converter.setKeyPair(keyStoreKeyFactory.getKeyPair("mytest"));
return converter;
}
6.5. Сервер ресурсов
Наконец, сервер ресурсов необходимо настроить для использования открытого ключа следующим образом:
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
Resource resource = new ClassPathResource("public.txt");
String publicKey = null;
try {
publicKey = IOUtils.toString(resource.getInputStream());
} catch (final IOException e) {
throw new RuntimeException(e);
}
converter.setVerifierKey(publicKey);
return converter;
}
7. Заключение
В этой статье описывается, как настроить проект Spring Security OAuth2 для интеграции JSON Web Token.
этого руководстваполная реализациядопустимыйпроект гитхаб, который представляет собой проект Eclipse, который легко импортировать и запускать.