Oauth2授权,熟悉微信开发的同学对这个东西应该不陌生吧。当我们的应用系统需要集成第三方授权时一般都会做oauth集成,今天就来看看在Dapr的语境下我们如何仅通过配置无需修改应用程序的方式让第三方服务保护我们的API应用。

目录:
一、通过Dapr实现一个简单的基于.net的微服务电商系统

二、通过Dapr实现一个简单的基于.net的微服务电商系统(二)——通讯框架讲解

三、通过Dapr实现一个简单的基于.net的微服务电商系统(三)——一步一步教你如何撸Dapr

四、通过Dapr实现一个简单的基于.net的微服务电商系统(四)——一步一步教你如何撸Dapr之订阅发布

五、通过Dapr实现一个简单的基于.net的微服务电商系统(五)——一步一步教你如何撸Dapr之状态管理

六、通过Dapr实现一个简单的基于.net的微服务电商系统(六)——一步一步教你如何撸Dapr之Actor服务

七、通过Dapr实现一个简单的基于.net的微服务电商系统(七)——一步一步教你如何撸Dapr之服务限流

八、通过Dapr实现一个简单的基于.net的微服务电商系统(八)——一步一步教你如何撸Dapr之链路追踪

九、通过Dapr实现一个简单的基于.net的微服务电商系统(九)——一步一步教你如何撸Dapr之OAuth2授权
附录:(如果你觉得对你有用,请给个star)
一、电商Demo地址

二、通讯框架地址

  Dapr目前支持两种Oauth2授权,一种是用户认证模式,一种是客户端凭据模式。今天的演示主要是通过集成github用户认证的模式来实现相关功能,先上流程图:

  流程图画的比较简单,而且这里隐藏了dapr相关的细节,下面我们详细看看到底发生了什么:

  1、首先访问者通过客户端发起一个对鉴权服务的访问,sidecar检测到此次访问没有对应cookie则会发起一个重定向到github的302请求。

  2、客户端检测到302后会重定向到github,github会展示一个登录页面并提示访问者登录并授权给应用使用相关能力(如获取用户信息),授权完成后github带上code并发起一个302重定向回到我们提前录入好的回调地址,该地址实际上也是指向我们的鉴权服务。

  3、鉴权服务的sidecar拿到对应code后会再次请求github拿到accesstoken并通过header的方式将该accesstoken返回给应用。

  4、应用拿到accesstoken后就可以访问github公开的api获取访问者授权部分的功能。

  基本逻辑如上,下面我们看看如何集成github,首先我们需要登录github创建一个对应的应用:

  登录你的github账号,并在右上角账号头像上点击进入setting,进入设置页面后在左侧菜单栏选择“Developer settings”并选择二级菜单“OAuth Apps”,在这里我们需要创建一个应用,创建应用比较简单,这里唯一需要注意的是Authorization callback URL这一栏需要输入授权地址。不过创建时可以随意填写一个地址,等后续授权服务上线后再修改这里的回调地址即可。创建完成后我们可以进入detail拿到两个关键配置Client ID、Client secrets。

  接着我们创建对应的Component并录入刚才拿到的Client ID、Client secrets:注意这里的redirectURL如果填了的话,跳转会按照这里填写的地址跳转,否则按照应用上预设的地址跳转,我这里留空。另外authHeaderName是我们告诉daprd回调拿到的accesstoken的header名字自定义为“myauth”,否则会使用默认的关键字“authorization”,如果你不想占用该关键字则可以声明一个自定义headername。

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: githubauth
namespace: dapreshop
spec:
type: middleware.http.oauth2
version: v1
metadata:
- name: clientId
value: "your client id"
- name: clientSecret
value: "your client secret"
- name: scopes
value: "user:email"
- name: authURL
value: "https://github.com/login/oauth/authorize"
- name: tokenURL
value: "https://github.com/login/oauth/access_token"
- name: redirectURL
value: ""
- name: authHeaderName
value: "myauth"

  接着我们申明一个Configuration并注入到鉴权服务中(注入部分参考之前的限流)

apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
namespace: dapreshop
spec:
httpPipeline:
handlers:
- name: githubauth
type: middleware.http.oauth2

  接着我们在eshop-sample上创建一个鉴权服务并创建一个service,该service主要是获取到“myauth”之后向github发起请求访问其user接口获取之前授权访问者的基本用户信息用于创建默认的商城管理员。获取信息后会将user信息打包到cookie并通过302的方式回写到admin.dapreshop.com方便创建用户。

    [RemoteService("oauthservice", "github", "github授权服务")]
public interface IService
{
[RemoteFunc(funcDescription: "请求OAUTH登录")]
Task<Model> GetUserInfo();
}
public class Service: IService
{
private readonly IHttpClientFactory httpClientFactory;
public Service(IHttpClientFactory httpClientFactory)
{
this.httpClientFactory = httpClientFactory;
}
public async Task<Model> GetUserInfo()
{
var model = new Model() { login = "" };
if (HttpContextExt.Current.Headers.Any(x => x.Key.ToLower().Equals("myauth")))
{
var req = new HttpRequestMessage();
req.Headers.Add("User-Agent", "dapr-eshop");
req.Headers.Add("Authorization", HttpContextExt.Current.Headers.FirstOrDefault(x => x.Key.ToLower().Equals("myauth")).Value);
req.Method = HttpMethod.Get;
req.RequestUri = new Uri("https://api.github.com/user");
var result = await httpClientFactory.CreateClient().SendAsync(req);
if (result.IsSuccessStatusCode)
{
var content = await result.Content.ReadAsStringAsync();
HttpContextExt.Current.Response.Cookies.Append("githubuser", JsonSerializer.Serialize(JsonSerializer.Deserialize<Model>(content)),
new Microsoft.AspNetCore.Http.CookieOptions() { Domain = "dapreshop.com" });
HttpContextExt.Current.Response.Redirect("http://admin.dapreshop.com:30882");
}
}
return model;
}
}

  接着我们改造一下AccountUseCaseService的InitRoleBasedAccessControler这个方法,如果获取到从页面回调的cookie,则直接用cookie创建初始管理员,否则用默认值创建初始管理员(代码略,具体看github对应的repo)

  由于oauth会涉及到多次302重定向,我之前预设的简易反代网关暂时走不通这个逻辑,所以这里我们直接将授权服务的dapr service暴露到ingress:(补充一个小知识,所有开启了dapr的应用都会创建一个“yingoyngming-dapr”的service,通过该service可以直接访问sidecar)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: dapreshop
name: oauth
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: 'http://admin.dapreshop.com:30882'
nginx.ingress.kubernetes.io/cors-allow-headers: 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authentication,AuthIgnore'
spec:
rules:
- host: oauth.dapreshop.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: oauthservice-dapr
port:
number: 80

  照例将127.0.0.1 oauth.dapreshop.com 录入host文件。接着我们回到github应用,将回调地址录入:http://oauth.dapreshop.com:30882/v1.0/invoke/oauthservice/method/github/GetUser 保存

  最后我们在admin.dapreshop.com的前端页面增加一个跳转到github的图标,并将地址设置为“http://oauth.dapreshop.com:30882/v1.0/invoke/oauthservice/method/github/GetUser”,这样点击时即可进行oauth鉴权校验:

  一切就绪,启动我们的电商demo,进入admin.dapreshop.com后,取消点击初始化,点击github小图标,会跳转到github授权页面

  登录后会回跳到我们的oauth服务的GetUserInfo方法,并通过该方法拿到user并回写到cookie中,此时再点击初始化,则会根据github账号创建对应的超管

  整个流程就完毕了,大家可以clone最新的demo并尝试一下~

通过Dapr实现一个简单的基于.net的微服务电商系统(九)——一步一步教你如何撸Dapr之OAuth2授权的更多相关文章

  1. 通过Dapr实现一个简单的基于.net的微服务电商系统(十)——一步一步教你如何撸Dapr之绑定

    如果说Actor是dapr有状态服务的内部体现的话,那绑定应该是dapr对serverless这部分的体现了.我们可以通过绑定极大的扩展应用的能力,甚至未来会成为serverless的基础.最开始接触 ...

  2. 通过Dapr实现一个简单的基于.net的微服务电商系统(十一)——一步一步教你如何撸Dapr之自动扩/缩容

    上一篇我们讲到了dapr提供的bindings,通过绑定可以让我们的程序轻装上阵,在极端情况下几乎不需要集成任何sdk,仅需要通过httpclient+text.json即可完成对外部组件的调用,这样 ...

  3. 通过Dapr实现一个简单的基于.net的微服务电商系统(十二)——istio+dapr构建多运行时服务网格

    多运行时是一个非常新的概念.在 2020 年,Bilgin Ibryam 提出了 Multi-Runtime(多运行时)的理念,对基于 Sidecar 模式的各种产品形态进行了实践总结和理论升华.那到 ...

  4. 通过Dapr实现一个简单的基于.net的微服务电商系统(十三)——istio+dapr构建多运行时服务网格之生产环境部署

    之前所有的演示都是在docker for windows上进行部署的,没有真正模拟生产环境,今天我们模拟真实环境在公有云上用linux操作如何实现istio+dapr+电商demo的部署. 目录:一. ...

  5. 通过Dapr实现一个简单的基于.net的微服务电商系统(十四)——开发环境容器调试小技巧

    之前有很多同学提到如何做容器调试,特别是k8s环境下的容器调试,今天就讲讲我是如何调试的.大家都知道在vs自带的创建项目模板里勾选docker即可通过F5启动docker容器调试.但是对于启动在k8s ...

  6. 通过Dapr实现一个简单的基于.net的微服务电商系统(十五)——集中式接口文档实现

    之前有小伙伴在评论区留言说如何集成swagger,最开始没有想透给了对方一个似是而非的回答.实际上后来下来想了一下,用.NET5 提供的Source Generator其实可以很方便的实现接口集成.今 ...

  7. 通过Dapr实现一个简单的基于.net的微服务电商系统(十六)——dapr+sentinel中间件实现服务保护

    dapr目前更新到了1.2版本,在之前4月份的时候来自阿里的开发工程师发起了一个dapr集成Alibaba Sentinel的提案,很快被社区加入到了1.2的里程碑中并且在1.2 release 相关 ...

  8. 通过Dapr实现一个简单的基于.net的微服务电商系统(十七)——服务保护之动态配置与热重载

    在上一篇文章里,我们通过注入sentinel component到apigateway实现了对下游服务的保护,不过受限于目前变更component需要人工的重新注入配置以及重启应用更新componen ...

  9. 通过Dapr实现一个简单的基于.net的微服务电商系统(十九)——分布式事务之Saga模式

    在之前的系列文章中聊过分布式事务的一种实现方案,即通过在集群中暴露actor服务来实现分布式事务的本地原子化.但是actor服务本身有其特殊性,场景上并不通用.所以今天来讲讲分布式事务实现方案之sag ...

随机推荐

  1. 敏捷史话(八):敏捷的破局之道——Martin Fowler

    在 Martin Fowler 的世界里,任何事情都有最优解. 1963年,Martin 出生于英格兰的沃尔索尔(Walsall),也在同样位于沃尔索尔的玛丽女王文法学校中接受中等教育.在这里的乡村中 ...

  2. 剑指 Offer 19. 正则表达式匹配 + 动态规划

    剑指 Offer 19. 正则表达式匹配 题目链接 一. 字符串匹配大致可以分为三种情况: 第一种:正则串的最后一个字符为正常字符,此时根据主串的最后一个字符是否和它相同来判断是否匹配, 如果相同,则 ...

  3. 2020年12月-第02阶段-前端基础-CSS字体样式

    CSS字体样式属性调试工具 应用 使用css字体样式完成对字体的设置 使用css外观属性给页面元素添加样式 1.font字体 1.1 font-size:大小 作用: font-size属性用于设置字 ...

  4. go中sync.Once源码解读

    sync.Once 前言 sync.Once的作用 实现原理 总结 sync.Once 前言 本次的代码是基于go version go1.13.15 darwin/amd64 sync.Once的作 ...

  5. 腾讯云发布存储一体机TStor,打通全面上云“最后一公里”

    随着云计算.大数据.人工智能等技术的发展,各行各业加速数据化转型,数据容量以前所未有的速度增长,本地存储难以适应数据的指数式增长. 另一方面,公有云因其易扩展.低成本.安全稳定的特点,逐渐被企业广泛应 ...

  6. HTML标签解读

    因为最近在学习爬虫,那么在爬取网页内容时,就要求我们能够简单的看懂这个网页的基本结构,才能更好的去爬取我们所需要的内容. 这篇随笔也只是简单的说明了一些标签的含义. 标签关系 包含关系 eg:< ...

  7. Python—关于Pandas缺失值问题(国内唯一)

    获取文中的CSV文件用于代码编程以及文章首发地址,请点击下方超链接 获取CSV,用于编程调试请点这 在本文中,我们将使用Python的Pandas库逐步完成许多不同的数据清理任务.具体而言,我们将重点 ...

  8. 「HTML+CSS」--自定义加载动画【007】

    前言 Hello!小伙伴! 首先非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出- 哈哈 自我介绍一下 昵称:海轰 标签:程序猿一只|C++选手|学生 简介:因C语言结识编程,随后转入计算机 ...

  9. 从 lite-apiserver 看 SuperEdge 边缘节点自治

    引言 在 SuperEdge 0.2.0版本中,lite-apiserver 进行了重大的架构升级和功能增强.本文将从 lite-apiserver 实现及其与其它 SuperEdge 组件协同的角度 ...

  10. String 的不可变真的是因为 final 吗?

    尽人事,听天命.博主东南大学硕士在读,热爱健身和篮球,乐于分享技术相关的所见所得,关注公众号 @ 飞天小牛肉,第一时间获取文章更新,成长的路上我们一起进步 本文已收录于 「CS-Wiki」Gitee ...