旧的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. 学习 Haproxy (一)

    haproxy是一个开源的.高性能的基于tcp和http应用代理的HA的.LB服务软件,它支持双机热备.HA.LB.虚拟主机.图形界面查看状态信息等功能,其配置简单.维护方便,而且后端RS的healt ...

  2. 经历了源码的痛苦,掌握DRF的核心序列化器

    目录 DRF的核心--序列化器 序列化器 什么是序列化和反序列化? 序列化 序列化demo 字段类型 字段参数 序列化自定制返回字段 方法一:在序列化类(serializers.py)中写 方法二:在 ...

  3. 时间工具类之“ JDK1.8中 LocalDate、LocalTime、LocalDateTime、LocalDateTimeUtil四个时间工具类”

    一.使用的原因 在JDK8发布的时候,推出了LocalDate.LocalTime.LocalDateTime这个三个时间处理类,以此来弥补之前的日期时间类的不足,简化日期时间的操作. 在Java8之 ...

  4. Cadence 错误合集

    1.原理图DRC出现如下错误"Duplicate Pin Name "GND" found on Packag" 解决方案:原因是元件引脚重复定义,可以进行重新 ...

  5. 顺利通过EMC试验(2)

    限制值 电磁波照射,静电放电敏感性

  6. 开源HTML5游戏引擎Kiwi.js 1.0正式发布

    Kiwi.js是由GameLab开发的一款全新的开源HTML5 JavaScript游戏引擎.在经过一年多的开发和测试之后,终于在日前正式发布了Kiwi.js 1.0版本. 其创始人Dan Milwa ...

  7. BeeFramework:以极客的方式开发你的应用

    BeeFramework 是新一代的应用开发框架,它能使应用开发变得更简单更容易,它是由 Gavin Kwoe 和 QFish 开发并维护的.使用 BeeFramework 能像 html 和 css ...

  8. 前端面试题整理——手写flatern摊平数组

    // flatern 是摊平数组 function flat(arr) { const isDeep = arr.some(item => item instanceof Array) if(! ...

  9. Citus 分布式 PostgreSQL 集群 - SQL Reference(SQL支持和变通方案)

    由于 Citus 通过扩展 PostgreSQL 提供分布式功能,因此它与 PostgreSQL 结构兼容.这意味着用户可以使用丰富且可扩展的 PostgreSQL 生态系统附带的工具和功能来处理使用 ...

  10. 单例模式的实现Singleton和MonoSingleton

    using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary> / ...