1)用Visual Studio 2013/2015创建一个Web API 4项目,VS会生成一堆OAuth相关代码。
2)打开Startup.Auth.cs ,精简一下代码,我们只需要实现以Client Credentials Grant授权方式拿到token,其它无关代码全部清除,最终剩下如下代码:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.Google;
using Microsoft.Owin.Security.OAuth;
using Owin;
using WebApi4.Providers;
using WebApi4.Models;
namespace WebApi4
{
public partial class Startup
{
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
public static string PublicClientId { get; private set; }
// 有关配置身份验证的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
var OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/token"),//获取Token的地址 示例:http://localhost:54342/token
Provider = new CustomAuthorizationServerProvider(),//
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),//Token有效期
AllowInsecureHttp = true
};
app.UseOAuthBearerTokens(OAuthOptions);
}
}
}
3)创建一个新的类 CustomAuthorizationServerProvider,并继承自 OAuthAuthorizationServerProvider,重载 OAuthAuthorizationServerProvider() 与 GrantClientCredentials() 这两个方法。代码如下:
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.OAuth;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
namespace WebApi4.Providers
{
public class CustomAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
/// <summary>
/// 在 ValidateClientAuthentication() 方法中获取客户端的 client_id 与 client_secret 进行验证
/// 在 GrantClientCredentials() 方法中对客户端进行授权,授了权就能发 access token
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
string clientId;
string clientSecret;
context.TryGetBasicCredentials(out clientId, out clientSecret);//使用Basic Authentication传递clientId与clientSecret;使用Form Authentication TryGetFormCredentials
if (clientId == "xsj" && clientSecret == "1989")
{
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, "xsj"));
var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties());
context.Validated(ticket);
return base.GrantClientCredentials(context);
}
}
}
4)然后写客户端调用代码测试一下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Web;
using System.Web.Mvc;
namespace WebApi4.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Title = "Home Page";
return View();
}
public ContentResult Get_Accesss_Token_By_Client_Credentials_Grant()
{
//Home/Get_Accesss_Token_By_Client_Credentials_Grant
//使用Form Authentication 传递 clientId与clientSecret
//HttpClient _httpClient = new HttpClient();
//_httpClient.BaseAddress = new Uri("http://localhost:54342");
//var parameters = new Dictionary<string, string>();
//parameters.Add("client_id", "xsj");
//parameters.Add("client_secret", "1989");
//parameters.Add("grant_type", "client_credentials");//
//string result = _httpClient.PostAsync("/token", new FormUrlEncodedContent(parameters)).Result.Content.ReadAsStringAsync().Result;
//return Content(result);
//使用Basic Authentication传递clientId与clientSecret
var clientId = "xsj";//用户名
var clientSecret = "1989";//密码
HttpClient _httpClient = new HttpClient();
_httpClient.BaseAddress = new Uri("http://localhost:54342");
_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");
string result = _httpClient.PostAsync("/token", new FormUrlEncodedContent(parameters)).Result.Content.ReadAsStringAsync().Result;
return Content(result);
}
}
}
返回结果:
{"access_token":"aH7eq761wPUqjffAW0Q9qoxY1LxQ3bXVSFnjIIXOmG2u_PpSVYxW5xmdr1tYWFFSYN4X2vPKqW0HFFSoNNdG6Os3zU-_NAG5AYcJMcotYPkvqQbkueaHXzDf8qvWIIbyLI0u7oxhTNyV_OpEuZkUUcUceCBoLOc9_y4Ff627UEvQErZriTK_OoT0atxsyKftxUW2m0pUxHLWpb2p6Ys25g","token_type":"bearer","expires_in":1209599}
注:使用Basic Authentication传递clientId与clientSecret,服务端CustomAuthorizationServerProvider中的TryGetFormCredentials()改为TryGetBasicCredentials()
使用Fiddler获得Token:

【参考资料】
http://www.cnblogs.com/dudu/p/4569857.html
http://www.hackered.co.uk/articles/asp-net-mvc-creating-an-oauth-client-credentials-grant-type-token-endpoint
在ASP.NET中基于Owin OAuth使用Client Credentials Grant授权发放Token
原文:http://www.cnblogs.com/xsj1989/p/5557251.html