Shaw0xyz 发表于 2024-6-3 12:21:30

SpringCloud之SSO单点登录-基于Gateway和OAuth2的跨系统统一认证和鉴权详解

本帖最后由 Shaw0xyz 于 2024-6-9 13:56 编辑

1. 引言

在微服务架构中,各个服务之间通常是独立部署的。然而,当用户需要在多个服务之间切换时,每次都要求重新认证将极大影响用户体验。为了解决这一问题,单点登录(Single Sign-On, SSO)技术应运而生。本文将介绍如何使用SpringCloud、Gateway和OAuth2实现跨系统的统一认证和鉴权。

1.1 单点登录概述

单点登录(SSO)是一种用户认证方式,用户只需一次登录,即可访问所有相互信任的应用系统。SSO的主要优点包括:

(1) 用户体验提升:用户只需一次登录即可访问所有应用。
(2) 安全性提高:集中管理用户身份,便于实施安全策略。
(3) 管理效率提高:简化用户认证和授权的管理流程。

1.2 SpringCloud和OAuth2

SpringCloud是一套构建分布式系统的工具集,而OAuth2是一种开放标准,用于令牌认证和授权。通过结合SpringCloud和OAuth2,可以方便地实现微服务架构下的单点登录功能。

2. 环境准备

在开始实现SSO之前,需要准备以下环境和工具:

(1) JDK 1.8及以上版本
(2) SpringBoot 2.3.0及以上版本
(3) SpringCloud Hoxton及以上版本
(4) Redis,用于存储会话信息
(5) 一个IDE,如IntelliJ IDEA

2.1 创建基础项目

首先,使用Spring Initializr创建一个SpringBoot项目,并添加以下依赖:

(1) Spring Web
(2) Spring Security
(3) Spring Security OAuth2
(4) Spring Cloud Gateway
(5) Spring Data Redis

3. 实现OAuth2认证服务

OAuth2认证服务负责用户的认证和令牌的签发。

3.1 配置认证服务

在application.yml文件中配置OAuth2认证服务:

server:
port: 8080
spring:
application:
    name: auth-service
datasource:
    url: jdbc:mysql://localhost:3306/auth_db
    username: root
    password: password
redis:
    host: localhost
    port: 6379
security:
    oauth2:
      client:
      registration:
          custom-client:
            client-id: client
            client-secret: secret
            scope: read,write
            authorization-grant-type: authorization_code
            redirect-uri: http://localhost:8080/login/oauth2/code/custom-client

3.2 实现授权服务器

创建一个授权服务器配置类:

import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    // 配置授权服务器
}

3.3 配置Web安全

创建一个WebSecurity配置类:

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
      http
            .authorizeRequests()
            .antMatchers("/login", "/oauth/authorize").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin().permitAll();
    }
}

4. 配置Gateway服务

Gateway服务作为微服务的统一入口,负责请求路由和统一认证。

4.1 配置Gateway

在application.yml文件中配置Gateway:

server:
port: 8081
spring:
application:
    name: gateway-service
cloud:
    gateway:
      routes:
      - id: auth-service
          uri: lb://auth-service
          predicates:
            - Path=/auth/**
      - id: other-service
          uri: lb://other-service
          predicates:
            - Path=/other/**
      globalcors:
      cors-configurations:
          '[/**]':
            allowedOrigins: "*"
            allowedMethods:
            - GET
            - POST
            - PUT
            - DELETE

4.2 配置Security过滤器

创建一个GatewaySecurity配置类:

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class GatewaySecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
      http
            .authorizeRequests()
            .antMatchers("/auth/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .oauth2Login();
    }
}

5. 统一认证和鉴权

在实现了认证服务和Gateway服务之后,我们需要实现跨系统的统一认证和鉴权。

5.1 使用Redis存储会话信息

在认证服务中配置Redis:

import org.springframework.context.annotation.Configuration;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

@Configuration
@EnableRedisHttpSession
public class RedisConfig {
    // Redis配置
}

5.2 配置跨系统鉴权

在各个微服务中配置资源服务器:

import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    // 配置资源服务器
}

6. 结论

通过本文的讲解,我们了解了如何使用SpringCloud、Gateway和OAuth2实现跨系统的单点登录和统一鉴权。通过配置OAuth2认证服务和Gateway服务,我们实现了统一的用户认证和授权管理,提高了系统的安全性和用户体验。在实际应用中,可以根据具体需求进行进一步的优化和扩展,以满足更多的业务场景。



/ 荔枝学姐de课后专栏 /

Hi!这里是荔枝学姐~

欢迎来到我的课后专栏

自然语言学渣 NLP摆烂姐

热衷于技术写作 IT边角料

AIGC & Coding & Linux ...

~互撩~ TG: @Shaw_0xyz
页: [1]
查看完整版本: SpringCloud之SSO单点登录-基于Gateway和OAuth2的跨系统统一认证和鉴权详解