• Spring Security 自定义资源服务器实践


    相关文章:

    1. OAuth2的定义和运行流程
    2. Spring Security OAuth实现Gitee快捷登录
    3. Spring Security OAuth实现GitHub快捷登录
    4. Spring Security的过滤器链机制
    5. Spring Security OAuth Client配置加载源码分析
    6. Spring Security内置过滤器详解
    7. 为什么加载了两个OAuth2AuthorizationRequestRedirectFilter分析
    8. Spring Security 自定义授权服务器实践

    前言

    在前面我们使用最小化配置的方式搭建了自己的授权服务器,现在我们依旧用最小化的方式配置自己的资源服务器。
    资源服务器负责scope的鉴权、authorities的鉴权、基于用户角色的鉴权等。

    最小化配置

    安装资源服务器

    1、 新建一个Spring Boot项目,命名为spring-security-resource-server
    2、引入pom.xml依赖

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-securityartifactId>
    dependency>
    
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-oauth2-resource-serverartifactId>
    dependency>
    
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    其中与授权服务器依赖不同的是,资源服务器有spring boot版本,版本号会有spring boot进行管理,不需要显示声明。

    配置资源服务器

    1、配置application.yml 文件

    spring:
      security:
        oauth2:
          resourceserver:
            jwt:
              issuer-uri: http://localhost:9000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    该配置用于指定授权服务器地址,资源服务器将从该地址获取JWT令牌,并根据JWT中的属性进一步自我配置,发现授权服务器的公钥、验证JWT令牌。

    2、创建配置类

    @EnableWebSecurity(debug = true)
    public class ResoruceServerConfig {
    
        @Bean
        SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
            http
                    .authorizeRequests()
                    .mvcMatchers("/userinfo/**").hasAuthority("SCOPE_userinfo")
                    .and()
                    .oauth2ResourceServer()
                    .jwt();
            return http.build();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    .mvcMatchers("/userinfo/**").hasAuthority("SCOPE_userinfo")匹配/userinfo/**地址,允许访问范围是SCOPE_userinfo
    oauth2ResourceServer()定义为资源服务器
    jwt()使用JWT令牌

    3、 创建一个资源接口
    /userinfo/用来获取资源所有者基本信息

    @Data
    public class UserInfoRes {
    
        private String username;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    创建Rest接口

    @RestController
    public class UserInfoController {
    
        @GetMapping("/userinfo")
        public UserInfoRes getUserInfo() {
            UserInfoRes userInfoRes = new UserInfoRes();
            userInfoRes.setUsername("阿提说说");
            return userInfoRes;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    配置客户端

    目前我们客户端的配置是这样的:

    spring:
      security:
        oauth2:
          client:
            registration:
              gitee:
                client-id: gitee_clientId
                client-secret: gitee_secret
                authorization-grant-type: authorization_code
                redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
                client-name: Gitee
              github:
                client-id: github_clientId
                client-secret: github_secret
              # 自定义
              customize:
                client-id: testClientId
                client-secret: testClientSecret
                authorization-grant-type: authorization_code
                redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
                client-name: Customize
                scope:
                  - userinfo
            provider:
              gitee:
                authorization-uri: https://gitee.com/oauth/authorize
                token-uri: https://gitee.com/oauth/token
                user-info-uri: https://gitee.com/api/v5/user
                user-name-attribute: name
              # 自定义
              customize:
                authorization-uri: http://localhost:9000/oauth2/authorize
                token-uri: http://localhost:9000/oauth2/token
                user-info-uri: http://localhost:9000/userinfo
                user-name-attribute: username
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    这里我们只需要修改customize部分的user-info-uriuser-name-attribute
    调整后配置如下,其他部分跟原来是一样的。

              customize:
                authorization-uri: http://localhost:9000/oauth2/authorize
                token-uri: http://localhost:9000/oauth2/token
                user-info-uri: http://localhost:8090/userinfo
                user-name-attribute: username
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ❗ user-name-attribute的名字,必须在user-info-uri返回的属性名中存在

    整流程体验

    在如上三部分配置完成后,就可以体验了,启动spring-security-resource-serverspring-security-authorization-serverspring-security-oauth2-client

    浏览器访问地址:http://127.0.0.1:8080/hello,在授权完成后,即跳转回并显示结果。

    image.png
    ResourceServer下能看到带着token的/userinfo请求日志。

    ************************************************************
    
    Request received for GET '/userinfo':
    
    org.apache.catalina.connector.RequestFacade@3418bfc9
    
    servletPath:/userinfo
    pathInfo:null
    headers: 
    accept: application/json
    authorization: Bearer eyJraWQiOiI5YjZjZWMzNi05ZDYyLTRkMWMtOWRiNi0wMWM1ODQzMDc1N2UiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwiYXVkIjoidGVzdENsaWVudElkIiwibmJmIjoxNjYwOTU1ODQyLCJzY29wZSI6WyJ1c2VyaW5mbyJdLCJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3Q6OTAwMCIsImV4cCI6MTY2MDk1NjE0MiwiaWF0IjoxNjYwOTU1ODQyfQ.gVWwwfzB-xNuWWUBpgGokIOy5xwV9Wkd05k3rqpk1h92b-TWENB4ZArEL--zpngSyE8iuml0vG3veCv647FDx_EY56ClM-UxH-3Wq0D2f3b6WTgFO5RpCCwRLCHahBlV5g9plr7hWYY5uX2cQ4MsC4-ltZSR6wga5LSLDB-bIK46ZmJ3DOaQFwTTCpWB4OgOuq1j59i9XkgDUc_I8WUsHB4eEDEbBJeOmdimDn5O1Ux6nDhPgLMLcpnrt3lHLmXDTk8Q7hX7YBynO2VBm6wkTeYP4a2rfinfhW-LtF1o3hm8QAY0hn1QKSEeWU5K5qiIOVeSJ5FqrYJ_VQPadT1qAQ
    user-agent: Java/11
    host: localhost:8090
    connection: keep-alive
    
    
    Security filter chain: [
      DisableEncodeUrlFilter
      WebAsyncManagerIntegrationFilter
      SecurityContextPersistenceFilter
      HeaderWriterFilter
      CsrfFilter
      LogoutFilter
      BearerTokenAuthenticationFilter
      RequestCacheAwareFilter
      SecurityContextHolderAwareRequestFilter
      AnonymousAuthenticationFilter
      SessionManagementFilter
      ExceptionTranslationFilter
      FilterSecurityInterceptor
    ]
    
    
    ************************************************************
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    总结

    到此,我们通过自己搭建的授权服务器和资源服务器,完整体验了OAuth2流程,再来体会下第一篇文章中说明的交互流程。
    在这里插入图片描述

    在整个流程中,我们使用的是最严密的授权码模式,它将用户引导到授权服务器进行身份验证,授权服务器将发放的访问令牌传递给客户端,目前主流都是使用该模式,因此特别重要,要好好体会

    在这里插入图片描述

    源代码地址:https://github.com/jujunchen/21Study

  • 相关阅读:
    sqlite3数据库
    总是留不住客户怎么办?这三点每多做一点,回头客翻一倍!
    深入剖析Sgementation fault原理
    Go 企业级框架 Beego 版全新发布
    44、Map
    Javascript 手写 LRU 算法
    【LaTex】如何输入英文字母的花体字?花体字最全总结
    通过 MSE 实现基于Apache APISIX的全链路灰度
    办公技巧:Excel日常高频使用技巧
    【力扣题:循环队列】
  • 原文地址:https://blog.csdn.net/weixin_40972073/article/details/126446735