之前已经简单实现了OAUTH2的授权码模式(Authorization Code),但是基于JAVA的,今天花了点时间调试了OWIN的实现,基本就把基于OWIN的OAUHT2的四种模式实现完了。官方推荐的.NET 包有

Katana已经不更新了,新的版本是已经是asp.net core 1.0的一部分,实现OAUTH2好的选择可以考虑使用新版或IdentityServer3对应asp.net core 1.0版本为IdentityServer4。

Startup

public partial class Startup
{
private readonly ConcurrentDictionary<string, string> _authenticationCodes = new ConcurrentDictionary<string, string>(StringComparer.Ordinal);
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = Paths.AuthenticationType,
AuthenticationMode = AuthenticationMode.Passive,
LoginPath = new PathString(Paths.LoginPath),
LogoutPath = new PathString(Paths.LogoutPath),
}); app.UseOAuthBearerTokens(new OAuthAuthorizationServerOptions
{
AuthorizeEndpointPath = new PathString(Paths.AuthorizePath),
TokenEndpointPath = new PathString(Paths.TokenPath),
AccessTokenExpireTimeSpan = TimeSpan.FromHours(2),
Provider = new OAuthAuthorizationServerProvider
{
OnValidateClientRedirectUri = ValidateClientRedirectUri,
OnValidateClientAuthentication = ValidateClientAuthentication,
OnGrantResourceOwnerCredentials = GrantResourceOwnerCredentials,
OnGrantClientCredentials = GrantClientCredetails
},
//Provider = new ApplicationOAuthProvider(),
AuthorizationCodeProvider = new AuthenticationTokenProvider
{
OnCreate = CreateAuthenticationCode,
OnReceive = ReceiveAuthenticationCode,
},
RefreshTokenProvider = new AuthenticationTokenProvider
{
OnCreate = CreateRefreshToken,
OnReceive = ReceiveRefreshToken,
},
ApplicationCanDisplayErrors = true,
#if DEBUG
//HTTPS is allowed only AllowInsecureHttp = false
AllowInsecureHttp = true,
#endif
});
} private void CreateAuthenticationCode(AuthenticationTokenCreateContext context)
{
context.SetToken(Guid.NewGuid().ToString("n") + Guid.NewGuid().ToString("n"));
_authenticationCodes[context.Token] = context.SerializeTicket();
} private void ReceiveAuthenticationCode(AuthenticationTokenReceiveContext context)
{
string value;
if (_authenticationCodes.TryRemove(context.Token, out value))
{
context.DeserializeTicket(value);
}
} private Task GrantClientCredetails(OAuthGrantClientCredentialsContext context)
{
var identity = new ClaimsIdentity(new GenericIdentity(context.ClientId, OAuthDefaults.AuthenticationType), context.Scope.Select(x => new Claim("urn:oauth:scope", x)));
context.Validated(identity);
return Task.FromResult(0);
} private Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var identity = new ClaimsIdentity(new GenericIdentity(context.UserName, OAuthDefaults.AuthenticationType), context.Scope.Select(x => new Claim("urn:oauth:scope", x)));
context.Validated(identity);
return Task.FromResult(0);
} private Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
string clientId;
string clientSecret;
if (context.TryGetBasicCredentials(out clientId, out clientSecret) || context.TryGetFormCredentials(out clientId, out clientSecret))
{
context.Validated();
}
return Task.FromResult(0);
} private Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
{
if (context.ClientId == Clients.Client1.Id)
{
context.Validated();
//context.Validated(Clients.Client1.RedirectUrl);
}
else if (context.ClientId == Clients.Client2.Id)
{
context.Validated(Clients.Client2.RedirectUrl);
}
return Task.FromResult(0);
} private void CreateRefreshToken(AuthenticationTokenCreateContext context)
{
context.SetToken(context.SerializeTicket());
} private void ReceiveRefreshToken(AuthenticationTokenReceiveContext context)
{
context.DeserializeTicket(context.Token);
}
}

OAuthController

/// <summary>
/// 授权码模式授权
/// </summary>
/// <returns></returns>
public ActionResult Authorize()
{
var authentication = HttpContext.GetOwinContext().Authentication;
var ticket = authentication.AuthenticateAsync(Paths.AuthenticationType).Result;
var identity = ticket != null ? ticket.Identity : null;
if (identity == null)
{
authentication.Challenge(Paths.AuthenticationType);
return new HttpUnauthorizedResult();
}
var scopes = (Request.QueryString.Get("scope") ?? "").Split(' ');
if (Request.HttpMethod == "POST")
{
if (!string.IsNullOrEmpty(Request.Form.Get("submit.Grant")))
{
identity = new ClaimsIdentity(identity.Claims, "Bearer", identity.NameClaimType, identity.RoleClaimType);
foreach (var scope in scopes)
{
identity.AddClaim(new Claim("urn:oauth:scope", scope));
}
authentication.SignIn(identity);
}
if (!string.IsNullOrEmpty(Request.Form.Get("submit.Login")))
{
authentication.SignOut("Application");
authentication.Challenge("Application");
return new HttpUnauthorizedResult();
}
}
return View();
}

AccountController

/// <summary>
/// 用户登录
/// </summary>
/// <returns></returns>
public ActionResult Login()
{
var authentication = HttpContext.GetOwinContext().Authentication;
if (Request.HttpMethod == "POST")
{
var isPersistent = !string.IsNullOrEmpty(Request.Form.Get("isPersistent"));
if (!string.IsNullOrEmpty(Request.Form.Get("submit.Signin")))
{
authentication.SignIn(
new AuthenticationProperties { IsPersistent = isPersistent },
new ClaimsIdentity(new[] { new Claim(ClaimsIdentity.DefaultNameClaimType, Request.Form["username"]) }, "Application"));
}
}
return View();
} /// <summary>
/// 退出
/// </summary>
/// <returns></returns>
public ActionResult Logout()
{
return View();
}

调试

获得授权码

GET /oauth/authorize?client_id=irving&redirect_uri=http://localhost:38500/oauth_callback&state=LYUVwcuaGuKeRTjxhdFzhQ&scope=bio

%20notes&response_type=code HTTP/1.1

http://localhost:56889/oauth/authorize?

client_id=irving&redirect_uri=http://localhost:38500/oauth_callback&state=LYUVwcuaGuKeRTjxhdFzhQ&scope=bio%20notes&response_type=code

页面重定向

HTTP/1.1 302 Found

Location: /oauth_callback?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz

http://localhost:56889/oauth_callback?code=0aa3e35bd515413bb93bdb6fb015591cc763a8d30c554730a07ebd39e3149252&state=LYUVwcuaGuKeRTjxhdFzhQ

获得令牌

POST /token HTTP/1.1

Host: server.example.com

Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=929dc42905a24e79bdf028f7043769acddd90056ca8141708b3834ec174e8083&state=LYUVwcuaGuKeRTjxhdFzhQ&redirect_uri=http://localhost:38500/oauth_callback

源码:https://github.com/zhouyongtao/SecuringForWebAPI/tree/master/KatanaForWebAPI

注意事项

资源服务器识别认证服务器颁发的令牌, 需要配置相同的machinekey

<machineKey decryptionKey="B7EFF1C5839A624E3F97D0268917EDE82F408D2ECBFAC817" validation="SHA1" validationKey="C2B8DF31AB9624D69428066DFDA1A479542825F3B48865C4E47AF6A026F22D853DEC2B3248DF268599BF89EF78B9E86CA05AC73577E0D5A14C45E0267588850B" />

REFER:

http://beginor.github.io/2015/01/24/oauth2-server-with-owin.html

http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server

基于OWIN WebAPI 使用OAUTH2授权服务【授权码模式(Authorization Code)】的更多相关文章

  1. 【干货】基于Owin WebApi 使用OAuth2进行客户端授权服务

    前言:采用Client Credentials方式,即密钥key/password,场景一般是分为客户端限制必须有权限才能使用的模块,这和微信公众号开放平台很类似. 让用户通过客户端去获取自己的tok ...

  2. IdentityServer4 (3) 授权码模式(Authorization Code)

    写在前面 1.源码(.Net Core 2.2) git地址:https://github.com/yizhaoxian/CoreIdentityServer4Demo.git 2.相关章节 2.1. ...

  3. Apache Oltu 实现 OAuth2.0 服务端【授权码模式(Authorization Code)】

    要实现OAuth服务端,就得先理解客户端的调用流程,服务提供商实现可能也有些区别,实现OAuth服务端的方式很多,具体可能看 http://oauth.net/code/ 各语言的实现有(我使用了Ap ...

  4. Owin中间件搭建OAuth2.0认证授权服务体会

    继两篇转载的Owin搭建OAuth 2.0的文章,使用Owin中间件搭建OAuth2.0认证授权服务器和理解OAuth 2.0之后,我想把最近整理的资料做一下总结. 前两篇主要是介绍概念和一个基本的D ...

  5. 使用Owin中间件搭建OAuth2.0认证授权服务器

    前言 这里主要总结下本人最近半个月关于搭建OAuth2.0服务器工作的经验.至于为何需要OAuth2.0.为何是Owin.什么是Owin等问题,不再赘述.我假定读者是使用Asp.Net,并需要搭建OA ...

  6. 基于 IdentityServer3 实现 OAuth 2.0 授权服务【密码模式(Resource Owner Password Credentials)】

    密码模式(Resource Owner Password Credentials Grant)中,用户向客户端提供自己的用户名和密码.客户端使用这些信息,向"服务商提供商"索要授权 ...

  7. 【PHP】基于ThinkPHP框架搭建OAuth2.0服务

    [PHP]基于ThinkPHP框架搭建OAuth2.0服务 http://leyteris.iteye.com/blog/1483403

  8. OAuth2.0学习(1-6)授权方式3-密码模式(Resource Owner Password Credentials Grant)

    授权方式3-密码模式(Resource Owner Password Credentials Grant) 密码模式(Resource Owner Password Credentials Grant ...

  9. OAuth 第三方登录授权码(authorization code)方式的小例子

    假如上面的网站A,可以通过GitHub账号登录: 下面以OAuth其中一种方式,授权码(authorization code)方式为例. 一.第三方登录的原理 所谓第三方登录,实质就是 OAuth 授 ...

随机推荐

  1. MongoEngine简易教程(转)

    原文:http://www.xefan.com/archives/84063.html Mongoengine教程(1)——概述 Mongoengine教程(2)——文档模式 Mongoengine教 ...

  2. MC的一些具体的应用的例子的总结

    任何东西,都有其适用的场景,在合适的场景下,才能发挥好更大的作用. 对于memcached,使用内存来存取数据,一般情况下,速度比直接从数据库和文件系统读取要快的多. memcached的最常用的场景 ...

  3. {CSDN}{英雄会}{火车调度}

    思路: 给定一系列时刻表,求能满足各个时刻的最小火车数量. 打眼一看, 把此题归入到最大流,仔细一想不符合流网络的规律,换思路. 由于是一个最优化问题,自然想到动态规划和贪心. 最后确定贪心.从最早出 ...

  4. BootLoader 详解(1)

    1. Boot Loader的概念 BootLoader就是在操作系统内核运行前之前运行的一段小程序.通过这段小程序,可以初始化硬件设备.建立内存空间映射图,从而将系统的软硬件带到一个合适的状态,以便 ...

  5. 生成prefix.pch文件

    (借鉴网络资源)

  6. 搭建本地MAVEN NEXUS 服务

    下载 http://120.192.76.70/cache/www.sonatype.org/downloads/nexus-latest-bundle.zip?ich_args=232fba36ed ...

  7. [Swift]基础

    [Swift]基础 一, 常用变量 var str = "Hello, playground" //变量 let str1="Hello xmj112288" ...

  8. Linux网络编程-SIGPIPE信号导致的程序退出问题

    当客户端close关闭连接时,若server端接着发送数据,根据TCP协议的规定,server端会收到RST响应,当server端再次往客户端发送数据时,系统会发出一个SIGPIPE信号给server ...

  9. IOS设计模式第一篇之MVC

    设计模式的好处:我们可以写出容易理解,重用度很高的代码.降低代码的耦合度,符合软件工程的思想. 设计模式主要分为三类:创造型的:单例和抽象工厂.结构类型的: MVC  Decorator, Adapt ...

  10. Java Web的开始学习

    今天开始学习Web了,需要的前提技能是  XML ,我还不太熟悉,今天的任务需要熟悉一下 XML-- 输入输出流  I/O     序列化反序列化,也需要看一下,我看这两块会有用到. 任务: ---- ...