Предисловие: Эта статья предназначена для того, чтобы помочь вам создать базовую среду, а конкретный фактический боевой план должен быть сформулирован в соответствии с потребностями вашего бизнеса. В итоге мы не использовали Spring Security OAuth2 для построения сервиса авторизации, а реализовали сервис полностью по стандарту OAuth2.
Spring Cloud Security OAuth2 — это реализация Spring OAuth2 с открытым исходным кодом. Преимущество заключается в том, что его можно легко интегрировать со стеком технологий Spring Cloud. Если используются все конфигурации по умолчанию, разработчикам нужно только добавить аннотации для завершения создания авторизации OAuth2. услуга.
1. Добавьте зависимости
Сервис авторизации основан на Spring Security, поэтому в проект нужно внедрить две зависимости:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
Первый — Security, а второй — расширение OAuth2 Security.
2. Добавьте аннотации и конфигурацию
Добавить в класс запуска@EnableAuthorizationServerаннотация:
@SpringBootApplication
@EnableAuthorizationServer
public class AlanOAuthApplication {
public static void main(String[] args) {
SpringApplication.run(AlanOAuthApplication.class, args);
}
}
После их завершения был построен самый базовый скелет нашей службы авторизации. Но чтобы запустить весь процесс, мы должны выделитьclient_id, client_secretПросто сделай это. Метод настройки Spring Security OAuth2 заключается в написании@Configurationнаследование классовAuthorizationServerConfigurerAdapter, затем перепишитеvoid configure(ClientDetailsServiceConfigurer clients)методы, такие как:
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory() // 使用in-memory存储
.withClient("client") // client_id
.secret("secret") // client_secret
.authorizedGrantTypes("authorization_code") // 该client允许的授权类型
.scopes("app"); // 允许的授权范围
}
3. Процесс авторизации
Посетите страницу авторизации:
localhost:8080/oauth/authorize?client_id=client&response_type=code&redirect_uri=http://www.baidu.com
На этом этапе браузер попросит вас ввести имя пользователя и пароль, потому что Spring Security по умолчанию добавляет аутентификацию Basic Auth ко всем URL-адресам. Имя пользователя по умолчаниюuser, пароль генерируется случайным образом и его можно увидеть в журнале консоли.
Хотя стиль очень простой, основные функции доступны. нажмитеAuthorizeПосле этого браузер перенаправит на Baidu и выведетcodeпараметр:
получитьcodeПозже вы можете позвонить
POST/GET http://client:secret@localhost:8080/oauth/token
в обмен наaccess_tokenв настоящее время:
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'grant_type=authorization_code&code=Li4NZo&redirect_uri=http://www.baidu.com' "http://client:secret@localhost:8080/oauth/token"
Обратите внимание, что клиент в URL-адресе - это тот, который был передан в приведенном выше
ClientDetailsServiceConfigurerclientId, указанный классом. Так как метод авторизации author_code не требует client_secret, секрет может быть заполнен любым значением
Возврат следующим образом:
{
"access_token": "32a1ca28-bc7a-4147-88a1-c95abcc30556", // 令牌
"token_type": "bearer",
"expires_in": 2591999,
"scope": "app"
}
На этом наша основная служба авторизации завершена. Однако это всего лишь демонстрация, и для ее использования в производстве требуется дополнительная работа.
4. Используйте MySQL для хранения access_token и информации о клиенте
В приведенном выше примере вся информация о токенах хранится в памяти, которую, очевидно, нельзя использовать в производственной среде (все токены теряются после завершения процесса, и пользователю необходимо повторно авторизоваться), поэтому нам нужно сохранить эту информацию. . Хранить данные на сервере авторизации в базе данных несложно, потому что Spring Cloud Security OAuth разработал для нас набор Schema и соответствующие объекты DAO. Но прежде чем использовать его, нам нужно иметь определенное представление о соответствующих классах.
4.1 Связанные интерфейсы
Spring Cloud Security OAuth2 PassDefaultTokenServicesкласс для завершения бизнес-логики, указанной стандартом OAuth2, такой как создание и истечение срока действия токена, в то время какDefaultTokenServicesснова черезTokenStoreИнтерфейс завершает сохранение сгенерированных данных. В приведенной выше демонстрацииTokenStoreРеализация по умолчаниюInMemoryTokenStore, объем памяти.
Для информации о клиенте,ClientDetailsServiceИнтерфейс отвечает за чтение данных из хранилища, которое также используется по умолчанию в демо выше.InMemoryClientDetialsServiceКласс реализации. Сказав это, вы можете видеть, что для использования хранилища базы данных вам нужно только предоставить классы реализации этих интерфейсов. К счастью, фреймворк уже написал за нас реализацию JDBC, а именноJdbcTokenStoreиJdbcClientDetailsService.
4.2 Создайте таблицу
Чтобы использовать эти реализации JDBC, вы должны сначала создать таблицу. Фреймворк разработал для нас схему заранее, на github:GitHub.com/spring-pro — это…
Прежде чем использовать эту структуру таблицы, следует отметить, что для MySQL первичный ключ в операторе создания таблицы по умолчанию имеет тип varchar (255), и при выполнении в mysql будет сообщено об ошибке, поскольку mysql имеет ограничение на длину первичного ключа varchar. Так что измените его на 128 здесь. Во-вторых, в операторе будут некоторые поля, которыеLONGVARBINARYтип, который соответствует mysqlblobТакже необходимо изменить тип.
4.3 Конфигурация
После создания базы данных следующим шагом будет настройка платформы для использования реализации JDBC. способ или написать@Configurationнаследование классовAuthorizationServerConfigurerAdapter:
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private DataSource dataSource;
@Bean // 声明TokenStore实现
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
@Bean // 声明 ClientDetails实现
public ClientDetailsService clientDetails() {
return new JdbcClientDetailsService(dataSource);
}
@Override // 配置框架应用上述实现
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
endpoints.tokenStore(tokenStore());
// 配置TokenServices参数
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenStore(endpoints.getTokenStore());
tokenServices.setSupportRefreshToken(false);
tokenServices.setClientDetailsService(endpoints.getClientDetailsService());
tokenServices.setTokenEnhancer(endpoints.getTokenEnhancer());
tokenServices.setAccessTokenValiditySeconds( (int) TimeUnit.DAYS.toSeconds(30)); // 30天
endpoints.tokenServices(tokenServices);
}
После их завершения фреймворк запишет данные, сгенерированные в середине, в mysql.oauth_client_detailsЭто таблица клиентов, вы можете добавлять записи прямо в эту таблицу для добавления клиентов:
4.4 На что обратить внимание
Здесь я должен сказать, что у весеннего дизайна есть замечательное место. Внимательно следитьoauth_access_tokenВ таблице хранится токен доступа, но он не хранится непосредственно в поле. Весеннее использованиеOAuth2AccessTokenабстрагировать все атрибуты, связанные с токеном, при записи в базу данных,Spring сериализует объект в байты с помощью механизма сериализации, который поставляется с JDK.непосредственно сохраняется в таблицеtokenв поле. Другими словами, если вы только посмотрите на техпаспорт, вы его не увидите.access_tokenКакова стоимость, срок действия и другая информация. Это приводит к проблемам с реализацией сервера ресурсов. Наш поставщик ресурсов не использует Spring
Безопасность, и я не хочу вводить какие-либо зависимости от Spring Security. В настоящее время я могу использовать толькоDefaultOAuth2AccessTokenскопируйте исходный код в проект поставщика ресурсов, а затем прочитайтеtokenполе и десериализовать восстановленный объект, чтобы получить информацию о маркере. Однако, если вы сделаете это, вы столкнетесь с проблемой совместимости десериализации, Для конкретного решения, пожалуйста, обратитесь к другому моему сообщению в блоге:blog.CSDN.net/нео Смит/AR…
5. Резюме
На этом этапе настроена служба авторизации, которую можно использовать в производственной среде. На самом деле, мы должны соответствующим образом настроить его в реальном использовании.JdbcTokenStoreилиClientDetailsServiceОн может адаптироваться к потребностям бизнеса и даже может реализовать интерфейс напрямую с нуля, без реализации, предоставляемой фреймворком. Кроме того, Spring напрямую конвертируетDefaultOAuth2AccessTokenСчитаю очень неразумным сериализовать дизайн в байты и сохранять в БД. Возможно, первоначальное намерение дизайнера состояло в том, чтобы хранить секретыaccess_token, но можно добиться и через шифрование, и не стоит кидать байты напрямую. Но при настройкеTokenStoreинтерфейс, мы можем использовать нашу собственную структуру таблицы, не придерживаясь реализации по умолчанию.
6. Личное мнение
Реализация Spring OAuth2 слишком сложна, сам по себе oauth2 — это очень простой протокол, который можно свободно реализовать на основе SpringMVC без затруднений и сложностей. Я думаю, что многие люди используют фреймворк, потому что их беспокоит сложность протокола oauth2 и недостаточная надежность — на самом деле, это уже слишком. Если бы я разрабатывал свой личный проект, я бы точно не использовал какой-либо фреймворк.
адрес гитхаба:GitHub.com/Ван Хунфэй…