Рубрики
Без рубрики

Аутентификация OAuth 2.0 с помощью Spring Security, Angular и MySQL

OAuth 2.0 – это стандартный в отрасли протокол авторизации. OAuth 2.0 ориентирован на разработчика-клиента… С тегами java, spring boot, mysql, springsecurity.

OAuth 2.0 – это стандартный отраслевой протокол авторизации. OAuth 2.0 фокусируется на простоте разработки для клиентов, обеспечивая при этом конкретные потоки авторизации для веб-приложений, настольных приложений, мобильных телефонов и устройств для гостиной. В этом сообщении в блоге объясняется реализация аутентификации OAuth2 с помощью Spring Boot, Spring Security и Angular.

OAuth определяет четыре роли:

  • Владелец ресурса
  • Клиент
  • Сервер ресурсов
  • Сервер авторизации

Владелец ресурса: Пользователь

Владельцем ресурса является пользователь , который разрешает приложению доступ к своей учетной записи. Доступ приложения к учетной записи пользователя ограничен “областью” предоставленной авторизации (например, доступ на чтение или запись).

Сервер ресурсов/авторизации: API

На сервере ресурсов размещаются защищенные учетные записи пользователей, а сервер авторизации проверяет личность пользователя , а затем выдает токены доступа приложению .

Клиент: Приложение

Клиент – это приложение , которое хочет получить доступ к учетной записи пользователя . Прежде чем он сможет это сделать, он должен быть авторизован пользователем, и авторизация должна быть подтверждена API.

Следующая диаграмма объясняет процесс

OAuth2 Рабочий процесс

  1. Пользователь переходит в http://localhost:4200 для доступа к данным и Angular перенаправляет его на страницу входа в систему
  2. Пользователь вводит учетные данные и нажимает на кнопку войти
  3. Angular отправляет эти учетные данные в https://localhost:8090/oauth/token и Spring Security, используя OAuth2, пытается аутентифицировать его
  4. Если учетные данные действительны, он возвращает следующий ответ. И неверные учетные данные удерживают его на той же странице с сообщением об ошибке
{"access\_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3","token\_type":"bearer","expires\_in":3600,"refresh\_token":"IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk","scope":"create"}

5. Затем Angular выполняет другой запрос, используя access_token для получения информации о пользователе (Это можно сделать многими способами)

6. Как только Angular получает ответ, он перенаправляет его на домашнюю страницу. Он может получить доступ к категориям, заказам и т.д. В зависимости от ролей.

  1. Пружинный ботинок 2.x
  2. Пружинная защита 2.x
  3. OAuth2
  4. База данных MySQL
  5. Угловой 8
  1. Создайте следующие таблицы в базе данных 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”