SpringBoot实战(三十四)集成 spring-security-oauth2(OAuth2的4个角色、5种认证方式、demo集成)

06-01 1512阅读

目录

    • 一、简介
      • 1.1 什么是 OAuth2 协议?
      • 1.2 OAuth2 的4个角色
      • 1.3 OAuth2 的3种令牌
      • 1.4 OAuth2 的5种认证方式
      • 1.5 OAuth2 内置接口地址
      • 二、项目集成过程
        • 2.1 Maven依赖
        • 2.2 springboot-oauth2-server 授权服务器模块搭建和配置
          • 1)目录结构
          • 2)SecurityConfig——授权服务器的 Security 配置
          • 3)AuthorizationConfig——授权服务器的 Authorize 配置
          • 4)yml配置
          • 5)授权服务器验证
            • 获取token方式一:授权码模式
            • 获取token方式二:密码模式
            • 2.3 springboot-oauth2-client 资源服务器模块搭建和配置
              • 1)目录结构
              • 2)ResourceConfig——资源服务器配置
              • 3)yml配置
              • 4)DemoController——模拟接口资源
              • 5)资源服务器验证

                一、简介

                1.1 什么是 OAuth2 协议?

                OAuth2(Open Authorization 2.0) 协议是 RFC 6749 文件,是一种 用于授权的开放标准协议,用于通过第三方应用程序访问用户在某个服务提供商上存储的资源,而无需共享用户的凭证(例如用户名和密码)。

                OAuth 引入了一个授权层,用来分离两种不同的角色:客户端和资源所有者。…资源所有者同意以后,资源服务器可以向客户端颁发令牌。客户端通过令牌,去请求数据。

                OAuth2.0 的运行流程如下图所示:

                SpringBoot实战(三十四)集成 spring-security-oauth2(OAuth2的4个角色、5种认证方式、demo集成)

                (A)用户打开客户端以后,客户端要求用户给予授权。

                (B)用户同意给予客户端授权。

                (C)客户端使用上一步获得的授权,向认证服务器申请令牌。

                (D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。

                (E)客户端使用令牌,向资源服务器申请获取资源。

                (F)资源服务器确认令牌无误,同意向客户端开放资源。

                简而言之:你要获取我(资源服务器)的资源的话,得先找他(授权服务器)授权。

                1.2 OAuth2 的4个角色

                OAuth2.0 认证过程中,涉及到的四个角色如下 :

                • 客户端(Client):代表资源所有者与授权服务器进行交互的应用程序。可以是Web应用程序、移动应用程序或第三方服务。
                • 资源所有者(Resource Owner):即用户或系统的代表,拥有受保护资源的所有权。
                • 授权服务器(Authorization Server):负责验证资源所有者的身份并颁发访问令牌(Access Token)给客户端。它通常是一个独立的服务器,可以与资源服务器分离或合并。
                • 资源服务器(Resource Server):存储受保护的资源,并根据令牌的有效性进行访问控制。资源服务器可以是一个或多个服务,可以授权服务器分离或合并。

                  1.3 OAuth2 的3种令牌

                  • 授权许可(Authorization Grant):资源所有者授权客户端访问受保护资源的凭证,如:授权码、隐式授权、密码授权、客户端凭证等。
                  • 令牌(Access Token):用于标识授权许可的凭证,包括访问令牌、刷新令牌和身份令牌等。
                  • 令牌端点(Token Endpoint):客户端与授权服务器交互以获取或刷新令牌的API端点。

                    1.4 OAuth2 的5种认证方式

                    OAuth2.0 提供了五种认证方式:

                    授权类型grant_type 值适用场景安全性
                    授权码模式authorization_code有后端的 Web 应用
                    简化模式implicit纯前端应用(如 SPA)
                    密码模式password高度信任的客户端(如第一方应用)
                    客户端凭证模式client_credentials客户端访问自己的资源(M2M)
                    刷新令牌模式refresh_token获取新的访问令牌

                    这里我们举例的是 授权码模式,篇幅有限,没有集成数据库。如果需要支持其他模式,需要对 AuthorizationConfig.java 中的内容进行改造。

                    1.5 OAuth2 内置接口地址

                    OAuth2.0 内置了6个接口地址,如下所示:

                    • /oauth/authorize:授权端点(核心)
                    • /oauth/token:获取令牌端点(核心)
                    • /oauth/confirm_access:用户确认授权提交端点
                    • /oauth/error:授权服务错误信息端点
                    • /oauth/check_token:用于资源服务访问的令牌解析端点
                    • /oauth/token_key:提供公有密匙的端点,如果你使用JWT令牌的话

                      二、项目集成过程

                      在示例项目中,包含两个部分:

                      1. springboot-oauth2-server:授权服务器
                      2. springboot-oauth2-client:资源服务器

                      整体项目目录结构如下:

                      SpringBoot实战(三十四)集成 spring-security-oauth2(OAuth2的4个角色、5种认证方式、demo集成)

                      2.1 Maven依赖

                      
                          org.springframework.boot
                          spring-boot-starter-security
                      
                      
                      
                          org.springframework.security.oauth
                          spring-security-oauth2
                          2.2.1.RELEASE
                      
                      
                      
                          io.jsonwebtoken
                          jjwt
                          0.6.0
                      
                      

                      2.2 springboot-oauth2-server 授权服务器模块搭建和配置

                      1)目录结构

                      授权服务器目录结构如下:

                      SpringBoot实战(三十四)集成 spring-security-oauth2(OAuth2的4个角色、5种认证方式、demo集成)

                      2)SecurityConfig——授权服务器的 Security 配置

                      授权服务器的 Spring Security 配置代码如下:

                      import org.springframework.context.annotation.Bean;
                      import org.springframework.context.annotation.Configuration;
                      import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
                      import org.springframework.security.config.annotation.web.builders.HttpSecurity;
                      import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
                      import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
                      import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
                      import org.springframework.security.crypto.password.PasswordEncoder;
                      /**
                       * Spring Security 配置
                       */
                      @Configuration
                      @EnableWebSecurity
                      public class SecurityConfig extends WebSecurityConfigurerAdapter {
                          @Bean
                          public PasswordEncoder passwordEncoder() {
                              return new BCryptPasswordEncoder();
                          }
                          @Override
                          protected void configure(AuthenticationManagerBuilder auth) throws Exception {
                              auth.inMemoryAuthentication()
                                      .withUser("zhangsan")
                                      .password(passwordEncoder().encode("123456"))
                                      .authorities("/*");
                          }
                          @Override
                          public void configure(HttpSecurity http) throws Exception {
                              http.authorizeRequests()
                                      .anyRequest().authenticated()
                                      .and()
                                      .httpBasic()
                                      .and()
                                      .csrf()
                                      .disable();
                          }
                      }
                      
                      3)AuthorizationConfig——授权服务器的 Authorize 配置

                      授权服务器的 Authorize 相关配置如下:

                      (@EnableAuthorizationService 注解切记需要配置哈。)

                      import org.springframework.beans.factory.annotation.Autowired;
                      import org.springframework.security.crypto.password.PasswordEncoder;
                      import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
                      import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
                      import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
                      import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
                      import org.springframework.stereotype.Component;
                      /**
                       * Spring OAuth2 配置
                       */
                      @Component
                      @EnableAuthorizationServer
                      public class AuthorizationConfig extends AuthorizationServerConfigurerAdapter {
                          @Autowired
                          private PasswordEncoder passwordEncoder;
                          /**
                           * 对应于配置AuthorizationServer安全认证的相关信息,创建ClientCredentialsTokenEndpointFilter核心过滤器
                           */
                          @Override
                          public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
                              security.allowFormAuthenticationForClients()
                                      .checkTokenAccess("permitAll()");
                          }
                          /**
                           * 配置客户端详情(Client Details)
                           * @param clients 用于配置客户端信息的工具类
                           */
                          @Override
                          public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
                              clients.inMemory()
                                      .withClient("security_appid")
                                      .secret(passwordEncoder.encode("security_secret"))
                                      .authorizedGrantTypes("authorization_code")
                                      .scopes("all")
                                      .resourceIds("security_resource")
                                      .redirectUris("https://www.baidu.com/callback");
                          }
                      }
                      
                      4)yml配置
                      server:
                      	port: 8110
                      
                      5)授权服务器验证

                      这里我们采用两种模式进行验证:授权码模式、密码模式。

                      获取token方式一:授权码模式

                      启动授权服务器后,请求如下地址:

                      • http://localhost:8110/oauth/authorize?client_id=security_appid&response_type=code

                        /oauth/authorize 是 OAuth 框架封装的请求,网络请求路径必须像上面这样。其中 client_id 必须是我们在 Authorize 中 withClient 配置的数据,否则会报错。

                        输入上面的请求后,会被 Security 框架资源拦截,需要先进行登录。输入我们在 Security 中配置的账号密码:zhangsan/123456。

                        SpringBoot实战(三十四)集成 spring-security-oauth2(OAuth2的4个角色、5种认证方式、demo集成)

                        这是登录后的结果:

                        SpringBoot实战(三十四)集成 spring-security-oauth2(OAuth2的4个角色、5种认证方式、demo集成)

                        选择 同意 后,会出现跳转到 https://www.baidu.com/callback 目录并且会进行数据回调,如下所示:(注意这里在地址栏生成的 code,下一步会用到)

                        SpringBoot实战(三十四)集成 spring-security-oauth2(OAuth2的4个角色、5种认证方式、demo集成)

                        接下来,我们使用 PostMan 请求 /oauth/token 接口来获取 Token 令牌。下面这些请求参数很重要,注意是 POST 请求方式。

                        SpringBoot实战(三十四)集成 spring-security-oauth2(OAuth2的4个角色、5种认证方式、demo集成)

                        获取token方式二:密码模式

                        不同的认证方式我们需要设置不同的 grant_type 值,具体参数如下所示:

                        SpringBoot实战(三十四)集成 spring-security-oauth2(OAuth2的4个角色、5种认证方式、demo集成)

                        可以看到,两种方式都成功获取了 access_token,这样授权服务器就结束了。

                        2.3 springboot-oauth2-client 资源服务器模块搭建和配置

                        1)目录结构

                        资源服务器目录结构如下:

                        SpringBoot实战(三十四)集成 spring-security-oauth2(OAuth2的4个角色、5种认证方式、demo集成)

                        2)ResourceConfig——资源服务器配置

                        代码如下:

                        (注意,这里的 setCheckTokenEndpointUrl() 需要和授权服务器的配置相匹配才行。)

                        import org.springframework.context.annotation.Bean;
                        import org.springframework.context.annotation.Configuration;
                        import org.springframework.context.annotation.Primary;
                        import org.springframework.security.config.annotation.web.builders.HttpSecurity;
                        import org.springframework.security.config.http.SessionCreationPolicy;
                        import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
                        import org.springframework.security.crypto.password.PasswordEncoder;
                        import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
                        import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
                        import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
                        import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
                        /**
                         * 资源服务器配置
                         */
                        @Configuration
                        @EnableResourceServer
                        public class ResourceConfig extends ResourceServerConfigurerAdapter {
                            @Bean
                            public PasswordEncoder passwordEncoder() {
                                return new BCryptPasswordEncoder();
                            }
                            @Bean
                            @Primary
                            public RemoteTokenServices remoteTokenServices() {
                                RemoteTokenServices remoteTokenServices = new RemoteTokenServices();
                                remoteTokenServices.setCheckTokenEndpointUrl("http://localhost:8110/oauth/check_token");
                                remoteTokenServices.setClientId("security_appid");
                                remoteTokenServices.setClientSecret("security_secret");
                                return remoteTokenServices;
                            }
                            @Override
                            public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
                                resources.resourceId("security_resource").stateless(true);
                            }
                            @Override
                            public void configure(HttpSecurity http) throws Exception {
                                http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
                                http.authorizeRequests().anyRequest().authenticated();
                            }
                        }
                        
                        3)yml配置
                        server:
                        	port: 8111
                        
                        4)DemoController——模拟接口资源
                        import com.demo.common.Result;
                        import org.springframework.web.bind.annotation.RequestMapping;
                        import org.springframework.web.bind.annotation.ResponseBody;
                        import org.springframework.web.bind.annotation.RestController;
                        /**
                         * 

                        @Title DemoController *

                        @Description 测试Controller * * @author ACGkaka * @date 2025/2/7 11:46 */ @RestController public class DemoController { @RequestMapping("test") @ResponseBody public Result test() { return Result.succeed(); } }

                        5)资源服务器验证

                        资源服务器启动之后,我们请求上面创建的接口地址:

                        • http://localhost:8111/demo

                          可以看到,请求失败,在没有携带token的情况下会被鉴权拦截,返回 401 状态码,如下所示:

                          SpringBoot实战(三十四)集成 spring-security-oauth2(OAuth2的4个角色、5种认证方式、demo集成)

                          我们在请求头中加入上面在授权服务器中获取的token,就可以 成功访问资源 了,如下所示:

                          SpringBoot实战(三十四)集成 spring-security-oauth2(OAuth2的4个角色、5种认证方式、demo集成)

                          整理完毕,完结撒花~🌻





                          参考地址:

                          1.【Spring底层原理高级进阶】【SpringCloud整合Spring Security OAuth2】深入了解 Spring Security OAuth2:底层解析+使用方法+实战,https://cloud.tencent.com/developer/article/2392742

                          2.Oauth2详解-介绍(一),https://www.jianshu.com/p/84a4b4a1e833

                          3.SpringBoot整合Oauth2快速入门(入坑),https://blog.csdn.net/weixin_45982841/article/details/114378146

                          4.Spring Cloud Security OAuth2 中实现密码模式,https://cloud.tencent.com/developer/article/2264281

                          5.OAuth 2.0 的四种方式,http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html

                          6.SpringBoot整合spring-security-oauth2完整实现例子,https://cloud.tencent.com/developer/article/1786077

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码