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的更多相关文章

  1. 在WebApi中基于Owin OAuth使用授权发放Token

    如何基于Microsoft.Owin.Security.OAuth,使用Client Credentials Grant授权方式给客户端发放access token? Client Credentia ...

  2. 在ASP.NET Web API 2中使用Owin OAuth 刷新令牌(示例代码)

    在上篇文章介绍了Web Api中使用令牌进行授权的后端实现方法,基于WebApi2和OWIN OAuth实现了获取access token,使用token访问需授权的资源信息.本文将介绍在Web Ap ...

  3. Oauth Client Credentials Grant

    http://www.cnblogs.com/dudu/p/4569857.html OAuth真是一个复杂的东东,即使你把OAuth规范倒背如流,在具体实现时也会无从下手.因此,Microsoft. ...

  4. (转)基于OWIN WebAPI 使用OAuth授权服务【客户端模式(Client Credentials Grant)】

    适应范围 采用Client Credentials方式,即应用公钥.密钥方式获取Access Token,适用于任何类型应用,但通过它所获取的Access Token只能用于访问与用户无关的Open ...

  5. 基于OWIN WebAPI 使用OAuth授权服务【客户端模式(Client Credentials Grant)】

    适应范围 采用Client Credentials方式,即应用公钥.密钥方式获取Access Token,适用于任何类型应用,但通过它所获取的Access Token只能用于访问与用户无关的Open ...

  6. ASP.NET OWIN OAuth:遇到的2个refresh token问题

    之前写过2篇关于refresh token的生成与持久化的博文:1)Web API与OAuth:既生access token,何生refresh token:2)ASP.NET OWIN OAuth: ...

  7. 基于 IdentityServer3 实现 OAuth 2.0 授权服务【客户端模式(Client Credentials Grant)】

    github:https://github.com/IdentityServer/IdentityServer3/ documentation:https://identityserver.githu ...

  8. [OAuth]基于DotNetOpenAuth实现Client Credentials Grant

    Client Credentials Grant是指直接由Client向Authorization Server请求access token,无需用户(Resource Owner)的授权.比如我们提 ...

  9. 利用Fiddler模拟通过Dynamics 365的OAuth 2 Client Credentials认证后调用Web API

    微软动态CRM专家罗勇 ,回复337或者20190521可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me. 配置Dynamics 365 & PowerApps 支 ...

随机推荐

  1. ASP.NET Core 之 Identity 入门(二)

    前言 在 上篇文章 中讲了关于 Identity 需要了解的单词以及相对应的几个知识点,并且知道了Identity处在整个登入流程中的位置,本篇主要是在 .NET 整个认证系统中比较重要的一个环节,就 ...

  2. 06.LoT.UI 前后台通用框架分解系列之——浮夸的图片上传

    LOT.UI分解系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#lotui LoT.UI开源地址如下:https://github.com/du ...

  3. FragmentTabHost的基本用法

    开通博客以来已经约莫1个月了.几次想提笔写写东西,但总是由于各种各样的原因并没有开始.现在,年假刚结束,项目也还没有开始,但最终促使我写这篇博客的是,看了一篇博友写的新年计划,说是要在新的一年中写50 ...

  4. C#为IE编写BHO插件心得

    啥是BHO,其实大家都用过,没听过只是没在意而已,来张图你就知道是什么了 是不是很熟悉,就是这么个玩意~~ 先说说我要用来干嘛~我们有个库,里面数据很全面,但是某个部门需要在第三方的B/S系统录入某些 ...

  5. Xamarin+Prism开发详解四:简单Mac OS 虚拟机安装方法与Visual Studio for Mac 初体验

    Mac OS 虚拟机安装方法 最近把自己的电脑升级了一下SSD固态硬盘,总算是有容量安装Mac 虚拟机了!经过心碎的安装探索,尝试了国内外的各种安装方法,最后在youtube上找到了一个好方法. 简单 ...

  6. Xamarin+Prism开发详解二:Xaml文件如何简单绑定Resources资源文件内容

    我们知道在UWP里面有Resources文件xxx.resx,在Android里面有String.Xml文件等.那跨平台如何统一这些类别不一的资源文件以及Xaml设计文件如何绑定这些资源?应用支持多国 ...

  7. GPG终极指南(加密/签名)

    我们平时都听过非对称加密,公钥和私钥,签名验证,但这些证书都是怎么得到的呢?本篇文章会解答这些问题. 背景介绍 加密的一个简单但又实用的任务就是发送加密电子邮件.多年来,为电子邮件进行加密的标准一直是 ...

  8. React Native环境配置之Windows版本搭建

    接近年底了,回想这一年都做了啥,学习了啥,然后突然发现,这一年买了不少书,看是看了,就没有完整看完的.悲催. 然后,最近项目也不是很紧了,所以抽空学习了H5.自学啃书还是很无趣的,虽然Head Fir ...

  9. 项目持续集成环境(jenkins + SVN + maven + tomcat)

    整体流程 每次SVN上代码有变动,触发自动构建动作,并部署到服务器的tomcat上,具体流程: 1.SVN上提交代码修改 2.maven执行Goals 3.将web工程打成war包 4.关闭服务器的t ...

  10. C++的性能C#的产能?! - .Net Native 系列五:.Net Native与反射

    此系列系小九的学堂原创翻译,翻译自微软官方开发向导,一共分为六个主题.本文是第五个主题:.Net Native与反射. 向导文链接:<C++的性能C#的产能?! - .Net Native 系列 ...