2019独角兽企业重金招聘Python工程师标准>>>

Spring Cloud Security OAuth2 是 Spring 对 OAuth2 的开源实现,优点是能与Spring Cloud技术线无缝集成,如果全部使用默认配置,开发者只需要添加注解就能完成 OAuth2 授权服务的搭建。

1. 添加依赖

授权服务是基于Spring Security的,因此需要在项目中引入两个依赖:

 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-security</artifactId>
</dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-oauth2</artifactId></dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

前者为 Security,后者为Security的OAuth2扩展。

2. 添加注解和配置

在启动类中添加@EnableAuthorizationServer注解:

@SpringBootApplication
@EnableAuthorizationServer
public class AlanOAuthApplication {public static void main(String[] args) {SpringApplication.run(AlanOAuthApplication.class, args);}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

完成这些我们的授权服务最基本的骨架就已经搭建完成了。但是要想跑通整个流程,我们必须分配 client_idclient_secret才行。Spring Security OAuth2的配置方法是编写@Configuration类继承AuthorizationServerConfigurerAdapter,然后重写void configure(ClientDetailsServiceConfigurer clients)方法,如:

@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.inMemory() // 使用in-memory存储.withClient("client") // client_id.secret("secret") // client_secret.authorizedGrantTypes("authorization_code") // 该client允许的授权类型.scopes("app"); // 允许的授权范围}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

3. 授权流程

访问授权页面:

localhost:8080/oauth/authorize?client_id=client&response_type=code&redirect_uri=http://www.baidu.com
  • 1

此时浏览器会让你输入用户名密码,这是因为 Spring Security 在默认情况下会对所有URL添加Basic Auth认证。默认的用户名为user, 密码是随机生成的,在控制台日志中可以看到。

画风虽然很简陋,但是基本功能都具备了。点击Authorize后,浏览器就会重定向到百度,并带上code参数:

拿到code以后,就可以调用

POST/GET http://client:secret@localhost:8080/oauth/token
  • 1

来换取access_token了:

curl -X POST -H "Cache-Control: no-cache" -H "Content-Type: application/x-www-form-urlencoded" -d 'grant_type=authorization_code&code=Li4NZo&redirect_uri=http://www.baidu.com' "http://client:secret@localhost:8080/oauth/token"
  • 1

返回如下:

{"access_token": "32a1ca28-bc7a-4147-88a1-c95abcc30556","token_type": "bearer","expires_in": 2591999,"scope": "app"
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

到此我们最最基本的授权服务就搭建完成了。然而,这仅仅是个demo,如果要在生产环境中使用,还需要做更多的工作。

4. 使用MySQL存储access_token和client信息

把授权服务器中的数据存储到数据库中并不难,因为 Spring Cloud Security OAuth 已经为我们设计好了一套Schema和对应的DAO对象。但在使用之前,我们需要先对相关的类有一定的了解。

4.1 相关接口

Spring Cloud Security OAuth2通过DefaultTokenServices类来完成token生成、过期等 OAuth2 标准规定的业务逻辑,而DefaultTokenServices又是通过TokenStore接口完成对生成数据的持久化。在上面的demo中,TokenStore的默认实现为InMemoryTokenStore,即内存存储。 对于Client信息,ClientDetailsService接口负责从存储仓库中读取数据,在上面的demo中默认使用的也是InMemoryClientDetialsService实现类。说到这里就能看出,要想使用数据库存储,只需要提供这些接口的实现类即可。庆幸的是,框架已经为我们写好JDBC实现了,即JdbcTokenStoreJdbcClientDetailsService

4.2 建表

要想使用这些JDBC实现,首先要建表。框架为我们提前设计好了schema, 在github上:https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/test/resources/schema.sql

在使用这套表结构之前要注意的是,对于MySQL来说,默认建表语句中主键是varchar(255)类型,在mysql中执行会报错,原因是mysql对varchar主键长度有限制。所以这里改成128即可。其次,语句中会有某些字段为LONGVARBINARY类型,它对应mysql的blob类型,也需要修改一下。

4.3 配置

数据库建好后,下一步就是配置框架使用JDBC实现。方法还是编写@Configuration类继承AuthorizationServerConfigurerAdapter

    @Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate DataSource dataSource;@Bean // 声明TokenStore实现public TokenStore tokenStore() {return new JdbcTokenStore(dataSource);}@Bean // 声明 ClientDetails实现public ClientDetailsService clientDetails() {return new JdbcClientDetailsService(dataSource);}@Override // 配置框架应用上述实现public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.authenticationManager(authenticationManager);endpoints.tokenStore(tokenStore());// 配置TokenServices参数DefaultTokenServices tokenServices = new DefaultTokenServices();tokenServices.setTokenStore(endpoints.getTokenStore());tokenServices.setSupportRefreshToken(false);tokenServices.setClientDetailsService(endpoints.getClientDetailsService());tokenServices.setTokenEnhancer(endpoints.getTokenEnhancer());tokenServices.setAccessTokenValiditySeconds( (int) TimeUnit.DAYS.toSeconds(30)); // 30天endpoints.tokenServices(tokenServices);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

完成这些后,框架就会将中间产生的数据写到mysql中了。oauth_client_details是client表,可以直接在该表中添加记录来添加client: 

4.4 需要注意的地方

这里不得不说 Spring 设计有一个奇葩地的方。注意看oauth_access_token表是存放访问令牌的,但是并没有直接在字段中存放token。Spring 使用OAuth2AccessToken来抽象与令牌有关的所有属性,在写入到数据库时,Spring将该对象通过JDK自带的序列化机制序列成字节直接保存到了该表的token字段中。也就是说,如果只看数据表你是看不出access_token的值是多少,过期时间等信息的。这就给资源服务器的实现带来了麻烦。我们的资源提供方并没有使用Spring Security,也不想引入 Spring Security 的任何依赖,这时候就只能将 DefaultOAuth2AccessToken的源码copy到资源提供方的项目中,然后读取token字段并反序列化还原对象来获取token信息。但是如果这样做还会遇到反序列化兼容性的问题,具体解决方法参考我另一篇博文:http://blog.csdn.net/neosmith/article/details/52539614

5. 总结

至此一个能在生产环境下使用的授权服务就搭建好了。其实我们在实际使用时应该适当定制JdbcTokenStoreClientDetailsService来实适应业务需要,甚至可以直接从0开始实现接口,完全不用框架提供的实现。另外,Spring 直接将DefaultOAuth2AccessToken序列化成字节保存到数据库中的设计,我认为是非常不合理的。或许设计者的初衷是保密access_token,但是通过加密的方法也可以实现,完全不应该直接扔字节。不过通过定制TokenStore接口,我们可以使用自己的表结构而不拘泥于默认实现。

转载于:https://my.oschina.net/Seaside20151225/blog/745282

使用Spring Cloud Security OAuth2搭建授权服务相关推荐

  1. 【java_wxid项目】【第七章】【Spring Cloud Security Oauth2集成】

    主项目链接:https://gitee.com/java_wxid/java_wxid 项目架构及博文总结: 点击:[使用Spring Boot快速构建应用] 点击:[使用Spring Cloud O ...

  2. spring cloud+.net core搭建微服务架构:Api授权认证(六)

    前言 这篇文章拖太久了,因为最近实在太忙了,加上这篇文章也非常长,所以花了不少时间,给大家说句抱歉.好,进入正题.目前的项目基本都是前后端分离了,前端分Web,Ios,Android...,后端也基本 ...

  3. spring cloud+dotnet core搭建微服务架构:配置中心续(五)

    前言 上一章最后讲了,更新配置以后需要重启客户端才能生效,这在实际的场景中是不可取的.由于目前Steeltoe配置的重载只能由客户端发起,没有实现处理程序侦听服务器更改事件,所以还没办法实现彻底实现这 ...

  4. 【译文】用Spring Cloud和Docker搭建微服务平台

    by Kenny Bastani Sunday, July 12, 2015 转自:http://www.kennybastani.com/2015/07/spring-cloud-docker-mi ...

  5. gateway oauth2 对称加密_深入理解Spring Cloud Security OAuth2及JWT

    因项目需要,需要和三方的oauth2服务器进行集成.网上关于spring cloud security oauth2的相关资料,一般都是讲如何配置,而能把这块原理讲透彻的比较少,这边自己做一下总结和整 ...

  6. 玩转Spring Cloud Security OAuth2身份认证扩展——电话号码+验证码认证

    在程序的认证过程中,除了常规的用户名和密码方式(可以参考深入理解Spring Cloud Security OAuth2身份认证),也经常会出现电话号码+密码的方式:电话号码+验证码的方式:或者第三方 ...

  7. 用Spring Cloud和Docker搭建微服务平台

    This blog series will introduce you to some of the foundational concepts of building a microservice- ...

  8. spring cloud+dotnet core搭建微服务架构:Api网关(三)

    前言 国庆假期,一直没有时间更新. 根据群里面的同学的提问,强烈推荐大家先熟悉下spring cloud.文章下面有纯洁大神的spring cloud系列. 上一章最后说了,因为服务是不对外暴露的,所 ...

  9. spring cloud+dotnet core搭建微服务架构:配置中心(四)

    前言 我们项目中有很多需要配置的地方,最常见的就是各种服务URL地址,这些地址针对不同的运行环境还不一样,不管和打包还是部署都麻烦,需要非常的小心.一般配置都是存储到配置文件里面,不管多小的配置变动, ...

  10. spring cloud+dotnet core搭建微服务架构:服务发现(二)

    前言 上篇文章<手把手教你使用spring cloud+dotnet core搭建微服务架构:服务治理(-)>实际上只讲了服务治理中的服务注册,服务与服务之间如何调用呢?传统的方式,服务A ...

最新文章

  1. java 网络爬虫 正则表达式_【干货】Java网络爬虫基础知识
  2. ACM训练赛--递推专题
  3. Eclipse新建Maven项目没有web.xml
  4. 第四周作业wcPro
  5. windows和linux主机名,windows和linux下如何远程获取操作系统版本和主机名
  6. 无法从套接字中获取更多数据_数据科学中应引起更多关注的一个组成部分
  7. 各种initcall的执行先后顺序(module_init、postcore_initcall、arch_initcall、subsys_initcall、 fs_initcall)【转】...
  8. 使用screen的时候出现了如下错误: Cannot open your terminal '/dev/pts/0' - please check.
  9. Tomcat URL重写
  10. IntelliJ IDEA 设置Output (输出窗口)窗口字体大小
  11. SHA256算法原理详解图
  12. php个人财务管理,PHP个人理财管理系统的设计与实现
  13. html网页版国际象棋,棋友推荐的十五大国外国际象棋网站
  14. UBUNTU VS C++ 调试报错Unable to open ‘libc-start.c‘: File not found.
  15. 中国止血分析仪行业市场供需与战略研究报告
  16. 工作流引擎的流程业务表设计
  17. @Resource和@Autowired注解的区别
  18. 题目1026 c语言,1026 程序运行时间——C/C++实现
  19. 关于这个开源项目 from VIP Lab
  20. ALEXA中国网站排名真相调查[内幕调查:出卖Alexa]

热门文章

  1. 多小区下小区上行速率的计算的想法
  2. 安卓命令和linux命令行,scrcpy:用电脑显示和控制Android设备的命令行工具
  3. Regularized Gaussian Covariance Estimation
  4. LIBSVM使用方法及参数设置
  5. 【Gym-102606 H】Heat Pipes【奇环染色、bfs 生成树】
  6. 数据库服务器系统崩溃,mssql数据库系统崩溃后的一般处理步骤与方法
  7. 潍坊科技学院五专部计算机应用基础试题,14计算机应用基础(A)
  8. 优化无极限:从96秒到1.5秒
  9. Python——Pycharm基本设置
  10. Go语言 channel 管道 阻塞 死锁 经典问题