如何具体实现Spring Security OAuth2的授权码模式?
- 内容介绍
- 文章标签
- 相关推荐
本文共计2089个文字,预计阅读时间需要9分钟。
在前言中,我们简要介绍了OAuth 2.0的概念及授权流程。在此,我们深入探讨OAuth 2.0的授权模式,并准备几个demo进行演示。一方面,总结我们最近的学习心得;另一方面,进行知识输出。
写在前边
在文章OAuth 2.0 概念及授权流程梳理 中我们谈到OAuth 2.0的概念与流程,这里我准备分别记一记这几种授权模式的demo,一方面为自己的最近的学习做个总结,另一方面做下知识输出,如果文中有错误的地方,请评论指正,在此不胜感激
受众前提
阅读本文,默认读者已经过Spring Security有一定的了解,对OAuth2流程有一定了解
本文目标
带领读者对Spring Security OAuth2框架的授权码模式有一个比较直观的概念,能使用框架搭建授权码模式授权服务器与资源服务器(分离版本)
授权码模式流程回顾
授权码模式要求:用户登录并对第三方应用(客户端)进行授权,出示授权码交给客户端,客户端凭授权码换取access_token(访问凭证)
此模式要求授权服务器与用户直接交互,在此过程中,第三方应用是无法获取到用户输入的密码等信息的,这个模式也是OAuth 2.0中最安全的一个
Demo基本结构
这里主要关注authorization-code-authorization-server与authorization-code-resource-server这两个模块
本文以及后续文章的demo均放在GitHub上,欢迎大家Star & Fork,源码地址:github.com/hellxz/spring-security-oauth2-learn
authorization-code-client-resttemplate-jdbc这个项目是用来测试非OAuth2服务使用RestTemplate与JdbcTemplate对接OAuth2授权服务的,流程这里不讲,有兴趣可以debug看看,可能会让您对整个流程会有更清晰的感受
Maven依赖
<!--Spring Security--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!--Spring Boot Starter Web 所有demo均使用web--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring Security OAuth2 --> <dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> <version>${spring-security-oauth2.version}</version> </dependency>
搭建授权服务器(Authorization Server)
文中服务器均使用demo级别配置,请勿直接使用到生产环境
授权服务器结构主体如下:
启动类自不多说,先说下SecurityConfig
package com.github.hellxz.oauth2.config; 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; import java.util.Collections; @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // @formatter: off auth.inMemoryAuthentication() .withUser("hellxz") .password(passwordEncoder().encode("xyz")) .authorities(Collections.emptyList()); // @formatter: on } @Override protected void configure(HttpSecurity localhost:9001/callback"); //回调地址 // @formatter: on } }
1.通过@Configuration 和EnableAuthorizationServer开启授权服务器配置,通过重写AuthorizationServerConfigurerAdapter的方法来完成自定义授权服务器
2.OAuth2授权码模式中,要求不仅仅用户需要登录,还要求客户端也需要登录,这里就需要在configure(ClientDetailsServiceConfigurer clients)这个方法中配置客户端(第三方应用)的登录信息,
withClient中配置的是客户端id(client_id)
secret为客户端的密码,要求使用加密器进行加密
授权码的authorizedGrantTypes必须配置有"authorization_code"(授权码模式),这里是可以同时支持多种授权模式的,为了简单只写一个
scopes,请求资源作用域,用于限制客户端与用户无法访问没有作用域的资源
resourceIds,可选,资源id,可以对应一个资源服务器,个人理解为某个资源服务器的所有资源标识
redirectUris,回调地址,有两个作用:1.回调客户端地址,返回授权码; 2.校验是否是同一个客户端
redirectUris校验是否同一个客户端这个,可能说的不是很准确,说下大体流程,我们在授权服务器上配置了这个回调地址,授权服务器在用户授权成功后,返回授权码的地址就是它,另外我们后续申请token时,也需要传递这个回调地址,所以我的理解是校验是否是同一客户端发来的第二次请求(换token时)
3.configure(AuthorizationServerSecurityConfigurer security)这里配置资源客户端(第三方应用)的表单提交权限,类似Spring Security配置的permitAll()等权限控制标识,如果不配置,客户端将无法换取token
4.application.properties
这里我只配置了server.port=8080
这样我们就配置了相当简易的授权服务器,启动测试下
获取授权码的流程,一般是由客户端使用自己的client_id与密码+response_type=code拼接url,让浏览器跳转完成的,用户的登录与授权过程都需要在浏览器中完成,启动项目后访问下列url
localhost:8080/oauth/authorize?client_id=client-a&client_secret=client-a-secret&response_type=code
登录用户/密码: hellxz/xyz ,选择Approve表示接受授权,Deny反之,如下动图所示
最后我们得到了回调地址localhost:9001/callback?code=2e6450
这里的code就是授权码,接下来我们使用授权码进行换取token
POST请求,localhost:8080/oauth/token,参数如图
BasicAuth:这里填的是客户端配置的client_id和client_secret的值,相当于curl --user client_id:client_secret,配置后会在Header中添加Authorization:Basic Y2xpZW50LWE6Y2xpZW50LWEtc2VjcmV0,Basic空格 后的是client_id:client_secret具体值被Base64后得到的值
请求参数列表:
- code=授权码
- grant_type=authorization_code
- redirect_uri=回调url ,要与配置处和获取授权码处相同
- scope=作用域
最后我们获得了授权服务的响应,包含token的json
{ "access_token": "99435e13-f9fe-438a-a94e-3b00d549b329", //访问token "token_type": "bearer", //token类型,使用时需要拼接在token前并在token前加空格 "expires_in": 43199, //过期时间 "scope": "read_user_info" //作用域 }
在access_token未过期之前,同一个用户名使用同一个客户端访问都会是同一个access_token
授权服务器先放在这里,不要关服,接下来搭建资源服务器
搭建资源服务器(Resource Server)
资源服务器结构
入口类不多说,先搭建资源服务器主要配置,这里直接使用ResourceConfig进行配置
package com.github.hellxz.oauth2.config; 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.localhost:8080/oauth/check_token"); //设置客户端id与secret,注意:client_secret值不能使用passwordEncoder加密! tokenServices.setClientId("client-a"); tokenServices.setClientSecret("client-a-secret"); return tokenServices; } @Override public void configure(HttpSecurity localhost:8081/user/hellxz001
Bearer Token相当于在Headers中添加Authorization:Bearer空格access_token
至此我们成功的搭建并测试了授权码模式下的最简单的授权服务与资源服务分离的demo
尾声
授权码模式就先在这里告一段落,写的比较基础,自认为该说到的点都说到了,后续还会写其它模式的文章,如文中有何遗漏,请不吝评论反馈,本人会尽快改正,谢谢
本文以及后续文章的demo均放在GitHub上,欢迎大家Star & Fork,源码地址:github.com/hellxz/spring-security-oauth2-learn ,Demo中的README文档写得比较详细,也可堪一看
原文出处www.cnblogs.com/hellxz/p/oauth2_oauthcode_pattern.html
到此这篇关于Spring Security OAuth2 授权码模式的实现的文章就介绍到这了,更多相关Spring Security OAuth2 授权码模式内容请搜索易盾网络以前的文章或继续浏览下面的相关文章希望大家以后多多支持易盾网络!
本文共计2089个文字,预计阅读时间需要9分钟。
在前言中,我们简要介绍了OAuth 2.0的概念及授权流程。在此,我们深入探讨OAuth 2.0的授权模式,并准备几个demo进行演示。一方面,总结我们最近的学习心得;另一方面,进行知识输出。
写在前边
在文章OAuth 2.0 概念及授权流程梳理 中我们谈到OAuth 2.0的概念与流程,这里我准备分别记一记这几种授权模式的demo,一方面为自己的最近的学习做个总结,另一方面做下知识输出,如果文中有错误的地方,请评论指正,在此不胜感激
受众前提
阅读本文,默认读者已经过Spring Security有一定的了解,对OAuth2流程有一定了解
本文目标
带领读者对Spring Security OAuth2框架的授权码模式有一个比较直观的概念,能使用框架搭建授权码模式授权服务器与资源服务器(分离版本)
授权码模式流程回顾
授权码模式要求:用户登录并对第三方应用(客户端)进行授权,出示授权码交给客户端,客户端凭授权码换取access_token(访问凭证)
此模式要求授权服务器与用户直接交互,在此过程中,第三方应用是无法获取到用户输入的密码等信息的,这个模式也是OAuth 2.0中最安全的一个
Demo基本结构
这里主要关注authorization-code-authorization-server与authorization-code-resource-server这两个模块
本文以及后续文章的demo均放在GitHub上,欢迎大家Star & Fork,源码地址:github.com/hellxz/spring-security-oauth2-learn
authorization-code-client-resttemplate-jdbc这个项目是用来测试非OAuth2服务使用RestTemplate与JdbcTemplate对接OAuth2授权服务的,流程这里不讲,有兴趣可以debug看看,可能会让您对整个流程会有更清晰的感受
Maven依赖
<!--Spring Security--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!--Spring Boot Starter Web 所有demo均使用web--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring Security OAuth2 --> <dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> <version>${spring-security-oauth2.version}</version> </dependency>
搭建授权服务器(Authorization Server)
文中服务器均使用demo级别配置,请勿直接使用到生产环境
授权服务器结构主体如下:
启动类自不多说,先说下SecurityConfig
package com.github.hellxz.oauth2.config; 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; import java.util.Collections; @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // @formatter: off auth.inMemoryAuthentication() .withUser("hellxz") .password(passwordEncoder().encode("xyz")) .authorities(Collections.emptyList()); // @formatter: on } @Override protected void configure(HttpSecurity localhost:9001/callback"); //回调地址 // @formatter: on } }
1.通过@Configuration 和EnableAuthorizationServer开启授权服务器配置,通过重写AuthorizationServerConfigurerAdapter的方法来完成自定义授权服务器
2.OAuth2授权码模式中,要求不仅仅用户需要登录,还要求客户端也需要登录,这里就需要在configure(ClientDetailsServiceConfigurer clients)这个方法中配置客户端(第三方应用)的登录信息,
withClient中配置的是客户端id(client_id)
secret为客户端的密码,要求使用加密器进行加密
授权码的authorizedGrantTypes必须配置有"authorization_code"(授权码模式),这里是可以同时支持多种授权模式的,为了简单只写一个
scopes,请求资源作用域,用于限制客户端与用户无法访问没有作用域的资源
resourceIds,可选,资源id,可以对应一个资源服务器,个人理解为某个资源服务器的所有资源标识
redirectUris,回调地址,有两个作用:1.回调客户端地址,返回授权码; 2.校验是否是同一个客户端
redirectUris校验是否同一个客户端这个,可能说的不是很准确,说下大体流程,我们在授权服务器上配置了这个回调地址,授权服务器在用户授权成功后,返回授权码的地址就是它,另外我们后续申请token时,也需要传递这个回调地址,所以我的理解是校验是否是同一客户端发来的第二次请求(换token时)
3.configure(AuthorizationServerSecurityConfigurer security)这里配置资源客户端(第三方应用)的表单提交权限,类似Spring Security配置的permitAll()等权限控制标识,如果不配置,客户端将无法换取token
4.application.properties
这里我只配置了server.port=8080
这样我们就配置了相当简易的授权服务器,启动测试下
获取授权码的流程,一般是由客户端使用自己的client_id与密码+response_type=code拼接url,让浏览器跳转完成的,用户的登录与授权过程都需要在浏览器中完成,启动项目后访问下列url
localhost:8080/oauth/authorize?client_id=client-a&client_secret=client-a-secret&response_type=code
登录用户/密码: hellxz/xyz ,选择Approve表示接受授权,Deny反之,如下动图所示
最后我们得到了回调地址localhost:9001/callback?code=2e6450
这里的code就是授权码,接下来我们使用授权码进行换取token
POST请求,localhost:8080/oauth/token,参数如图
BasicAuth:这里填的是客户端配置的client_id和client_secret的值,相当于curl --user client_id:client_secret,配置后会在Header中添加Authorization:Basic Y2xpZW50LWE6Y2xpZW50LWEtc2VjcmV0,Basic空格 后的是client_id:client_secret具体值被Base64后得到的值
请求参数列表:
- code=授权码
- grant_type=authorization_code
- redirect_uri=回调url ,要与配置处和获取授权码处相同
- scope=作用域
最后我们获得了授权服务的响应,包含token的json
{ "access_token": "99435e13-f9fe-438a-a94e-3b00d549b329", //访问token "token_type": "bearer", //token类型,使用时需要拼接在token前并在token前加空格 "expires_in": 43199, //过期时间 "scope": "read_user_info" //作用域 }
在access_token未过期之前,同一个用户名使用同一个客户端访问都会是同一个access_token
授权服务器先放在这里,不要关服,接下来搭建资源服务器
搭建资源服务器(Resource Server)
资源服务器结构
入口类不多说,先搭建资源服务器主要配置,这里直接使用ResourceConfig进行配置
package com.github.hellxz.oauth2.config; 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.localhost:8080/oauth/check_token"); //设置客户端id与secret,注意:client_secret值不能使用passwordEncoder加密! tokenServices.setClientId("client-a"); tokenServices.setClientSecret("client-a-secret"); return tokenServices; } @Override public void configure(HttpSecurity localhost:8081/user/hellxz001
Bearer Token相当于在Headers中添加Authorization:Bearer空格access_token
至此我们成功的搭建并测试了授权码模式下的最简单的授权服务与资源服务分离的demo
尾声
授权码模式就先在这里告一段落,写的比较基础,自认为该说到的点都说到了,后续还会写其它模式的文章,如文中有何遗漏,请不吝评论反馈,本人会尽快改正,谢谢
本文以及后续文章的demo均放在GitHub上,欢迎大家Star & Fork,源码地址:github.com/hellxz/spring-security-oauth2-learn ,Demo中的README文档写得比较详细,也可堪一看
原文出处www.cnblogs.com/hellxz/p/oauth2_oauthcode_pattern.html
到此这篇关于Spring Security OAuth2 授权码模式的实现的文章就介绍到这了,更多相关Spring Security OAuth2 授权码模式内容请搜索易盾网络以前的文章或继续浏览下面的相关文章希望大家以后多多支持易盾网络!

