在ASP.NET中基于Owin OAuth使用Client Credentials Grant授权发放Token
OAuth真是一个复杂的东东,即使你把OAuth规范倒背如流,在具体实现时也会无从下手。因此,Microsoft.Owin.Security.OAuth应运而生(它的实现代码在Katana项目中),帮助开发者偷了不少工,减了不少料。
这篇博文试图通过一个简单的示例分享一下如何基于Microsoft.Owin.Security.OAuth,使用Client Credentials Grant授权方式给客户端发放access token。
Client Credentials Grant的授权方式就是只验证客户端(Client),不验证用户(Resource Owner),只要客户端通过验证就发access token。举一个对应的应用场景例子,比如我们想提供一个“获取网站首页最新博文列表”的WebAPI给iOS App调用。由于这个数据与用户无关,所以不涉及用户登录与授权,不需要Resource Owner的参与。但我们不想任何人都可以调用这个WebAPI,所以要对客户端进行验证,而使用OAuth中的 Client Credentials Grant 授权方式可以很好地解决这个问题。
具体实现方式如下:
1)用Visual Studio 2013/2015创建一个Web API项目,VS会生成一堆OAuth相关代码。
2)打开Startup.Auth.cs ,精简一下代码,我们只需要实现以Client Credentials Grant授权方式拿到token,其它无关代码全部清除,最终剩下如下代码:
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
var OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/token"),
Provider = new CNBlogsAuthorizationServerProvider(),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(),
AllowInsecureHttp = true
}; app.UseOAuthBearerTokens(OAuthOptions);
}
}
3)创建一个新的类 CNBlogsAuthorizationServerProvider,并继承自 OAuthAuthorizationServerProvider,重载 OAuthAuthorizationServerProvider() 与 GrantClientCredentials() 这两个方法。代码如下:
public class CNBlogsAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
string clientId;
string clientSecret;
context.TryGetFormCredentials(out clientId, out clientSecret); if (clientId == "" && clientSecret == "")
{
context.Validated(clientId);
} return base.ValidateClientAuthentication(context);
} public override Task GrantClientCredentials(OAuthGrantClientCredentialsContext context)
{
var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, "iOS App"));
var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties());
context.Validated(ticket); return base.GrantClientCredentials(context);
}
}
在 ValidateClientAuthentication() 方法中获取客户端的 client_id 与 client_secret 进行验证。
在 GrantClientCredentials() 方法中对客户端进行授权,授了权就能发 access token 。
这样,OAuth的服务端代码就完成了。这么简单?是的,就这么简单,因为有了Microsoft.Owin.Security.OAuth。
4)然后写客户端调用代码测试一下:
public class OAuthClientTest
{
private HttpClient _httpClient; public OAuthClientTest()
{
_httpClient = new HttpClient();
_httpClient.BaseAddress = new Uri("http://openapi.cnblogs.com");
} [Fact]
public void Get_Accesss_Token_By_Client_Credentials_Grant()
{
var parameters = new Dictionary<string, string>();
parameters.Add("client_id", "");
parameters.Add("client_secret", "");
parameters.Add("grant_type", "client_credentials"); Console.WriteLine(_httpClient.PostAsync("/token", new FormUrlEncodedContent(parameters))
.Result.Content.ReadAsStringAsync().Result);
}
}
运行结果如下:
{"access_token":"8PqaWilv_SJT7vRXambP7Mebyaf3KO1GXYHsqA-oPMOQF6xk1YpluczOZGo-WwATU5YmGb0wSR0cUQMC8RSZfwO8nwom7yG11FIANhy2PNiqTg2CYdJF0sf0ggFs6it_i3mc_m1iEFCK2dLBPDJXPI24wngCPR0wP_zugZvyKv314BM0PQmnnwg3kLXR1DISKRbs5-i59VCtFSZgkM7A0w","token_type":"bearer","expires_in":1209599}
搞定!
【更新】
建议使用Basic Authentication传递clientId与clientSecret,服务端CNBlogsAuthorizationServerProvider中的TryGetFormCredentials()改为TryGetBasicCredentials(),客户端的调用代码如下:
public class OAuthClientTest
{
private HttpClient _httpClient; public OAuthClientTest()
{
_httpClient = new HttpClient();
_httpClient.BaseAddress = new Uri("http://openapi.cnblogs.com");
} [Fact]
public void Get_Accesss_Token_By_Client_Credentials_Grant()
{
var clientId = "";
var clientSecret = "";
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes(clientId + ":" + clientSecret))); var parameters = new Dictionary<string, string>();
parameters.Add("grant_type", "client_credentials"); Console.WriteLine(_httpClient.PostAsync("/token", new FormUrlEncodedContent(parameters))
.Result.Content.ReadAsStringAsync().Result);
}
}
【参考资料】
ASP.Net MVC: Creating an OAuth client credentials grant type token endpoint
在ASP.NET中基于Owin OAuth使用Client Credentials Grant授权发放Token的更多相关文章
- 在WebApi中基于Owin OAuth使用授权发放Token
如何基于Microsoft.Owin.Security.OAuth,使用Client Credentials Grant授权方式给客户端发放access token? Client Credentia ...
- 在ASP.NET Web API 2中使用Owin OAuth 刷新令牌(示例代码)
在上篇文章介绍了Web Api中使用令牌进行授权的后端实现方法,基于WebApi2和OWIN OAuth实现了获取access token,使用token访问需授权的资源信息.本文将介绍在Web Ap ...
- Oauth Client Credentials Grant
http://www.cnblogs.com/dudu/p/4569857.html OAuth真是一个复杂的东东,即使你把OAuth规范倒背如流,在具体实现时也会无从下手.因此,Microsoft. ...
- (转)基于OWIN WebAPI 使用OAuth授权服务【客户端模式(Client Credentials Grant)】
适应范围 采用Client Credentials方式,即应用公钥.密钥方式获取Access Token,适用于任何类型应用,但通过它所获取的Access Token只能用于访问与用户无关的Open ...
- 基于OWIN WebAPI 使用OAuth授权服务【客户端模式(Client Credentials Grant)】
适应范围 采用Client Credentials方式,即应用公钥.密钥方式获取Access Token,适用于任何类型应用,但通过它所获取的Access Token只能用于访问与用户无关的Open ...
- ASP.NET OWIN OAuth:遇到的2个refresh token问题
之前写过2篇关于refresh token的生成与持久化的博文:1)Web API与OAuth:既生access token,何生refresh token:2)ASP.NET OWIN OAuth: ...
- 基于 IdentityServer3 实现 OAuth 2.0 授权服务【客户端模式(Client Credentials Grant)】
github:https://github.com/IdentityServer/IdentityServer3/ documentation:https://identityserver.githu ...
- [OAuth]基于DotNetOpenAuth实现Client Credentials Grant
Client Credentials Grant是指直接由Client向Authorization Server请求access token,无需用户(Resource Owner)的授权.比如我们提 ...
- 利用Fiddler模拟通过Dynamics 365的OAuth 2 Client Credentials认证后调用Web API
微软动态CRM专家罗勇 ,回复337或者20190521可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me. 配置Dynamics 365 & PowerApps 支 ...
随机推荐
- 一个粗心的Bug,JSON格式不规范导致AJAX错误
一.事件回放 今天工作时碰到了一个奇怪的问题,这个问题很早很早以前也碰到过,不过没想到过这么久了竟然又栽在这里. 当时正在联调一个项目,由于后端没有提供数据接口,于是我直接本地建立了一个 json ...
- 采用MiniProfiler监控EF与.NET MVC项目(Entity Framework 延伸系列1)
前言 Entity Framework 延伸系列目录 今天来说说EF与MVC项目的性能检测和监控 首先,先介绍一下今天我们使用的工具吧. MiniProfiler~ 这个东西的介绍如下: MVC Mi ...
- JavaScript之职责链模式
一.概述 职责链模式(Chain of responsibility),就是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连成一条链,并沿着这条链传递该请求,直到有 ...
- 编写自己的PHP MVC框架笔记
1.MVC MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器(Controller). ...
- [笔记]kubernetes 无法启动问题
在启动kubernetes的时候报错误. ERROR: timed out for http://localhost:4001/v2/keys/ 原因是无法启动etcd, etcd 监听4001本地端 ...
- 屌丝giser成长记-大学篇
作为一名屌丝giser的我,刚接触gis专业是2007年的大一,好悲催,当时gis这个专业是被调剂的,我压根都不知道gis为何物,那时候gis冷门的一逼,报名这个专业的寥寥无几.记得那时候得知被调剂到 ...
- Android—应用程序开机自启
android开机时候会发送开机广播,我们想要收到广播知道手机开机,才能启动我们的应用程序. 首先要在配置文件中添加相应权限: <uses-permission android:name=&qu ...
- webService
什么是webService WebService,顾名思义就是基于Web的服务.它使用Web(HTTP)方式,接收和响应外部系统的某种请求.从而实现远程调用. 1:从WebService的工作模式上 ...
- JavaScript知识结构图
画的一个知识结构图,方便理解.
- 我的MYSQL学习心得(三) 查看字段长度
我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...