梳理整合 SpringCloud 和 SpringSecurity OAuth2 的搭建流程,网上看了一些,感觉都很差强人意,所以决定梳理下,不多说了开鲁吧。
首先要搭建微服务基础加包版本,基于阿里系微服务架构:
- 创建 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>
- 创建相关服务:
auth:认证服务(客服端认证,用户认证,登录鉴权,发放 token)
admin:后台管理系统(后台用户管理,客服端管理,用户角色权限组织架构管理)
gateway:网关(路由分发,token 验证、权限校验拦截) - 配置 auth 服务
- ①:创建聚合工程项目 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 { }
出现如下界面:
输出随机账户密码是出错的 - 配置本地授权认证信息
①配置加密工具类: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 如下:
密码登录授权完成 -
后面就是如何替换本地的认证信息
-
-
获取源码:请先关注公众号,发送: auth01