旧的Spring Security OAuth2停止维护已经有一段时间了,99%Spring Cloud微服务项目还在使用这些旧的体系,严重青黄不接。很多同学都在寻找新的解决方案,甚至还有念念不忘密码模式的。胖哥也在前面写了一篇解决思路的文章。好像还是不过瘾,今天看到这篇文章的同学有福了,问题将在这里得到解决。

方案

目前这应该是Spring生态中最新的解决方案,没有之一。先看下流程,微服务无关的其它的组件这里先屏蔽了,剩下图的几个组件:

详细流程为

  • ①用户向网关请求登录或者通过网关请求资源服务器的资源。

  • ②网关发现用户没有授权发起基于OAuth2授权码的OIDC流程,向授权服务器Id Server发起授权请求。

  • ③授权服务器Id Server收到授权请求重定向到用户登录页面要求用户登录认证,以发起授权。

  • ④用户输入用户名密码进行登录认证。

  • Id Server授权服务器处理用户认证并重定向到网关约定的OAuth2 Redirect URI,这个过程属于标准的OIDC授权码流程。

  • ⑥网关获得AccessTokenIdToken

    • 如果最初发起的是登录就重定向到/
    • 如果最初发起的是请求资源服务器资源就令牌中继重定向到对应的资源。
  • 资源服务器通过⑦⑧两个链路响应用户的请求。

请注意,上述流程中生成的AccessTokenIdToken不允许提供给用户侧,否则会引起中间人攻击,默认提供的是一个cookie策略,大部分情况下这种策略是够用的,如果你需要自定义必须深刻了解其机制,你可以通过我的Spring Security OAuth2专栏进行学习。

具体实现

根据上面的方案,我们需要三个应用,分别是网关Spring Cloud Gateway应用、资源服务器应用Resource ServerOAuth2授权服务器Id Server

Spring Cloud Gateway

Spring Cloud Gateway 应用,端口8080,它不仅仅是一个网关还是一个在授权服务器Id Server注册的OAuth2客户端,通过Id Server你可以在一分钟内完成配置。它需要配置到资源服务器的路由规则和令牌中继功能。核心配置为:

spring:
application:
name: gateway
security:
oauth2:
client:
registration:
# 这里为客户端名称可自行更改
gatewayclient:
client-id: e4da4a32-592b-46f0-ae1d-784310e88423
# 密码为注册客户端时的密码
client-secret: secret
# 只能选择一个
redirect-uri: http://127.0.0.1:8080/login/oauth2/code/gatewayclient
# 其它两种方式为refresh_token,client_credentials
authorization-grant-type: authorization_code
client-authentication-method: client_secret_basic
scope: message.write,userinfo,message.read,openid
provider:
gatewayclient:
# 要保证授权服务器地址可以被客户端访问
issuer-uri: http://localhost:9000
cloud:
gateway:
routes:
- id: resource-server
uri: http://127.0.0.1:8084
predicates:
- Path=/res/**
filters:
- TokenRelay

Resource Server

资源服务器就是我们平常编写的业务接口的服务器,端口这里定义为8084,它需要集成Spring Security及其Resource Server组件。它要负责定义资源接口的访问权限,例如:

         // 只有message.read才有资格访问资源/res/foo
httpSecurity.authorizeRequests()
.antMatchers("/res/foo").hasAnyAuthority("SCOPE_message.read")

另外它还要和授权服务器Id Server通讯获取AccessToken的解码公钥:

spring:
security:
oauth2:
resourceserver:
jwt:
jwk-set-uri: http://localhost:9000/oauth2/jwks

获取解码公钥的原理在我的Spring Security OAuth2专栏有详细介绍,这里不再赘述。

Id Server

仓库地址:https://github.com/NotFound403/id-server 欢迎star,欢迎贡献。

Id Server是一个基于Spring Authorization Server的开源的授权服务器,它大大降低OAuth2授权服务器的学习使用难度,提供UI控制台,动态权限控制,方便OAuth2客户端管理,可一键生成Spring Security配置,开箱即用,少量配置修改就可部署,代码开源,方便二次开发,支持OAuth2四种客户端认证方式和三种授权模式。它是目前Spring安全生态中重要的组成部分,也是未来的技术发展趋势,更多信息请参阅Id Server项目仓库的介绍

Id Server在本文扮演的是OAuth2授权服务器的角色,负责对授权请求进行处理,维护客户端注册信息,授权用户信息,后续会加入IDP支持,各种三方登录的用户也可以动态在这里进行登录,就像这样:

根据业务需要第三方OAuth2授权登录也能优雅的接入,当然,接入的登录方式需要OIDC或者OAuth2的支持。

DEMO以及使用方法

上述完整DEMOId Server的仓库中的samples下。使用方法:

  • 拉取Id Server项目并加载依赖。
  • IntelliJ IDEA中依次单独对samples文件夹下的所有项目的pom.xml进行右键菜单选中Add As Maven Project,这一步很重要。
  • 依次启动Id Servergatewayresource-server三个项目。

测试登录

  • 浏览器访问http://127.0.0.1:8080/login,点击http://localhost:9000
  • 输入用户名密码user/user
  • 能查看到认证信息就证明成功了,再次重申,在生产中该信息十分敏感,不应该直接对前端暴露。
  • 浏览器访问http://127.0.0.1:8080/res/foo,可以访问到资源服务器的资源。

另一种测试

关闭浏览器重新打开,浏览器访问http://127.0.0.1:8080/res/foo,你看看会发生什么?

总结

通过OAuth2客户端、Spring Cloud GatewayOAuth2授权服务器、OAuth2资源服务器的联动,你会发现授权码模式也可以实现完整的微服务认证授权,而且比密码模式更加安全。后续Id Server实现了联合登录之后,其它第三方登录也可以无缝集成进来。多多关注,更多先进的黑科技等着你。

关注公众号:Felordcn 获取更多资讯

个人博客:https://felord.cn

OAuth2密码模式已死,最先进的Spring Cloud认证授权方案在这里的更多相关文章

  1. MVC模式已死

    MVC模式:Model模型 View试图 Control控制器,是目前主流模式,被当作服务器软件入门基本模式学习和掌握,主流框架Struts 1/2 JSF Wicket基本都顺理成章支持MVC模式. ...

  2. 阶段5 3.微服务项目【学成在线】_day16 Spring Security Oauth2_09-SpringSecurityOauth2研究-Oauth2密码模式授权

    密码模式(Resource Owner Password Credentials)与授权码模式的区别是申请令牌不再使用授权码,而是直接 通过用户名和密码即可申请令牌. 测试如下: Post请求:htt ...

  3. [转]MVC模式已死?何不试试MOVE

    在36Kr看到一篇译文,主要是提出一些新的概念,升华老的MVC模式.看上很不错,转过来,做个记录. ========================= 华丽的分割线 ================= ...

  4. Spring Boot Security Oauth2之客户端模式及密码模式实现

    Spring Boot Security Oauth2之客户端模式及密码模式实现 示例主要内容 1.多认证模式(密码模式.客户端模式) 2.token存到redis支持 3.资源保护 4.密码模式用户 ...

  5. 被广泛使用的OAuth2.0的密码模式已经废了,放弃吧

    最近一直有同学在问,OAuth2密码模式为啥Spring Security还没有实现,就连新的Spring Authorization Server也没有这个玩意儿. 其实这里可以告诉大家,OAuth ...

  6. Spring Security OAuth2 Demo —— 密码模式(Password)

    前情回顾 前几节分享了OAuth2的流程与授权码模式和隐式授权模式两种的Demo,我们了解到授权码模式是OAuth2四种模式流程最复杂模式,复杂程度由大至小:授权码模式 > 隐式授权模式 > ...

  7. IdentityServer4 实现OAuth2.0四种模式之密码模式

    接上一篇:IdentityServer4 实现OAuth2.0四种模式之客户端模式,这一篇讲IdentityServer4 使用密码模式保护API访问. 一,IdentityServer配置 1,添加 ...

  8. oauth2.0密码模式详解

    oauth2.0密码模式 欢迎关注博主公众号「Java大师」, 专注于分享Java领域干货文章http://www.javaman.cn/sb2/oauth-password 如果你高度信任某个应用, ...

  9. IdentityServer4:IdentityServer4+API+Client+User实践OAuth2.0密码模式(2)

    一.密码模式实操 仍然使用第一节的代码:做如下改动: 1.授权服务端 前面我们使用项目:Practice.IdentityServer作为授权服务器 修改项目的Config.cs类: 添加测试用户,并 ...

随机推荐

  1. 细说【json&pickle】dumps,loads,dump,load的区别

    1 json.dumps() json.dumps()是将字典类型转化成字符串类型. import json name_emb = {'a':'1111','b':'2222','c':'3333', ...

  2. ubantu系统之快捷键使用

    1. 文件管理器中,目录切换为可以编辑的状态: ctrl + l 2. gedit 搜索 : ctrl + h

  3. JBOSS 7.1.1上的DB2和Orcale数据库配置

      将IBM DB2和Oracle数据源配置到JBOSS 7.1.1      第1步:  打开Standalone.xml文件将以下代码添加到数据源的子系统中,并根据数据库URL和数据源的用户名和密 ...

  4. rem,px,em最大的区别;

    px:px像素(Pixel).相对长度单位.像素px是相对于显示器屏幕分辨率而言的.移动端的分辨率很多.所以px不适用移动端em:em的值不固定:其长度继承父级元素的字体大小rem:相对于根元素htm ...

  5. golang 中 sync.Mutex 的实现

    mutex 的实现思想 mutex 主要有两个 method: Lock() 和 Unlock() Lock() 可以通过一个 CAS 操作来实现 func (m *Mutex) Lock() { f ...

  6. python---复杂度、斐波那切数列、汉诺塔

    时间复杂度 ​ 用来估计算法运行时间的一个式子. ​ 一般来说, 时间复杂度高的算法比复杂度低的算法慢. 常见的时间复杂度: ​ O(1) < O(logn) < O(n) < O( ...

  7. spring-xml实现aop-通知的种类

    如果本代码有疑问,请访问spring-aop快速入门或者spring-aop动态代理技术(底层分析) 1.导入aop的相关坐标 <dependency> <groupId>or ...

  8. 【FAQ】应用集成HMS Core部分服务出现“ 6003报错”情况的解决方法来啦

    背景 开发者在应用中集成HMS Core部分服务时,android sdk 以及flutter等跨平台sdk,会出现编译打包后,运行报6003错误码的情况.根据查询可以得知,错误代码 6003 表示证 ...

  9. thymeleaf模板使用

    使用模板页面,实现在同一个页面展现不同数据,controller实现页面跳转的时候就不在需要打开新页面

  10. 2021.08.05 P1738 洛谷的文件夹(树形结构)

    2021.08.05 P1738 洛谷的文件夹(树形结构) P1738 洛谷的文件夹 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.树!! 题意: 给出n个网页路径,求 ...