整合SpringSecurity OAuth2 JWT (附原因)一步步来如此简单

原创
2022/11/14 21:18
阅读数 303

梳理整合 SpringCloud 和 SpringSecurity OAuth2 的搭建流程,网上看了一些,感觉都很差强人意,所以决定梳理下,不多说了开鲁吧。

首先要搭建微服务基础加包版本,基于阿里系微服务架构:

  1. 创建 parent 项目,避免组件冲突加包版本必须选择好,不然后续很麻烦,一切源于《官方

    每个 Spring Cloud Alibaba 版本及其自身所适配的各组件对应版本如下表所示(注意,Spring Cloud Dubbo 从 2021.0.1.0 起已被移除出主干,不再随主干演进):

    Spring Cloud Alibaba Version Sentinel Version Nacos Version RocketMQ Version Dubbo Version Seata Version

    2.2.9.RELEASE

    1.8.5

    2.1.0

    4.9.4

    ~

    1.5.2

    2021.0.4.0

    1.8.5

    2.0.4

    4.9.4

    ~

    1.5.2

    2.2.8.RELEASE

    1.8.4

    2.1.0

    4.9.3

    ~

    1.5.1

    2021.0.1.0

    1.8.3

    1.4.2

    4.9.2

    ~

    1.4.2

    2.2.7.RELEASE

    1.8.1

    2.0.3

    4.6.1

    2.7.13

    1.3.0

    2.2.6.RELEASE

    1.8.1

    1.4.2

    4.4.0

    2.7.8

    1.3.0

    所以选择:(大家搭建项目的时候最好在看下版本支持)

    2.2.7.RELEASE

    1.8.1

    2.0.3

    4.6.1

    2.7.13

    1.3.0

    源码:
                <spring-boot.version>2.3.12.RELEASE</spring-boot.version>
    		    <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
    		    <spring-cloud-alibaba.version>2.2.7.RELEASE</spring-cloud-alibaba.version>
    
                <dependency>
    				<groupId>org.springframework.cloud</groupId>
    				<artifactId>spring-cloud-dependencies</artifactId>
    				<version>${spring-cloud.version}</version>
    				<type>pom</type>
    				<scope>import</scope>
    			</dependency>
    			<dependency>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-dependencies</artifactId>
    				<version>${spring-boot.version}</version>
    				<type>pom</type>
    				<scope>import</scope>
    			</dependency>
    			<dependency>
    				<groupId>com.alibaba.cloud</groupId>
    				<artifactId>spring-cloud-alibaba-dependencies</artifactId>
    				<version>${spring-cloud-alibaba.version}</version>
    				<type>pom</type>
    				<scope>import</scope>
    			</dependency>
    
    
  2. 创建相关服务:
            auth:认证服务(客服端认证,用户认证,登录鉴权,发放 token)
            admin:后台管理系统(后台用户管理,客服端管理,用户角色权限组织架构管理)
            gateway:网关(路由分发,token 验证、权限校验拦截)
  3. 配置 auth 服务
  4. ①:创建聚合工程项目 POM 为,并创建 2 个 model
      • <?xml version="1.0" encoding="UTF-8"?>
        <project xmlns="http://maven.apache.org/POM/4.0.0"
        	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        	<modelVersion>4.0.0</modelVersion>
        	<parent>
        		<groupId>com.gitee.zydaas</groupId>
        		<artifactId>zy-parent</artifactId>
        		<version>1.0.0</version>
        	</parent>
        
        	<artifactId>zy-auth</artifactId>
        	<packaging>pom</packaging>
        	<version>1.0.0-SNAPSHOT</version>
        
        	<modules>
        		<module>zy-auth-api</module>
        		<module>zy-auth-boot</module>
        	</modules>
        </project>
    • zy-auth-api POM
      <dependencies>
      		<dependency>
      			<groupId>com.gitee.zydaas</groupId>
      			<artifactId>zy-common-core</artifactId>
      			<version>${project.version}</version>
      		</dependency>
      		<!-- openfeign依赖 1. http客户端选择okhttp 2. loadbalancer替换ribbon -->
      		<dependency>
      			<groupId>org.springframework.cloud</groupId>
      			<artifactId>spring-cloud-starter-openfeign</artifactId>
      		</dependency>
      		<dependency>
      			<groupId>io.github.openfeign</groupId>
      			<artifactId>feign-okhttp</artifactId>
      		</dependency>
      	</dependencies>

      这个比较简单都 rpc 或者 HTTP 的接口,这主要是 openfeign 的接口

    •  创建 zy-auth-boot 

      <dependencies>
      		<dependency>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-starter-web</artifactId>
      		</dependency>
      		<dependency>
      			<groupId>org.springframework.cloud</groupId>
      			<artifactId>spring-cloud-starter-oauth2</artifactId>
      		</dependency>
      		
      		<dependency>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-starter-security</artifactId>
      		</dependency>
      		<!--安全模块-->
              <dependency>
                  <groupId>org.springframework.security.oauth.boot</groupId>
                  <artifactId>spring-security-oauth2-autoconfigure</artifactId>
              </dependency>
      		
      		<dependency>
      			<groupId>com.nimbusds</groupId>
      			<artifactId>nimbus-jose-jwt</artifactId>
      		</dependency>
      
      		<dependency>
      			<groupId>com.alibaba.cloud</groupId>
      			<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
      		</dependency>
      		
      		<!-- 本项目包 -->
      		<dependency>
      			<groupId>com.gitee.zydaas</groupId>
      			<artifactId>zy-common-redis</artifactId>
      			<version>${project.version}</version>
      		</dependency>
      		<dependency>
      			<groupId>com.gitee.zydaas</groupId>
      			<artifactId>zy-auth-api</artifactId>
      			<version>${project.version}</version>
      		</dependency>
      		<dependency>
      			<groupId>com.gitee.zydaas</groupId>
      			<artifactId>zy-admin-api</artifactId>
      			<version>${project.version}</version>
      		</dependency>
      	</dependencies>
      	
      	<build>
      		<plugins>
      			<plugin>
      				<groupId>org.springframework.boot</groupId>
      				<artifactId>spring-boot-maven-plugin</artifactId>
      			</plugin>
      		</plugins>
      	</build>
    •  zy-auth-boot 加入配置进入授权码模式
      ①:oauht2 核心配置:AuthorizationServerConfig
      @Configuration
      @EnableAuthorizationServer
      public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
      
      }

      ②:加入 security 核心配置:WebSecurityConfig 

      @Configuration
      @EnableWebSecurity
      public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
      
      }
      
      ③:测试授权端:   http://localhost:8000/oauth/authorize?response_type=code&client_id=client&secret=123456&redirect_uri=http://baidu.com&scope=all

      出现如下界面:

      输出随机账户密码是出错的

    • 配置本地授权认证信息
      ①配置加密工具类:WebSecurityConfig 中
          /**
           * 密码编码器
           * 委托方式,根据密码的前缀选择对应的encoder,例如:{bcypt}前缀->标识BCYPT算法加密;{noop}->标识不使用任何加密即明文的方式
           * 密码判读 DaoAuthenticationProvider#additionalAuthenticationChecks
           * @author kinbug
           */
          @Bean
          public PasswordEncoder passwordEncoder() {
              return PasswordEncoderFactories.createDelegatingPasswordEncoder();
          }

      ②配置默认认证用户信息:WebSecurityConfig 中

      @Autowired
          public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
              auth.inMemoryAuthentication().withUser("admin").password(passwordEncoder().encode("123456")).roles("USER","ADMIN").authorities(AuthorityUtils.commaSeparatedStringToAuthorityList("p1,p2"));
              //这里配置全局用户信息
          }

      ③配置默认端的认证信息:AuthorizationServerConfig 中

      @Autowired
      PasswordEncoder passwordEncoder;
      
      @Override
      public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
      
      	//基于内存便于测试
      	clients.inMemory()// 使用in-memory存储
      			.withClient("client")// client_id
      			.secret(passwordEncoder.encode("123456"))//加密
      			.authorizedGrantTypes("authorization_code", "password", "client_credentials", "implicit", "refresh_token")// 该client允许的授权类型authorization_code,password,refresh_token,implicit,client_credentials
      			.scopes("all", "ROLE_ADMIN", "ROLE_USER")// 允许的授权范围
      			.redirectUris("http://baidu.com");//加上验证回调地址
      }
      

      ④再测试(重启后)http://localhost:8000/oauth/authorize?response_type=code&client_id=client&secret=123456&redirect_uri=http://baidu.com&scope=all
      输入账户密码线上界面:

      点击授权调到百度:链接为:https://www.baidu.com/?code=WNfcWW   code 不一样哈
      ⑤获取用户授权后的 Token:
      header 中加入:key:Authorization  值:Basic Y2xpZW50OjEyMzQ1Ng==(值怎么来的呢)如下:

      System.out.println("Basic " + new String(Base64.getEncoder().encode("client:123456".getBytes())));	

      body 参数如下:

      看到这授权码模式就结束了

    • 秘密模式:
      ①:在 WebSecurityConfig 中认证交给 AuthenticationManager

          /**
           * AuthenticationManager
           * <p>
           * 如果不声明,会导致授权服务器无AuthenticationManager,
           * 密码模式:而password方式无法获取token
           * @author kinbug
           */
        	@Bean
        	@Override
          public AuthenticationManager authenticationManagerBean() throws Exception {
              return super.authenticationManagerBean();
          }

      ②:Auth 认证可以秘密模式:AuthorizationServerConfig 中 

      	@Autowired
          private AuthenticationManager authenticationManager;
      
      	@Override
          public void configure(AuthorizationServerEndpointsConfigurer endpoints) {//配置令牌的访问端点和令牌服务
              endpoints.authenticationManager(authenticationManager)//认证管理器
                     ;
          }
      

      ③:测试秘密登录:
      header 遇见验证码授权登录一样
      登录获取 token 如下:

      密码登录授权完成

    • 后面就是如何替换本地的认证信息

  5. 获取源码:请先关注公众号,发送: auth01

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部