基于Spring Security 6的OAuth2 系列之五 - 授权服务器--开篇

之所以想写这一系列,是因为之前工作过程中使用Spring Security OAuth2搭建了网关和授权服务器,但当时基于spring-boot 2.3.x,其默认的Spring Security是5.3.x。之后新项目升级到了spring-boot 3.3.0,结果一看Spring Security也升级为6.3.0。无论是Spring Security的风格和以及OAuth2都做了较大改动,里面甚至将授权服务器模块都移除了,导致在配置同样功能时,花费了些时间研究新版本的底层原理,这里将一些学习经验分享给大家。

注意由于框架不同版本改造会有些使用的不同,因此本次系列中使用基本框架是 spring-boo-3.3.0(默认引入的Spring Security是6.3.0),JDK版本使用的是19,本系列OAuth2的代码采用Spring Security6.3.0框架,所有代码都在oauth2-study项目上:https://github.com/forever1986/oauth2-study.git

上一篇我们讲到了作为客户端去找第三方授权服务器,这一章开始我们来讲讲我们自己搭建授权服务器。

1 Spring Authrization Server

早期版本的时候,Spring Security 5.3.x版本里面有一个OAuth模块,里面是包括授权服务器的,但是在2019年时,却被官方移除。这就造成原先使用Spring Security搭建的授权服务器将无法升级到Spring Security 6。不过好在Spring Security官方在收到很多不满抗议后,重新推出一个叫Spring Authrization Server,不过该项目已经不在Spring Security下面。我们从下图的Spring官方就可以看出来:

在这里插入图片描述

现在Spring Authrization Server是一个独立的项目,但是其实还是脱离不了Spring Security,因为你会发现引入Spring Authrization Server就会自动引入Spring Security,并且也是使用Spring Security的Filter链方式。话不多说,讲完背景,我们开始做一个入门示例

2 自定义授权服务器

代码参考lesson02子模块,其中该子模块有2个子模块,分别是:oauth-server和oauth-client,他们分别代表oauth的授权服务器和oauth的客户端。

2.1 oauth-server(授权服务器)

代码参考oauth-server子模块

1)在lesson02子模块下,新建oauth-server子模块,其pom引入依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-oauth2-authorization-server</artifactId>
    </dependency>
</dependencies>

2)在resources新建application.yml,从官方demo抄一下配置:

server:
  port: 9000

logging:
  level:
    org.springframework.security: trace

spring:
  security:
    # 使用security配置授权服务器的登录用户和密码
    user:
      name: user
      password: 1234
    oauth2:
      authorizationserver:
        # 客户端应用注册,这里就类似我们在gitee上面注册自己的应用一样
        client:
          # 客户端名称
          oidc-client:
            registration:
              # 客户端id
              client-id: "oidc-client"
              # 客户端secret
              client-secret: "{noop}secret"
              # 客户端验证方法
              client-authentication-methods:
                - "client_secret_basic"
              # 授权模式-这里使用授权码模式
              authorization-grant-types:
                - "authorization_code"
                - "refresh_token"
              # 回调地址
              redirect-uris:
                # 注意,该url在此版本中不能使用127.0.0.1,需要在host中配置域名映射,此处使用localhost
                - "http://localhost:8080/login/oauth2/code/oidc-client"
              # 客户端首页
              post-logout-redirect-uris:
                # 注意,该url在此版本中不能使用127.0.0.1,需要在host中配置域名映射,此处使用localhost
                - "http://localhost:8080/"
              # 授权范围
              scopes:
                # 用户唯一标识
                - "openid"
                # 用户信息
                - "profile"
            # 是否需要授权确认
            require-authorization-consent: true

3)新建启动了Oauth2Lesson02ServerApplication,并启动项目

@SpringBootApplication
public class Oauth2Lesson02ServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(Oauth2Lesson02ServerApplication.class, args);
    }

}

2.2 oauth-client(客户端)

代码参考oauth-client子模块

1)oauth-client子模块,其pom引入依赖(oauth-client子模块基本上抄lesson01子模块,只是其中配置和Controller略微修改)

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-client</artifactId>
    </dependency>
</dependencies>

2)在resources包下,新建application.yml,配置如下:

spring:
  application:
    name: oauth-client

  security:
    oauth2:
      client:
        registration:
          oidc-client:
            # 注册应用后的Client ID,这里对应oauth-server的client-id
            clientId: oidc-client
            # 注册应用后的Client Secret,这里对应oauth-server的client-secret
            clientSecret: secret
            # 授权码模式
            authorizationGrantType: authorization_code
            # 回调地址,这里对应oauth-server的redirect-uris
            redirectUri: http://localhost:8080/login/oauth2/code/oidc-client
            # 授权访问
            scope:
              - openid
              - profile
            # 应用的provider,注意,这个名称可以随便命名,但是必须与下面的provider保持一致
            provider: myserverprovider
        provider:
          myserverprovider:
            # 自建认证授权地址,之所以采用不同域名是为了防止Cookie覆盖问题
            authorizationUri: http://oauth-server:9000/oauth2/authorize
            # 自建认证获取access_token地址,之所以采用不同域名是为了防止Cookie覆盖问题
            tokenUri: http://oauth-server:9000/oauth2/token
            # 验证JWT签名,之所以采用不同域名是为了防止Cookie覆盖问题
            jwkSetUri: http://oauth-server:9000/oauth2/jwks

3)先电脑的host文件,配置如下域名映射:

127.0.0.1       localhost oauth-server

4)在config包下面,创建SecurityConfig配置类

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
        // 所有访问必须认证
        http.authorizeHttpRequests(auth->auth.anyRequest().authenticated());
        // 默认采用oauth2Login登录
        http.oauth2Login(Customizer.withDefaults());
        return http.build();
    }
}

5)在controller包下面,新建OAuth2LoginController作为测试接口

@RestController
public class OAuth2LoginController {

    // http://localhost:8080/demo
    @GetMapping("/demo")
    public String demo() {
        return "demo";
    }
}

6)新建启动类Oauth2Lesson02ClientApplication,并启动项目

@SpringBootApplication
public class Oauth2Lesson02ClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(Oauth2Lesson02ClientApplication.class, args);
    }

}

2.3 测试

1)打开浏览器,访问:http://localhost:8080/demo 将会自动跳转到http://oauth-server:9000/login (这一步和我们系列3中跳转到gitee的登录界面一样)

在这里插入图片描述

2)输入登录账号密码,我们在oauth-server配置了user和1234。这时候就会跳转如下地址,其实和我们系列2一样,调整到授权页面
在这里插入图片描述
授权页面:
在这里插入图片描述
3)确认授权之后,调整到oauth-client的demo接口,返回demo字符串
在这里插入图片描述

4)从上面过程,我们已经搭建完最简单的授权服务器,也是使用授权码模式。从代码中,我们的授权服务器只是做了yaml配置,并没有其它代码,就可以建立一个授权服务器,哪些授权地址,token地址是怎么来的,访问流程是什么,Spring Authrization Server默认为我们做了什么?接下来,我们来初步了解一下。

3 自动化配置原理

1)自动化配置那么最先找的当然是spring-boot-autoconfigure。我们发现有一个OAuth2AuthorizationServerAutoConfiguration,该类里面有两个比较重要的子配置:OAuth2AuthorizationServerConfigurationOAuth2AuthorizationServerWebSecurityConfiguration
在这里插入图片描述

2)下面我们先来看OAuth2AuthorizationServerConfiguration这个类:第一个propertiesMapper就解释了为什么我们在yaml文件做配置会被读取到;第二个RegisteredClientRepository也就是会从yaml文件中注册一个客户端应用;第三个AuthorizationServerSettings就是配置授权服务器访问端点;

在这里插入图片描述

3)我们再看看AuthorizationServerSettings,里面有一个builder,就是初始化默认的端口配置,这就是为什么我们在客户端配置的获取code、token和jwks的接口是怎么来的,就是这里配置的。
在这里插入图片描述

4)再回到OAuth2AuthorizationServerAutoConfiguration,我们来看看另外一个配置类OAuth2AuthorizationServerWebSecurityConfiguration。如下图,熟悉的味道又来了,配置了两条Filter链路,一条是配置授权服务器,一条是配置Security。这就解释我们访问授权服务器时,要先登录,而登陆就是Security的配置。而配置授权服务器的Filter链路就是对授权服务器的配置,这个Filter我们后续再细讲,这里知道其原因即可。

在这里插入图片描述

5)从这几个基本的自动配置类,我们大概了解一下几个点:

  • spring boot自动配置,会读取yaml文件,并将yaml文件的配置设置到授权服务器和Spring Security的配置Filter里面
  • 授权服务器也是配置一条Filter链路,但是这条Filter链路与Spring Security的Filter链路是分开的。如果我们要自定义,那么就要自定义授权服务器的Filter链路
  • 客户端应用注册可以通过RegisteredClientRepository进行注册,目前看其继承类,也是有内存和数据库两种模式

结语:到目前为止,我们搭建了自己一个授权服务器,并验证成功。也初步了解Spring Boot为我们做了哪些自动化配置。窥探了Spring Authrization Server的配置方法,那么接下来几章,我们将讲一下Spring Authrization Server的相关配置,并了解其原理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

linmoo1986

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值