旧的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. 机器学习 machine learn

    机器学习 机器学习 概述 什么是机器学习 机器学习是一门能够让编程计算机从数据中学习的计算机科学.一个计算机程序在完成任务T之后,获得经验E,其表现效果为P,如果任务T的性能表现,也就是用以衡量的P, ...

  2. Python的数据基础库Numpy怎样对数组进行排序

    Numpy怎样对数组排序 Numpy给数组排序的三个方法: numpy.sort:返回排序后数组的拷贝 array.sort:原地排序数组而不是返回拷贝 numpy.argsort:间接排序,返回的是 ...

  3. 顺利通过EMC实验(3)

  4. 使用Web存储API存取本地数据

    使用Web存储API TODO:本文由 赤石俊哉 翻译整理,您可以将本文自由地用于学习交流.如需用于其他用途请征得作者的同意. 原文链接:Using the Web Storage API - Moz ...

  5. java中将科学技术发转为正常数据

    import java.text.NumberFormat; public class test { public static void main(String[] args) { double d ...

  6. EL表达式详解(常用表达式以及取值)

    EL表达式 学习总结 一. El表达式概念 二. El中的表达式 1. 算术表达式 2. 比较表达式 3. 逻辑表达式 4. 三元表达式 5. 判空表达式 三.EL 从四个作用域中取值 1. 概念 2 ...

  7. Mysql中如何开启慢查询功能?

    1.修改mysql的配置文件my.ini,增加如下信息,修改之后需要重启mysql服务器. 2.执行一句sql查询语句,结果如下. mysql> select count(*) from ecs ...

  8. python2.7安装pyinstaller

    python2.7直接安装pyinstaller会报错,版本4与python2不兼容,所以我们安装时需指定兼容的pyinstaller版本号.安装命令如下: pip2 install pyinstal ...

  9. JavaScript 字符串(String)对象的方法

    anchor() 描述:用于创建 HTML 锚 原型:stringObject.anchor(anchorname) 用法: <script> var txt="Hello wo ...

  10. 各系统升级openssh

    修订号: [V1.0] 修订人: [陈土锋] 修订日期: [2019.06.04] 前言 该文档只适用用于服务器Redhat,centos,Ubuntu和suse系统的openssh升级.需要注意必须 ...