OAuth 2.0 – это стандартный отраслевой протокол авторизации. OAuth 2.0 фокусируется на простоте разработки для клиентов, обеспечивая при этом конкретные потоки авторизации для веб-приложений, настольных приложений, мобильных телефонов и устройств для гостиной. В этом сообщении в блоге объясняется реализация аутентификации OAuth2 с помощью Spring Boot, Spring Security и Angular.
OAuth определяет четыре роли:
- Владелец ресурса
- Клиент
- Сервер ресурсов
- Сервер авторизации
Владелец ресурса: Пользователь
Владельцем ресурса является пользователь , который разрешает приложению доступ к своей учетной записи. Доступ приложения к учетной записи пользователя ограничен “областью” предоставленной авторизации (например, доступ на чтение или запись).
Сервер ресурсов/авторизации: API
На сервере ресурсов размещаются защищенные учетные записи пользователей, а сервер авторизации проверяет личность пользователя , а затем выдает токены доступа приложению .
Клиент: Приложение
Клиент – это приложение , которое хочет получить доступ к учетной записи пользователя . Прежде чем он сможет это сделать, он должен быть авторизован пользователем, и авторизация должна быть подтверждена API.
Следующая диаграмма объясняет процесс
OAuth2 Рабочий процесс
- Пользователь переходит в http://localhost:4200 для доступа к данным и Angular перенаправляет его на страницу входа в систему
- Пользователь вводит учетные данные и нажимает на кнопку войти
- Angular отправляет эти учетные данные в https://localhost:8090/oauth/token и Spring Security, используя OAuth2, пытается аутентифицировать его
- Если учетные данные действительны, он возвращает следующий ответ. И неверные учетные данные удерживают его на той же странице с сообщением об ошибке
{"access\_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3","token\_type":"bearer","expires\_in":3600,"refresh\_token":"IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk","scope":"create"}
5. Затем Angular выполняет другой запрос, используя access_token
для получения информации о пользователе (Это можно сделать многими способами)
6. Как только Angular получает ответ, он перенаправляет его на домашнюю страницу. Он может получить доступ к категориям, заказам и т.д. В зависимости от ролей.
- Пружинный ботинок 2.x
- Пружинная защита 2.x
- OAuth2
- База данных MySQL
- Угловой 8
- Создайте следующие таблицы в базе данных MySQL для хранения токенов OAuth
drop table if exists oauth\_client\_details; create table oauth\_client\_details ( client\_id VARCHAR(255) PRIMARY KEY, resource\_ids VARCHAR(255), client\_secret VARCHAR(255), scope VARCHAR(255), authorized\_grant\_types VARCHAR(255), web\_server\_redirect\_uri VARCHAR(255), authorities VARCHAR(255), access\_token\_validity INTEGER, refresh\_token\_validity INTEGER, additional\_information VARCHAR(4096), autoapprove VARCHAR(255) ); drop table if exists oauth\_client\_token; create table oauth\_client\_token ( token\_id VARCHAR(255), token LONG VARBINARY, authentication\_id VARCHAR(255) PRIMARY KEY, user\_name VARCHAR(255), client\_id VARCHAR(255) ); drop table if exists oauth\_access\_token; create table oauth\_access\_token ( token\_id VARCHAR(255), token LONG VARBINARY, authentication\_id VARCHAR(255) PRIMARY KEY, user\_name VARCHAR(255), client\_id VARCHAR(255), authentication LONG VARBINARY, refresh\_token VARCHAR(255) ); drop table if exists oauth\_refresh\_token; create table oauth\_refresh\_token ( token\_id VARCHAR(255), token LONG VARBINARY, authentication LONG VARBINARY ); drop table if exists oauth\_code; create table oauth\_code ( code VARCHAR(255), authentication LONG VARBINARY ); SET SQL\_MODE='ALLOW\_INVALID\_DATES'; drop table if exists oauth\_approvals; create table oauth\_approvals ( userId VARCHAR(255), clientId VARCHAR(255), scope VARCHAR(255), status VARCHAR(10), expiresAt TIMESTAMP, lastModifiedAt TIMESTAMP ); drop table if exists ClientDetails; create table ClientDetails ( appId VARCHAR(255) PRIMARY KEY, resourceIds VARCHAR(255), appSecret VARCHAR(255), scope VARCHAR(255), grantTypes VARCHAR(255), redirectUrl VARCHAR(255), authorities VARCHAR(255), access\_token\_validity INTEGER, refresh\_token\_validity INTEGER, additionalInformation VARCHAR(4096), autoApproveScopes VARCHAR(255) );
2. Давайте вызовем сервер ресурсов resource-server-rest-api
и определим двух клиентов. Секрет клиента зашифрован с помощью BCrypt с 4 раундами.
- spring-security-oauth2-read-client (типы разрешенных разрешений: чтение)
- spring-security-oauth2-чтение-запись-клиент (типы разрешенных разрешений: чтение, запись)
Перейдите на веб-сайт и введите spring-security-oauth2-read-write-client-password 1234 в качестве пароля и округлите до 4, чтобы получить зашифрованный пароль. Обязательно замените поле зашифрованного пароля в следующем SQL-запросе вашим паролем BCrypt.
INSERT INTO OAUTH\_CLIENT\_DETAILS(CLIENT\_ID, RESOURCE\_IDS, CLIENT\_SECRET, SCOPE, AUTHORIZED\_GRANT\_TYPES, AUTHORITIES, ACCESS\_TOKEN\_VALIDITY, REFRESH\_TOKEN\_VALIDITY) VALUES ('spring-security-oauth2-read-client', 'resource-server-rest-api','Encrypted Password','read', 'password,authorization\_code,refresh\_token,implicit', 'USER', 10800, 2592000);INSERT INTO OAUTH\_CLIENT\_DETAILS(CLIENT\_ID, RESOURCE\_IDS, CLIENT\_SECRET, SCOPE, AUTHORIZED\_GRANT\_TYPES, AUTHORITIES, ACCESS\_TOKEN\_VALIDITY, REFRESH\_TOKEN\_VALIDITY) VALUES ('spring-security-oauth2-read-write-client', 'resource-server-rest-api','Encrypted Password','read,write', 'password,authorization\_code,refresh\_token,implicit', 'USER', 10800, 2592000);
3. Создайте сервер авторизации OAuth2, который авторизует запросы пользователей. Класс Конфигурация сервера авторизации
должен расширяться Авторизация serverconfigureradapter
и переопределите методы configure()
.
-
TokenStore()
bean устанавливает хранилище Mysql JDBC в качестве хранилища токенов -
настроить(конечные точки AuthorizationServerEndpointsConfigurer)
- метод связывает конечные точки с TokenStore, AuthenticationManager и UserDetailsService
configure(AuthorizationServerSecurityConfigurer oauthserver)
- метод устанавливает токен для доступа и алгоритм шифрования пароля клиента.
configure(ClientDetailsServiceConfigurer клиенты)
|| configure(ClientDetailsServiceConfigurer клиенты) || метод задает источник данных клиента
@Configuration @EnableAuthorizationServer @Import(SecurityConfig.class) public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { private final AuthenticationManager authenticationManager; @Qualifier("dataSource") private final DataSource dataSource; private final MyUserDetailsService myUserDetailsService; private final PasswordEncoder oauthClientPasswordEncoder; @Autowired public OAuth2AuthorizationServerConfig(AuthenticationManager authenticationManager, DataSource dataSource, MyUserDetailsService myUserDetailsService, @Qualifier("oauthClientPasswordEncoder") PasswordEncoder oauthClientPasswordEncoder) { this.authenticationManager \= authenticationManager; this.dataSource \= dataSource; this.myUserDetailsService \= myUserDetailsService; this.oauthClientPasswordEncoder \= oauthClientPasswordEncoder; } @Bean public OAuth2AccessDeniedHandler oauthAccessDeniedHandler() { return new OAuth2AccessDeniedHandler(); } @Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) { oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()").passwordEncoder(oauthClientPasswordEncoder); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.jdbc(dataSource); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) { endpoints.tokenStore(tokenStore()).authenticationManager(authenticationManager).userDetailsService(myUserDetailsService); } @Bean public TokenStore tokenStore() { return new JdbcTokenStore(dataSource); } }
4. SecurityConfig
класс защищает приложение с помощью Spring Security, которая позволяет настраивать роли и привилегии
5. Определить OAuth2CorsFilter
компонент в SecurityConfig и добавьте его в метод configure()
, как показано ниже. Это вынуждает Spring Security использовать проверку подлинности OAuth2 перед базовой проверкой подлинности
@Override public void configure(HttpSecurity http) throws Exception { http.addFilterBefore(oAuth2CorsFilter, BasicAuthenticationFilter.class); /\*Standard Spring Security config \*/ ............................... }
6. Сервер ресурсов принимает запрос, отправленный клиентом, и запрашивает Сервер авторизации для проверки токена. Определить Конфигурация сервера ресурсов OAuth2
класс, который действует как сервер ресурсов с аннотацией EnableResourceServer
.
@Configuration @EnableResourceServer public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(ResourceServerSecurityConfigurer resources) { resources.resourceId(ResourceConstants._RESOURCE\_SERVER\_REST\_API_); } }
7. Определить Methodsecurityconfig
класс, который расширяет Globalmethod Securityconfiguration
класс, который помогает использовать аннотации безопасности Spring поверх методов в контроллерах
8. Определить OAuth2CorsFilter
, Кодеры паролей
классы, как показано в базе кода
9. Определить Мои данные пользователя
класс, расширяющий ядро безопасности Spring UserDetails
класс
10. Определить сервис MyUserDetailsService
который реализует Spring Security interface UserDetailsService
11. Определить Пользовательский класс DaoAuthenticationProvider
, который проверяет подлинность предоставленных учетных данных по имени пользователя и паролю базы данных.
12. Определить CustomAuthenticationSuccessHandler
класс и переопределить Onauthenticationsuccess()
метод, который определяет действия, которые необходимо предпринять после успешной аутентификации, и аналогичным образом реализует другие классы, такие как usersaccessdecisionmanager
, CustomAuthenticationFailureHandler
и customlogoutsuccesshandler
13. Клонируйте репозиторий GitHub и запустите приложение. Это позволит создать необходимые таблицы, такие как пользователь, роль, привилегии и т.д.
14. Вставьте следующие пользовательские данные в таблицы пользователей, ролей и привилегий. Перейдите на веб-сайт и введите admin в качестве пароля и округлите до 12 и скопируйте зашифрованный пароль. Обязательно замените поле Зашифрованного пароля в следующем SQL-запросе вашим паролем BCrypt.
/\* Insert Data into User Table \*/ INSERT INTO springsessiondemo.user VALUES(1,1,1,1,1,'Encrypted Password','admin'); INSERT INTO springsessiondemo.user VALUES(2,1,1,1,1,'Encrypted Password','user'); /\* Insert Data into Role Table \*/ insert into springsessiondemo.role values(1,'ROLE\_USER'); insert into springsessiondemo.role values(2,'ROLE\_ADMIN'); insert into springsessiondemo.role values(3,'ROLE\_APIUSER'); insert into springsessiondemo.role values(4,'ROLE\_DBA'); insert into springsessiondemo.role values(5,'ROLE\_SELLER'); insert into springsessiondemo.role values(6,'ROLE\_BUYER'); /\* Insert Data into Privilege Table \*/ insert into springsessiondemo.privilege values(1,'READ\_PRIVILEGE'); insert into springsessiondemo.privilege values(2,'WRITE\_PRIVILEGE'); insert into springsessiondemo.privilege values(3,'DELETE\_PRIVILEGE'); /\* Insert Data into UserRole Table \*/ INSERT INTO \`springsessiondemo\`.\`user\_role\`(\`id\`,\`user\_id\`,\`role\_id\`) VALUES (1,2,1); INSERT INTO \`springsessiondemo\`.\`user\_role\`(\`id\`,\`user\_id\`,\`role\_id\`) VALUES (2,1,2);INSERT INTO \`springsessiondemo\`.\`user\_role\`(\`id\`,\`user\_id\`,\`role\_id\`) VALUES (3,1,1); /\* Insert Data into RolePrivilege Table \*/ insert into springsessiondemo.role\_privilege values(2,1); insert into springsessiondemo.role\_privilege values(2,2); insert into springsessiondemo.role\_privilege values(2,3); insert into springsessiondemo.role\_privilege values(1,1);
15. Перейдите в src/webapp
и выполните следующую команду, чтобы установить зависимости, необходимые для Angular UI.
$ npm install
16. Откройте пользовательский интерфейс Angular, выполнив следующую команду, и перейдите в http://localhost:4200 чтобы увидеть экран входа в систему
$ ng serve --watch
17. Введите имя пользователя и пароль, которые вы создали на шаге 14. Это должно привести вас на домашнюю страницу
18. Нажмите на Категории, чтобы просмотреть список категорий
Загрузите репозиторий с Github
Оригинал: “https://dev.to/pavankjadda/oauth-2-0-authentication-with-spring-security-angular-and-mysql-2dd6”