Разработка и реализация аутентификации, аутентификации и управления разрешениями API в микросервисной архитектуре (1)

Микросервисы Архитектура

Введение: эта статья является первой в серии «Проектирование и реализация аутентификации, аутентификации и контроля разрешений API в архитектуре микросервисов». Ожидается, что в этой серии будет четыре статьи, объясняющие реализацию аутентификации, аутентификации и контроля разрешений API в микросервисах.

1. Предпосылки

В последнее время я разрабатываю службы, связанные с разрешениями.После микросервисной системы исходное отдельное приложение представляет собой метод разрешений безопасности на основе сеанса, который не может соответствовать требованиям аутентификации и аутентификации существующей архитектуры микросервисов. В архитектуре микрослужб приложение разделено на несколько микроприложений, каждое микроприложение должно аутентифицировать доступ, и каждое микроприложение должно указать текущего пользователя доступа и его разрешения. Особенно, когда источником доступа является не только браузер, но и вызов других сервисов, метод аутентификации в монолитной архитектуре приложения не особо подходит. В архитектуре микросервисов следует учитывать различные сценарии аутентификации, такие как сценарии доступа к внешним приложениям, аутентификация пользователя-службы и аутентификация службы-службы.
Например, когда пользователь A получает доступ к User Service, если пользователь A не вошел в систему, ему сначала необходимо войти в систему и запросить токен авторизации. После получения токена A будет нести токен для запроса доступа к файлу, так что личность A необходимо проверить, и A сможет получить доступ к файлу.
Чтобы адаптироваться к изменениям в архитектуре и требованиям, модуль авторизации авторизации изолирован как базовая микросервисная система для предоставления сервисов для других бизнес-сервисов.

2. Изменения в архитектуре системы

Упрощенные изменения разрешений при переходе от архитектуры с одним приложением к распределенной архитектуре показаны на следующих двух рисунках.
(1) Схема архитектуры упрощенной версии одного приложения:

single
single

(2) Схема архитектуры упрощенной версии распределенного приложения:
distrubted
distrubted

Преимущество распределенной архитектуры, особенно микросервисной, в том, что бизнес-логика может быть четко разделена, так что каждый микросервис может взять на себя одну функцию, ведь чем проще, тем стабильнее.

Однако микросервисы также приносят немало проблем. Например, для выполнения бизнес-операции необходимо вызвать множество микросервисов, поэтому использование системы разрешений для управления вызовами пользователей к различным микросервисам представляет для нас проблему. Когда вызов бизнес-микросервисов связан с системой разрешений, их пропускная способность не может быть снижена, когда есть проблема с системой разрешений, их бизнес-вызовы не могут быть заблокированы, и, конечно, бизнес-логика не может быть изменена. Системой разрешений быстрого доступа для новых бизнес-микросервисов относительно легко управлять, поэтому как быстро получить доступ к существующим микросервисам компании, не меняя их архитектуру, также является для нас большой проблемой.

3. Технические решения

Это в основном включает в себя два требования: одно — аутентификация и аутентификация, авторизация запрошенного удостоверения пользователя и аутентификация законности; другое — управление полномочиями на уровне API, после первой точки, когда удостоверение пользователя аутентифицируется. После того, как это законно, проверьте, является ли конкретный запрос пользователя имеет разрешение на выполнение операции.

3.1 Аутентификация и аутентификация

Для первого требования автор исследовал некоторые решения реализации:

  1. распределенныйSessionплан
    Принцип схемы распределенного сеанса в основном заключается в хранении информации об аутентификации пользователя в общем хранилище и обычно использовании сеанса пользователя в качестве ключа для реализации простой распределенной хэш-карты. Когда пользователи обращаются к микросервисам, пользовательские данные могут быть извлечены из общего хранилища. В некоторых случаях эта схема очень хороша, статус входа пользователя не прозрачен. Это также высокодоступное и масштабируемое решение. Недостатком этого решения является то, что для общего хранилища требуется определенный механизм защиты, поэтому доступ к нему должен осуществляться через защищенную ссылку, а реализация решения обычно довольно сложна.

  2. на основеOAuth2 Tokenплан
    С появлением Restful API и микросервисов, основанных наTokenСертификация становится все более распространенной. Токен и идентификатор сеанса — это разные вещи, а не только ключ. Токен обычно содержит соответствующую информацию о пользователе, и проверка личности может быть завершена путем проверки токена. Пользователь вводит регистрационную информацию и отправляет ее службе проверки подлинности для проверки подлинности. AuthorizationServer проверяет правильность информации для входа и возвращает такую ​​информацию, как основная информация о пользователе, объем полномочий и действительное время, а клиент сохраняет интерфейс. Пользователь помещает токен в заголовок HTTP-запроса и инициирует соответствующие вызовы API. Вызванный микросервис, проверяющийToken. ResourceServer возвращает связанные ресурсы и данные.

Здесь выбирается второй вариант, исходя изOAuth2 TokenПреимущества сертификации заключаются в следующем:

  • На стороне сервера без сохранения состояния: механизму токена не нужно хранить информацию о сеансе на стороне сервера, поскольку сам токен содержит всю информацию, относящуюся к пользователю.
  • Производительность выше, поскольку больше нет необходимости обращаться к базе данных или удаленному сервису для проверки разрешений при проверке токена, что, естественно, может значительно повысить производительность.
  • Многие приложения теперь ориентированы как на мобильные устройства, так и на Интернет.OAuth2 TokenМеханизм может поддерживать мобильные устройства.
  • Последний момент тоже очень важен, OAuth2 используется в связке со Spring Security, документация по Spring Security OAuth2 написана более подробно.

oauth2 разделен на 4 режима в соответствии с различными сценариями использования:

  • Код авторизации
  • Упрощенный режим (неявный)
  • Режим пароля (учетные данные пароля владельца ресурса)
  • Режим клиента (учетные данные клиента)

Для студентов, которые не знакомы с четырьмя вышеупомянутыми режимами oauth2, вы можете самостоятельно использовать Baidu oauth2.В статье Ruan Yifeng есть объяснение. Обычно используются режим пароля и режим клиента.

3.2 Контроль разрешений на операции

Что касается второго требования, автор в основном смотрел на Spring Security и Shiro.

  1. Shiro
    Shiro — это мощная и гибкая платформа безопасности с открытым исходным кодом, которая очень аккуратно обрабатывает аутентификацию, авторизацию, управление сеансами и шифрование паролей. Широ легко начать, и вы можете быстро или точно контролировать детализацию. Обладая высокой степенью свободы, Широ можно использовать вместе со Spring или отдельно.

  2. Spring Security
    Экология весеннего сообщества очень сильна. Spring Security обладает всеми функциями Shiro, за исключением того, что его нельзя отделить от Spring. Более того, Spring Security также поддерживает Oauth и OpenID, а Shiro нужно реализовать это вручную. Разрешения Spring Security более детализированы. Но Spring Security слишком сложна.

Глядя на комментарии в Интернете, кажется, что это однобоко по отношению к Широ. предложено большинствомSpring SecurityПроблема в том, что он более сложный и трудный для понимания, а документ слишком длинный. Автор всесторонне оценил сложность и требования к разрешению, которые должны быть реализованы, а также результаты предыдущего обзора требований и, наконец, выбралSpring Security.

4. Архитектура системы

4.1 Компоненты

Компоненты конечного использования системы аутентификации следующие:

OAuth2.0 JWT Token
Spring Security
Spring boot

4.2 Шаги

Основные шаги:

  • Настройка сервера ресурсов и сервера аутентификации
  • Настроить весеннюю безопасность

Вышеуказанные шаги являются относительно общими.Требования, упомянутые в предыдущем разделе, относятся к основному содержанию системы аутентификации.Автор напишет другую статью, чтобы объяснить это позже.

4.3 endpoint

Предоставленная конечная точка:

/oauth/token?grant_type=password #请求授权token

/oauth/token?grant_type=refresh_token #刷新token

/oauth/check_token #校验token

/logout #注销token及权限相关信息

4.4 зависимости maven

Основной пакет jar, файл pom.xml, выглядит следующим образом:

        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>2.2.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
            <version>1.2.1-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
            <version>1.2.1-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jersey</artifactId>
            <version>1.5.3.RELEASE</version>
        </dependency>

4.5 Конфигурационный файл AuthorizationServer

Конфигурация AuthorizationServer в основном переопределяет следующие три метода, предназначенные для конечных точек, клиентов и конфигураций безопасности.

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    //配置客户端认证
        clients.withClientDetails(clientDetailsService(dataSource));
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 
    //配置token的数据源、自定义的tokenServices等信息
        endpoints.authenticationManager(authenticationManager)
                .tokenStore(tokenStore(dataSource))
                .tokenServices(authorizationServerTokenServices())
                .accessTokenConverter(accessTokenConverter())
                .exceptionTranslator(webResponseExceptionTranslator);
    }

4.6 Конфигурация ResourceServer

Конфигурация сервера ресурсов, которая переопределяет конфигурацию по умолчанию. Для поддержки выхода из системы, вот пользовательскийCustomLogoutHandlerи воляlogoutSuccessHandlerуказан для возврата статуса httpHttpStatusReturningLogoutSuccessHandler.

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .requestMatchers().antMatchers("/**")
                .and().authorizeRequests()
                .antMatchers("/**").permitAll()
                .anyRequest().authenticated()
                .and().logout()
                .logoutUrl("/logout")
                .clearAuthentication(true)
                .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler())
                .addLogoutHandler(customLogoutHandler());

4.7 Выполнение конечной точки

  1. Сначала выполните конечную точку для получения авторизации.
method: post 
url: http://localhost:12000/oauth/token?grant_type=password
header:
{
    Authorization: Basic ZnJvbnRlbmQ6ZnJvbnRlbmQ=,
    Content-Type: application/x-www-form-urlencoded
}
body:
{
    username: keets,
    password: ***
}

Вышеупомянутое создает почтовый запрос, и конкретный запрос написан очень подробно. Имя пользователя и пароль — это информация, предоставляемая клиентом серверу для проверки личности пользователя. Авторизация в заголовке — это закодированная строка сохраненного clientId и clientSecret.
Возвращаемые результаты следующие:

{   
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJYLUtFRVRTLVVzZXJJZCI6ImQ2NDQ4YzI0LTNjNGMtNGI4MC04MzcyLWMyZDYxODY4ZjhjNiIsImV4cCI6MTUwODQ0Nzc1NiwidXNlcl9uYW1lIjoia2VldHMiLCJqdGkiOiJiYWQ3MmIxOS1kOWYzLTQ5MDItYWZmYS0wNDMwZTdkYjc5ZWQiLCJjbGllbnRfaWQiOiJmcm9udGVuZCIsInNjb3BlIjpbImFsbCJdfQ.5ZNVN8TLavgpWy8KZQKArcbj7ItJLLaY1zBRaAgMjdo",   
    "token_type": "bearer",
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJYLUtFRVRTLVVzZXJJZCI6ImQ2NDQ4YzI0LTNjNGMtNGI4MC04MzcyLWMyZDYxODY4ZjhjNiIsInVzZXJfbmFtZSI6ImtlZXRzIiwic2NvcGUiOlsiYWxsIl0sImF0aSI6ImJhZDcyYjE5LWQ5ZjMtNDkwMi1hZmZhLTA0MzBlN2RiNzllZCIsImV4cCI6MTUxMDk5NjU1NiwianRpIjoiYWE0MWY1MjctODE3YS00N2UyLWFhOTgtZjNlMDZmNmY0NTZlIiwiY2xpZW50X2lkIjoiZnJvbnRlbmQifQ.mICT1-lxOAqOU9M-Ud7wZBb4tTux6OQWouQJ2nn1DeE",
    "expires_in": 43195,
    "scope": "all",
    "X-KEETS-UserId": "d6448c24-3c4c-4b80-8372-c2d61868f8c6",
    "jti": "bad72b19-d9f3-4902-affa-0430e7db79ed",
    "X-KEETS-ClientId": "frontend"
}

Видно, что после проверки логина и пароля клиент получает ответ от сервера авторизации, в основном включая доступжетон, обновитьтокен. И это указывает на то, что тип токена является предъявителем, а время истечения срока действия expires_in. Автор добавил пользовательскую информацию в токен jwt как UserId и ClientId.

2. Конечная точка аутентификации

method: post 
url: http://localhost:12000/oauth/check_token
header:
{
    Authorization: Basic ZnJvbnRlbmQ6ZnJvbnRlbmQ=,
    Content-Type: application/x-www-form-urlencoded
}
body:
{
    token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJYLUtFRVRTLVVzZXJJZCI6ImQ2NDQ4YzI0LTNjNGMtNGI4MC04MzcyLWMyZDYxODY4ZjhjNiIsImV4cCI6MTUwODQ0Nzc1NiwidXNlcl9uYW1lIjoia2VldHMiLCJqdGkiOiJiYWQ3MmIxOS1kOWYzLTQ5MDItYWZmYS0wNDMwZTdkYjc5ZWQiLCJjbGllbnRfaWQiOiJmcm9udGVuZCIsInNjb3BlIjpbImFsbCJdfQ.5ZNVN8TLavgpWy8KZQKArcbj7ItJLLaY1zBRaAgMjdo
}

Выше приведена подробная информация о запросе check_token. Следует отметить, что автор поместил в тело только что авторизованный токен, здесь может быть несколько методов, которые не будут здесь распространяться.

{
    "X-KEETS-UserId": "d6448c24-3c4c-4b80-8372-c2d61868f8c6",
    "user_name": "keets",
    "scope": [
        "all"
    ],
    "active": true,
    "exp": 1508447756,
    "X-KEETS-ClientId": "frontend",
    "jti": "bad72b19-d9f3-4902-affa-0430e7db79ed",
    "client_id": "frontend"
}

После проверки правильности маркера возвращается ответ, как показано выше. Основная информация в соответствующем токене также отображается в ответе.

3. Обновить токен
Поскольку старение токена, как правило, не очень продолжительное, а обновлениеЦикл токена, как правило, будет очень долгим. Чтобы не влиять на работу пользователя, вы можете использовать обновлениеtoken для динамического обновления токена.

method: post 
url: http://localhost:12000/oauth/token?grant_type=refresh_token&refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJYLUtFRVRTLVVzZXJJZCI6ImQ2NDQ4YzI0LTNjNGMtNGI4MC04MzcyLWMyZDYxODY4ZjhjNiIsInVzZXJfbmFtZSI6ImtlZXRzIiwic2NvcGUiOlsiYWxsIl0sImF0aSI6ImJhZDcyYjE5LWQ5ZjMtNDkwMi1hZmZhLTA0MzBlN2RiNzllZCIsImV4cCI6MTUxMDk5NjU1NiwianRpIjoiYWE0MWY1MjctODE3YS00N2UyLWFhOTgtZjNlMDZmNmY0NTZlIiwiY2xpZW50X2lkIjoiZnJvbnRlbmQifQ.mICT1-lxOAqOU9M-Ud7wZBb4tTux6OQWouQJ2nn1DeE
header:
{
    Authorization: Basic ZnJvbnRlbmQ6ZnJvbnRlbmQ=
}

Его ответ и /oauth/token аналогичны обычному ответу и не будут здесь перечислены.

4. Отменить токен

method: get
url: http://localhost:9000/logout
header:
{
    Authorization: Basic ZnJvbnRlbmQ6ZnJvbnRlbmQ=
}

Если выход выполнен успешно, будет возвращено значение 200. Конечная точка выхода в основном предназначена для очистки маркера и SecurityContextHolder.

5. Резюме

Эта статья представляет собой обзор серии статей «Проектирование и реализация аутентификации, аутентификации и управления разрешениями API в микросервисной архитектуре», начиная с возникших проблем и представляя предысторию проекта. Выбор технологии определяется путем изучения существующей технологии и ее сочетания с фактической ситуацией текущего проекта. Наконец, показана окончательная реализация системы. Реализация этой системы будет объяснена позже из деталей реализации. Следите за дальнейшими статьями.

Добро пожаловать, чтобы обратить внимание на мой общедоступный номер

微信公众号
Публичный аккаунт WeChat


Ссылаться на

  1. Понимание OAuth 2.0
  2. Техническая архитектура разрешений на уровне API для микросервисов
  3. Аутентификация безопасности и аутентификация в рамках микросервисной архитектуры