securing microservices є критичним аспектом архітектури розподілених систем. Цей блог занурюється в реалізацію безпеки за допомогою OAuth2 для авторизації та JWT (JSON Web Tokens) для безстанної аутентифікації в мікросервісах Java.
Чому безпека важлива в мікросервісах
Архітектури мікросервісів за своєю суттю вводять складності в забезпеченні безпеки міжсервісної комунікації та аутентифікації користувачів. Кожен сервіс є потенційною точкою нападу, що робить надійні механізми безпеки необхідними для запобігання несанкціонованому доступу та витоків даних.
Огляд OAuth2 та JWT
OAuth2
OAuth2 — це відкритий стандарт для делегованої авторизації. Він дозволяє безпечно отримати доступ до ресурсів від імені користувача без необхідності передавати облікові дані.
Основні ролі в OAuth2:
• Власник ресурсу (Resource Owner): Користувач, який володіє даними.
• Клієнт (Client): Застосунок, що запитує доступ до ресурсу.
• Сервер ресурсу (Resource Server): Сервер, що хостить захищені ресурси.
• Сервер авторизації (Authorization Server): Сервер, що видає токени доступу.
JWT (JSON Web Token)
JWT — це компактний, самодостатній формат токена, який широко використовується в безстанній аутентифікації.
• Заголовок (Header): Містить метадані (наприклад, тип, алгоритм підпису).
• Корпус (Payload): Містить претензії (дані користувача, дозволи).
• Підпис (Signature): Перевіряє цілісність токена.
Архітектура
Архітектура безпечних мікросервісів
-
Сервер авторизації (Authorization Server): Видає токени (наприклад, Spring Authorization Server).
-
Шлюз (Gateway): Використовується як єдина точка входу для клієнтів, перевіряючи токени.
-
Сервери ресурсів (Resource Servers): Мікросервіси, що перевіряють та обробляють запити за допомогою токенів.
Реалізація
Крок 1: Налаштування сервера авторизації
Використовуємо Spring Authorization Server для OAuth2.
Залежності:
org.springframework.boot
spring-boot-starter-oauth2-authorization-server
org.springframework.security
spring-security-oauth2-jose
Конфігурація:
@Configuration
public class AuthorizationServerConfig {
@Bean
public RegisteredClientRepository registeredClientRepository() {
RegisteredClient client = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("client-id")
.clientSecret("{noop}client-secret")
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.scope("read")
.build();
return new InMemoryRegisteredClientRepository(client);
}
}
Крок 2: Налаштування сервера ресурсів
Використовуємо Spring Boot для серверів ресурсів.
Залежності:
org.springframework.boot
spring-boot-starter-oauth2-resource-server
Конфігурація:
@Configuration
@EnableWebSecurity
public class ResourceServerConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/public").permitAll()
.anyRequest().authenticated()
.and()
.oauth2ResourceServer().jwt();
}
}
Крок 3: Використання JWT для безстанної аутентифікації
Користувацькі претензії в JWT:
@Bean
public JwtEncoder jwtEncoder() {
JWKSource jwkSource = new ImmutableJWKSet<>(new JWKSet(rsaKey));
return new NimbusJwtEncoder(jwkSource);
}
public String generateToken(String username) {
JwtClaimsSet claims = JwtClaimsSet.builder()
.subject(username)
.claim("roles", List.of("USER"))
.issuedAt(Instant.now())
.expiresAt(Instant.now().plus(1, ChronoUnit.HOURS))
.build();
return this.jwtEncoder.encode(JwtEncoderParameters.from(claims)).getTokenValue();
}
Переваги та недоліки
Переваги
- Безстанність (Statelessness): Відсутність управління сесіями на стороні сервера.
2.
Масштабованість (Scalability): Токени можна перевіряти незалежно.
- Сумісність (Interoperability): OAuth2 та JWT — це широко підтримувані стандарти.
Недоліки
-
Відкликання токенів (Token Revocation): Безстанні токени складно відкликати.
-
Складність (Complexity): Налаштування інфраструктури OAuth2 — це не просте завдання.
-
Ризики безпеки (Security Risks): Погане зберігання токенів або їх витік може призвести до вразливостей.
Кращі практики
-
Використовуйте HTTPS: Завжди шифруйте комунікацію.
-
Короткоживучі токени (Short-Lived Tokens): Зменшуйте ризик зловживання токенами.
-
Refresh токени: Використовуйте refresh токени для довгоживучих сесій.
-
Перевірка токенів (Token Validation): Уважно перевіряйте підписи та претензії.
-
Мінімальні привілеї (Least Privilege): Обмежуйте scopes лише тим, що необхідно.
Висновок
OAuth2 та JWT забезпечують надійні механізми для захисту мікросервісів. Хоча налаштування може бути складним, переваги в масштабованості, сумісності та безпеці роблять їх незамінними для сучасних розподілених систем. Дотримуючись кращих практик і використовуючи інструменти, як-от Spring Security, ви можете забезпечити безпечну та ефективну архітектуру мікросервісів.
Перекладено з: Building Secure Microservices: OAuth2 and JWT in Action