返回

分布式微服务的统一认证和授权指南

后端

在现代分布式系统架构中,认证和授权对于保护数据和确保应用安全至关重要。Spring Cloud Gateway作为API网关,提供了对微服务进行统一认证和授权的便捷方式,从而简化了开发人员的工作。

理解OAuth2.0

OAuth2.0是一种行业标准协议,用于授权第三方应用访问用户数据。它基于委派授权模型,允许用户授予应用访问其个人信息的权限,而无需分享其密码。

集成OAuth2.0到Spring Cloud Gateway

要将OAuth2.0集成到Spring Cloud Gateway中,需要完成以下步骤:

  1. 在Spring Cloud Gateway配置中启用OAuth2.0支持。
  2. 定义OAuth2.0资源服务器,指定受保护的资源。
  3. 定义OAuth2.0授权服务器,管理令牌颁发和验证。
  4. 配置网关过滤器,以强制执行OAuth2.0认证和授权。

实战案例:Spring Cloud Gateway整合OAuth2.0

本文将展示如何通过Spring Cloud Gateway整合OAuth2.0,实现分布式统一认证和授权。

项目结构

- gateway
 - pom.xml
 - application.yml
 - security-config.xml
- auth-server
 - pom.xml
 - application.yml
 - SecurityConfig.java

网关配置

在gateway项目的application.yml中,启用OAuth2.0支持:

spring:
  cloud:
    gateway:
      globalcors:
        allow-credentials: true
        allowed-methods: "*"
        allowed-headers: "*"
        max-age: 3600
    security:
      oauth2:
        resourceserver:
          jwt:
            issuer-uri: http://localhost:8081/auth/realms/spring-cloud-gateway

security-config.xml中,定义资源服务器:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/security"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
  <security:http>
    <security:oauth2-resource-server id="resourceServer" type="opaque">
      <security:authentication-manager>
        <security:oauth2-authentication-provider id="oidcAuthenticationProvider">
          <security:oidc-client-registration-repository id="clientRegistrationRepository"/>
          <security:jwt-decoder id="jwtDecoder"/>
        </security:oauth2-authentication-provider>
      </security:authentication-manager>
    </security:oauth2-resource-server>
  </security:http>
</beans>

认证服务器配置

在auth-server项目的application.yml中,配置授权服务器:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: http://localhost:8081/auth/realms/spring-cloud-gateway
      authorization:
        oidc:
          provider:
            spring-cloud-gateway:
              issuer-uri: http://localhost:8081/auth/realms/spring-cloud-gateway

SecurityConfig.java中,定义用户详情服务和授权管理器:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  @Bean
  public PasswordEncoder passwordEncoder() {
    return NoOpPasswordEncoder.getInstance();
  }

  @Bean
  @Override
  public UserDetailsService userDetailsService() {
    InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
    manager.createUser(User.withUsername("admin").password("password").authorities("USER", "ADMIN").build());
    return manager;
  }

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService());
  }

  @Bean
  @Override
  public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
  }
}

网关过滤器配置

在gateway项目的application.yml中,配置网关过滤器:

spring:
  cloud:
    gateway:
      routes:
        - id: auth-service
          uri: http://localhost:8082
          predicates: [Path=/auth/**]
          filters:
            - OAuth2AuthorizeHeader
            - OAuth2TokenRelay
            - OAuth2ClientCredentialsGrant
        - id: protected
          uri: http://localhost:8083
          predicates: [Path=/protected/**]
          filters:
            - OAuth2AuthorizeHeader
            - OAuth2TokenRelay
            - OAuth2ClientCredentialsGrant
            - OAuth2ResourceServer

运行应用

  1. 启动授权服务器:mvn spring-boot:run -Dspring.profiles.active=auth-server
  2. 启动网关:mvn spring-boot:run -Dspring.profiles.active=gateway
  3. 启动受保护的微服务:mvn spring-boot:run -Dspring.profiles.active=resource-server

测试认证和授权

使用浏览器或Postman访问受保护的微服务(/protected/**)。在首次访问时,您将被重定向到授权服务器的登录页面。输入有效凭据后,您将收到一个令牌,并被重定向回受保护的微服务。

结论

通过将OAuth2.0与Spring Cloud Gateway集成,可以轻松实现分布式微服务的统一认证和授权。这种方法提供了高级别的安全性,同时简化了开发流程,让开发人员专注于业务逻辑而不是安全细节。