如何编写spring cloud oauth2用户认证登录的示例代码?

2026-05-15 23:301阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2003个文字,预计阅读时间需要9分钟。

如何编写spring cloud oauth2用户认证登录的示例代码?

在微服务架构中,我们拥有众多业务模块,每个模块都需用户认证和权限验证。有时还会接入第三方厂商的应用。我们希望实现一次性登录,即可在各个服务的授权范围内进行操作。

需求

在微服务架构中,我们有很多业务模块,每个模块都需要有用户认证,权限校验。有时候也会接入来自第三方厂商的应用。要求是只登录一次,即可在各个服务的授权范围内进行操作。看到这个需求,立马就想到了这不就是单点登录吗?于是基于这样的需求,作者使用spring-cloud-oauth2去简单的实现了下用户认证和单点登录。

相关介绍

OAuth2

OAuth2是一个关于授权的网络标准,他定制了设计思路和执行流程。OAuth2一共有四种授权模式:授权码模式(authorization code)、简化模式(implicit)、密码模式(resource owner password)和客户端模式(client credentials)。数据的所有者告诉系统同意授权第三方应用进入系统,获取这些数据。于是数据所有者生产了一个短时间内有效的授权码(token)给第三方应用,用来代替密码,供第三方使用。具体流程请看下图,具体的OAuth2介绍,可以参考这篇文章,写的很详细。(www.jb51.net/article/198292.htm)

Token

令牌(token)和密码(password)的作用是一样的,都可以进入系统获取资源,但是也有几点不同:

  1. 令牌是短期的,到期会自动失效,用户无法修改。密码是长期的,用户可以修改,如果不修改,就不会发生变化。
  2. 令牌可以被数据所有者撤销,令牌会立即失效。密码一般不允许其他人撤销,只能被操作权限更高的人或者本人修改/重制。
  3. 令牌是有权限范围的,会被数据所有者授予。

实现的功能

本篇介绍的是通过密码模式来实现单点登录的功能。

​ 在微服务架构中,我们的一个应用可能会有很多个服务运行,协调来处理实际的业务。这就需要用到单点登录的技术,来统一认证调取接口的是哪个用户。那总不能请求一次,就认证一次,这么做肯定是不行的。那么就需要在认证完用户之后,给这个用户授权,然后发一个令牌(token),有效期内用户请求资源时,就只需要带上这个标识自己身份的token即可。

架构说明
认证中心:oauth2-oauth-server,OAuth2的服务端,主要完成用户Token的生成、刷新、验证等。

微服务:mzh-etl,微服务之一,接收到请求之后回到认证中心(oauth2-oauth-server)去验证。

代码实现

使用到的框架是java基础的spring boot 和spring-cloud-oauth2

认证中心:

1、引入需要的maven包

<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-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>

因为spring-cloud-starter-oauth2中包含了spring-cloud-starter-security,所以就不用再单独引入了,引入redis包是为了使用redis来存储token。

2、配置application.yml

这里主要用到的是redis的配置,mysql数据库的配置暂时没有用到。

spring: application: name: oauth-server datasource: url: jdbc:mysql://localhost:3306/mzh_oauth?useSSL=false&characterEncoding=UTF-8 username: root password: admin123 driver-class-name: com.mysql.jdbc.Driver hikari: connection-timeout: 30000 idle-timeout: 600000 max-lifetime: 1800000 maximum-pool-size: 9 redis: database: 0 host: localhost port: 6379 jedis: pool: max-active: 8 max-idle: 8 min-idle: 0 timeout: 10000 server: port: 8888 use-forward-headers: true management: endpoint: health: enabled: true

3、spring security 权限配置

需要继承WebSecurityConfigurerAdapter

/** * @Author mzh * @Date 2020/10/24 */ @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private CustomUserDetailsService customUserDetailsService; /** * 修改密码的加密方式 * @return */ @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception{ return super.authenticationManagerBean(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception{ // 如果使用BCryptPasswordEncoder,这里就必须指定密码的加密类 auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder()); } @Override protected void configure(HttpSecurity localhost:8888/oauth/token?grant_type=password&username=admin&password=123456&scope=all Accept: */* Cache-Control: no-cache Authorization: Basic dXNlci1jbGllbnQ6dXNlci1zZWNyZXQtODg4OA==

第一行POST localhost:8888/oauth/token?grant_type=password&username=admin&password=123456&scope=all 表示发起一个POST请求,请求路径是/oauth/token,请求参数是grant_type=password表示认证类型是password,username=admin&password=123456表示用户名是admin,密码是123456,scope=all是权限相关的,之前在Oauth2Config中配置了scope是all。

第四行表示在请求头中加入一个字段Authorization,值为Basic空格base64(clientId:clientSecret),我们之前配置的clientId是“meh-etl”,clientSecret是"meh-etl-8888",所以这个值的base64是:bXpoLWV0bDptemgtZXRsLTg4ODg=。

运行请求之后,如果参数都正确的话,获取到返回的内容如下:

{ // token值,后面请求接口时都需要带上的token "access_token": "b4cb804c-93d2-4635-913c-265ff4f37309", // token的形式 "token_type": "bearer", // 快过期时可以用这个换取新的token "refresh_token": "5cac05f4-158f-4561-ab16-b06c4bfe899f", // token的过期时间 "expires_in": 3599, // 权限范围 "scope": "all" }

token值过期之后,可以通过refresh_token来换取新的access_token

POST localhost:8888/oauth/token?grant_type=refresh_token&refresh_token=706dac10-d48e-4795-8379-efe8307a2282 Accept: */* Cache-Control: no-cache Authorization: Basic dXNlci1jbGllbnQ6dXNlci1zZWNyZXQtODg4OA==

这次grant_type的值为“refresh_token”,refresh_token的值是要过期的token的refresh_token值,也就是之前请求获取Token的refresh_token值,请求之后会返回一个和获取token时一样格式的数据。

微服务

1、引入需要的maven包

<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-data-redis</artifactId> </dependency>

2、配置application.yml

spring: application: name: mzh-etl redis: database: 1 host: localhost port: 6379 jedis: pool: max-active: 8 max-idle: 8 min-idle: 0 timeout: 10000 server: port: 8889 security: oauth2: client: # 需要和之前认证中心配置中的一样 client-id: mzh-etl client-secret: mzh-etl-8888 # 获取token的地址 access-token-uri: localhost:8888/oauth/token resource: id: mzh-etl user-info-uri: user-info authorization: # 检查token的地址 check-token-access: localhost:8888/oauth/check_token

这里的配置一定要仔细,必须和之前认证中心中配置的一样。

3、资源配置

在OAuth2中接口也称为资源,资源的权限也就是接口的权限。spring-cloud-oauth2提供了关于资源的注解

@EnableResourceServer /** * @Author mzh * @Date 2020/10/24 */ @Configuration @EnableResourceServer @EnableGlobalMethodSecurity(prePostEnabled = true) public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Value("${security.oauth2.client.client-id}") private String clientId; @Value("${security.oauth2.client.client-secret}") private String clientSecret; @Value("${security.oauth2.authorization.check-token-access}") private String checkTokenEndpointUrl; @Autowired private RedisConnectionFactory redisConnectionFactory; @Bean("redisTokenStore") public TokenStore redisTokenStore(){ return new RedisTokenStore(redisConnectionFactory); } @Bean public RemoteTokenServices tokenService() { RemoteTokenServices tokenService = new RemoteTokenServices(); tokenService.setClientId(clientId); tokenService.setClientSecret(clientSecret); tokenService.setCheckTokenEndpointUrl(checkTokenEndpointUrl); return tokenService; } @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.tokenServices(tokenService()); } @Override public void configure(HttpSecurity localhost:8889/get Accept: */* Cache-Control: no-cache Authorization: bearer b4cb804c-93d2-4635-913c-265ff4f37309

请求路径是localhost:8889/get 然后在请求头部带上我们上一步骤获取到的token,放入到Authorization中,格式是bearer空格token值,如果请求成功,就会把token原样返回。

如何编写spring cloud oauth2用户认证登录的示例代码?

到此这篇关于spring cloud oauth2 实现用户认证登录的示例代码的文章就介绍到这了,更多相关spring cloud oauth2 认证登录内容请搜索易盾网络以前的文章或继续浏览下面的相关文章希望大家以后多多支持易盾网络!

本文共计2003个文字,预计阅读时间需要9分钟。

如何编写spring cloud oauth2用户认证登录的示例代码?

在微服务架构中,我们拥有众多业务模块,每个模块都需用户认证和权限验证。有时还会接入第三方厂商的应用。我们希望实现一次性登录,即可在各个服务的授权范围内进行操作。

需求

在微服务架构中,我们有很多业务模块,每个模块都需要有用户认证,权限校验。有时候也会接入来自第三方厂商的应用。要求是只登录一次,即可在各个服务的授权范围内进行操作。看到这个需求,立马就想到了这不就是单点登录吗?于是基于这样的需求,作者使用spring-cloud-oauth2去简单的实现了下用户认证和单点登录。

相关介绍

OAuth2

OAuth2是一个关于授权的网络标准,他定制了设计思路和执行流程。OAuth2一共有四种授权模式:授权码模式(authorization code)、简化模式(implicit)、密码模式(resource owner password)和客户端模式(client credentials)。数据的所有者告诉系统同意授权第三方应用进入系统,获取这些数据。于是数据所有者生产了一个短时间内有效的授权码(token)给第三方应用,用来代替密码,供第三方使用。具体流程请看下图,具体的OAuth2介绍,可以参考这篇文章,写的很详细。(www.jb51.net/article/198292.htm)

Token

令牌(token)和密码(password)的作用是一样的,都可以进入系统获取资源,但是也有几点不同:

  1. 令牌是短期的,到期会自动失效,用户无法修改。密码是长期的,用户可以修改,如果不修改,就不会发生变化。
  2. 令牌可以被数据所有者撤销,令牌会立即失效。密码一般不允许其他人撤销,只能被操作权限更高的人或者本人修改/重制。
  3. 令牌是有权限范围的,会被数据所有者授予。

实现的功能

本篇介绍的是通过密码模式来实现单点登录的功能。

​ 在微服务架构中,我们的一个应用可能会有很多个服务运行,协调来处理实际的业务。这就需要用到单点登录的技术,来统一认证调取接口的是哪个用户。那总不能请求一次,就认证一次,这么做肯定是不行的。那么就需要在认证完用户之后,给这个用户授权,然后发一个令牌(token),有效期内用户请求资源时,就只需要带上这个标识自己身份的token即可。

架构说明
认证中心:oauth2-oauth-server,OAuth2的服务端,主要完成用户Token的生成、刷新、验证等。

微服务:mzh-etl,微服务之一,接收到请求之后回到认证中心(oauth2-oauth-server)去验证。

代码实现

使用到的框架是java基础的spring boot 和spring-cloud-oauth2

认证中心:

1、引入需要的maven包

<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-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>

因为spring-cloud-starter-oauth2中包含了spring-cloud-starter-security,所以就不用再单独引入了,引入redis包是为了使用redis来存储token。

2、配置application.yml

这里主要用到的是redis的配置,mysql数据库的配置暂时没有用到。

spring: application: name: oauth-server datasource: url: jdbc:mysql://localhost:3306/mzh_oauth?useSSL=false&characterEncoding=UTF-8 username: root password: admin123 driver-class-name: com.mysql.jdbc.Driver hikari: connection-timeout: 30000 idle-timeout: 600000 max-lifetime: 1800000 maximum-pool-size: 9 redis: database: 0 host: localhost port: 6379 jedis: pool: max-active: 8 max-idle: 8 min-idle: 0 timeout: 10000 server: port: 8888 use-forward-headers: true management: endpoint: health: enabled: true

3、spring security 权限配置

需要继承WebSecurityConfigurerAdapter

/** * @Author mzh * @Date 2020/10/24 */ @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private CustomUserDetailsService customUserDetailsService; /** * 修改密码的加密方式 * @return */ @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception{ return super.authenticationManagerBean(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception{ // 如果使用BCryptPasswordEncoder,这里就必须指定密码的加密类 auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder()); } @Override protected void configure(HttpSecurity localhost:8888/oauth/token?grant_type=password&username=admin&password=123456&scope=all Accept: */* Cache-Control: no-cache Authorization: Basic dXNlci1jbGllbnQ6dXNlci1zZWNyZXQtODg4OA==

第一行POST localhost:8888/oauth/token?grant_type=password&username=admin&password=123456&scope=all 表示发起一个POST请求,请求路径是/oauth/token,请求参数是grant_type=password表示认证类型是password,username=admin&password=123456表示用户名是admin,密码是123456,scope=all是权限相关的,之前在Oauth2Config中配置了scope是all。

第四行表示在请求头中加入一个字段Authorization,值为Basic空格base64(clientId:clientSecret),我们之前配置的clientId是“meh-etl”,clientSecret是"meh-etl-8888",所以这个值的base64是:bXpoLWV0bDptemgtZXRsLTg4ODg=。

运行请求之后,如果参数都正确的话,获取到返回的内容如下:

{ // token值,后面请求接口时都需要带上的token "access_token": "b4cb804c-93d2-4635-913c-265ff4f37309", // token的形式 "token_type": "bearer", // 快过期时可以用这个换取新的token "refresh_token": "5cac05f4-158f-4561-ab16-b06c4bfe899f", // token的过期时间 "expires_in": 3599, // 权限范围 "scope": "all" }

token值过期之后,可以通过refresh_token来换取新的access_token

POST localhost:8888/oauth/token?grant_type=refresh_token&refresh_token=706dac10-d48e-4795-8379-efe8307a2282 Accept: */* Cache-Control: no-cache Authorization: Basic dXNlci1jbGllbnQ6dXNlci1zZWNyZXQtODg4OA==

这次grant_type的值为“refresh_token”,refresh_token的值是要过期的token的refresh_token值,也就是之前请求获取Token的refresh_token值,请求之后会返回一个和获取token时一样格式的数据。

微服务

1、引入需要的maven包

<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-data-redis</artifactId> </dependency>

2、配置application.yml

spring: application: name: mzh-etl redis: database: 1 host: localhost port: 6379 jedis: pool: max-active: 8 max-idle: 8 min-idle: 0 timeout: 10000 server: port: 8889 security: oauth2: client: # 需要和之前认证中心配置中的一样 client-id: mzh-etl client-secret: mzh-etl-8888 # 获取token的地址 access-token-uri: localhost:8888/oauth/token resource: id: mzh-etl user-info-uri: user-info authorization: # 检查token的地址 check-token-access: localhost:8888/oauth/check_token

这里的配置一定要仔细,必须和之前认证中心中配置的一样。

3、资源配置

在OAuth2中接口也称为资源,资源的权限也就是接口的权限。spring-cloud-oauth2提供了关于资源的注解

@EnableResourceServer /** * @Author mzh * @Date 2020/10/24 */ @Configuration @EnableResourceServer @EnableGlobalMethodSecurity(prePostEnabled = true) public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Value("${security.oauth2.client.client-id}") private String clientId; @Value("${security.oauth2.client.client-secret}") private String clientSecret; @Value("${security.oauth2.authorization.check-token-access}") private String checkTokenEndpointUrl; @Autowired private RedisConnectionFactory redisConnectionFactory; @Bean("redisTokenStore") public TokenStore redisTokenStore(){ return new RedisTokenStore(redisConnectionFactory); } @Bean public RemoteTokenServices tokenService() { RemoteTokenServices tokenService = new RemoteTokenServices(); tokenService.setClientId(clientId); tokenService.setClientSecret(clientSecret); tokenService.setCheckTokenEndpointUrl(checkTokenEndpointUrl); return tokenService; } @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.tokenServices(tokenService()); } @Override public void configure(HttpSecurity localhost:8889/get Accept: */* Cache-Control: no-cache Authorization: bearer b4cb804c-93d2-4635-913c-265ff4f37309

请求路径是localhost:8889/get 然后在请求头部带上我们上一步骤获取到的token,放入到Authorization中,格式是bearer空格token值,如果请求成功,就会把token原样返回。

如何编写spring cloud oauth2用户认证登录的示例代码?

到此这篇关于spring cloud oauth2 实现用户认证登录的示例代码的文章就介绍到这了,更多相关spring cloud oauth2 认证登录内容请搜索易盾网络以前的文章或继续浏览下面的相关文章希望大家以后多多支持易盾网络!