1. введение
В этом уроке мы подготовим динамическую регистрацию клиента с помощью OAuth2.0. OAuth2.0-это система авторизации, которая позволяет получать ограниченный доступ к учетным записям пользователей в службе HTTP. Клиент OAuth2.0-это приложение, которое хочет получить доступ к учетной записи пользователя. Этот клиент может быть внешним веб-приложением, агентом пользователя или просто собственным клиентом.
Чтобы обеспечить динамическую регистрацию клиента, мы будем хранить учетные данные в базе данных, а не в жестко заданной конфигурации. Приложение, которое мы собираемся расширить, изначально было описано в учебнике Spring REST API + OAuth2 .
Примечание : в этой статье используется устаревший проект Spring OAuth .
2. Зависимости Maven
Сначала мы настроим следующий набор зависимостей:
org.springframework.boot spring-boot-starter-web org.springframework spring-jdbc org.springframework.security.oauth spring-security-oauth2
Обратите внимание, что мы используем spring-jdbc , потому что мы собираемся использовать aDB для хранения паролей новых зарегистрированных пользователей.
3. Конфигурация сервера OAuth2.0
Во-первых, нам нужно настроить наш сервер авторизации OAuth2.0. Основная конфигурация находится внутри следующего класса:
@Configuration @PropertySource({ "classpath:persistence.properties" }) @EnableAuthorizationServer public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { // config }
Есть несколько основных вещей, которые нам нужно настроить; давайте начнем с ClientDetailsServiceConfigurer:
@Override public void configure(final ClientDetailsServiceConfigurer clients) throws Exception { clients.jdbc(dataSource()) // ... }
Это позволит убедиться, что мы используем настойчивость для получения информации о клиентах.
Давайте, конечно, настроим этот стандартный источник данных:
@Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName")); dataSource.setUrl(env.getProperty("jdbc.url")); dataSource.setUsername(env.getProperty("jdbc.user")); dataSource.setPassword(env.getProperty("jdbc.pass")); return dataSource; }
Итак, теперь наше приложение будет использовать базу данных в качестве источника зарегистрированных клиентов вместо типичных жестко закодированных клиентов в памяти.
4. Схема БД
Давайте теперь определим структуру SQL для хранения наших клиентов OAuth:
create table oauth_client_details ( client_id VARCHAR(256) PRIMARY KEY, resource_ids VARCHAR(256), client_secret VARCHAR(256), scope VARCHAR(256), authorized_grant_types VARCHAR(256), web_server_redirect_uri VARCHAR(256), authorities VARCHAR(256), access_token_validity INTEGER, refresh_token_validity INTEGER, additional_information VARCHAR(4096), autoapprove VARCHAR(256) );
Наиболее важными полями из oauth_client_details , на которых мы должны сосредоточиться, являются:
- client_id – для хранения идентификатора вновь зарегистрированных клиентов
- client_secret – для хранения пароля клиентов
- access_token_validity – указывает, является ли клиент все еще действительным
- полномочия – указать, какие роли разрешены для конкретного клиента
- область действия – разрешенные действия, например, написание статусов в Facebook и т.д.
- authorized_grant_types , который предоставляет информацию о том, как пользователи могут войти в конкретный клиент (в нашем примере это форма входа с паролем)
Пожалуйста, обратите внимание, что у каждого клиента есть отношения “один ко многим” с пользователями, что, естественно, означает, что несколько пользователей могут использовать одного клиента .
5. Давайте Сохраним Некоторых Клиентов
С помощью определения схемы SQL мы можем, наконец, создать некоторые данные в системе – и в основном определить клиента.
Мы собираемся использовать следующий сценарий data.sql , который по умолчанию будет запущен при загрузке Spring, для инициализации базы данных:
INSERT INTO oauth_client_details (client_id, client_secret, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove) VALUES ("fooClientIdPassword", "secret", "foo,read,write, "password,authorization_code,refresh_token", null, null, 36000, 36000, null, true);
Описание наиболее важных полей в oauth_client_details приведено в предыдущем разделе.
6. Тестирование
Чтобы протестировать динамическую регистрацию клиента, нам необходимо запустить оба проекта spring-security-oauth-server и spring-security-oauth-resource на портах 8081 и 8082 соответственно.
Теперь мы наконец-то можем написать несколько живых тестов.
Предположим, что мы зарегистрировали клиента с идентификатором foo ClientID Password , который имеет доступ к чтению пищи.
Во-первых, мы попытаемся получить токен доступа с сервера аутентификации, используя уже определенный клиент:
@Test public void givenDBUser_whenRevokeToken_thenAuthorized() { String accessToken = obtainAccessToken("fooClientIdPassword", "john", "123"); assertNotNull(accessToken); }
И вот логика получения токена доступа:
private String obtainAccessToken(String clientId, String username, String password) { Mapparams = new HashMap (); params.put("grant_type", "password"); params.put("client_id", clientId); params.put("username", username); params.put("password", password); Response response = RestAssured.given().auth().preemptive() .basic(clientId, "secret").and().with().params(params).when() .post("http://localhost:8081/spring-security-oauth-server/oauth/token"); return response.jsonPath().getString("access_token"); }
7. Заключение
В этом уроке мы узнали, как динамически регистрировать неограниченное количество клиентов с помощью платформы OAuth2.0.
Полную реализацию этого руководства можно найти на GitHub – это проект на основе Maven, поэтому его должно быть легко импортировать и запускать как есть.
Пожалуйста, обратите внимание, что для тестирования вам нужно будет добавить клиентов в БД, и что .in Memory() конфигурация больше не будет действительна. Если вы хотите использовать старое . в памяти() config есть второй файл, содержащий конфигурацию с жестко закодированными клиентами.