Owin.OAuth

概念

OAuth2四种模式

  • 授权码模式(authorization code)
  • 简化模式(implicit)
  • 密码模式(resource owner password credentials)
  • 客户端模式(client credentials)

授权码模式

QQ,微信,等方式

  • 用户访问客户端,后者将前者导向认证服务器。
  • 用户选择是否给予客户端授权。
  • 假设用户给予授权,认证服务器将用户导向客户端事先指定的”重定向URI”(redirection URI),同时附上一个授权码。
  • 客户端收到授权码,附上早先的”重定向URI”,向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
  • 认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。

请求

  1. response_type:表示授权类型,必选项,此处的值固定为"code"
  2. client_id:表示客户端的ID,必选项
  3. redirect_uri:表示重定向URI,可选项
  4. scope:表示申请的权限范围,可选项
  5. state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。

客户端模式

对于这种方式,试用在 访问一些和用户无关的Open Api,比如一些首页数据,这些数据和用户无关,但是又不想任何人都可以调用这个WebApi,那么就可以采用这种模式。

这个流程很像账号密码模式,但是它认证的是客户端身份,而不是用户

  1. 客户端向认证服务器进行身份认证,并且要求一个访问令牌。
  2. 认证服务器认证无误后,向客户端提供访问令牌。

密码模式

这种模式是很清晰的.就跟传统的验证一样.

  1. 用户(确切的说是客户端)发用户名密码给资源提供者
  2. 资源提供者验证成功后返回访问令牌
  1. grant_type:表示授权类型,此处的值固定为"password",必选项。
  2. username:表示用户名,必选项。
  3. password:表示用户的密码,必选项。
  4. scope:表示权限范围,可选项。

配置

  1. public class Startup
  2. {
  3. public void Configuration(IAppBuilder app)
  4. {
  5. //授权配置
  6. var OAuthOptions = new OAuthAuthorizationServerOptions
  7. {
  8. //获取Token的路径
  9. TokenEndpointPath = new PathString("/Token"),
  10. //自定义的 校验,授权器
  11. Provider = new ApplicationOAuthProvider(),
  12. //我们不想让客户端直接输入凭据,需要一个服务器进行发放授权,这个就像点开QQ第三方登入弹出的登入页面.AuthorizeEndpointPath就是这种页面的地址
  13. AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
  14. //Token 过期时间,默认20分钟
  15. AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
  16. //在生产模式下设 AllowInsecureHttp = false
  17. AllowInsecureHttp = true
  18. };
  19. app.UseOAuthBearerTokens(OAuthOptions);
  20. }
  21. }

通过请求TokenEndpointPath获得Access_Token

自定义OAuthProvider

Owin.OAuth提供的授权方式有

  • GrantAuthorizationCode 授权码模式
  • GrantResourceOwnerCredentials 密码模式
  • GrantClientCredentials 客户端模式
  • GrantCustomExtension 自定义模式,只要grant_type不是上述3个

UseOAuthBearerTokens 内部包含了

  • UseOAuthAuthorizationServer
  • UseOAuthBearerAuthentication

通过基础OAuthAuthorizationServerProvider来定义自己的授权,通过重写上述相应的方法来选择不同的授权模式.这些方法触发条件就是grant_type,不同的值会触发不同的方法.

但在这之前必须经过ValidateClientAuthentication.因为整个流程就是认证->授权,认证是判断这个用户是否是本系统的,授权是给予用户相应的标记,该标记不仅标示用户身份也表示用户的权限.

  1. public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
  2. {
  3. public ApplicationOAuthProvider()
  4. {
  5. }
  6. ///
  7. /// 客户端验证,这是必须通过的方法,确保客户端是正确的,这里通过后才能开始授权
  8. ///
  9. ///
  10. ///
  11. public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
  12. {
  13. //context.TryGetFormCredentials() 从表单中获取clientId,clientSecret
  14. //context.TryGetBasicCredentials 从Authenticate Base解密 获取clientId,lientSecret
  15. //在数据库中查看clientId的有效性
  16. //在这里还没有些clientId,所以下面这句意思是,如果不是使用password认知方式,则直接验证通过,其clientId设置为12
  17. if (context.Parameters["username"] == null && context.Parameters["password"] == null)
  18. {
  19. context.Validated("123");
  20. }
  21. return base.ValidateClientAuthentication(context);
  22. }
  23. ///
  24. /// 账号密码授权,grant_type:password
  25. ///
  26. ///
  27. ///
  28. public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
  29. {
  30. var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
  31. oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
  32. //生成token
  33. var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties());
  34. context.Validated(ticket);//授权
  35. return base.GrantResourceOwnerCredentials(context);
  36. }
  37. ///
  38. /// 对客户端进行授权,grant_type:client_credentials
  39. ///
  40. ///
  41. ///
  42. public override Task GrantClientCredentials(OAuthGrantClientCredentialsContext context)
  43. {
  44. var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
  45. context.Request.Body.Seek(0, SeekOrigin.Begin);
  46. //从报文体重获取数据
  47. string FormStr = new StreamReader(context.Request.Body).ReadToEnd();
  48. var FormKeyValues = HttpUtility.ParseQueryString(FormStr);
  49. //登入
  50. var loginresult = AsyncHelper.RunSync<LoginOutput>(()=>studentLoginApp.Login(new LoginInput()
  51. {
  52. StuNum = FormKeyValues["StuNum"],
  53. Psw = FormKeyValues["Psw"]
  54. }));
  55. //添加Cookie到声明
  56. oAuthIdentity.AddClaim(new Claim(loginresult.Cookie.Name, loginresult.Cookie.Value));
  57. //添加学号
  58. oAuthIdentity.AddClaim(new Claim(ClaimTypes.UserData, loginresult.StuNum));
  59. //生成token
  60. var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties());
  61. context.Validated(ticket);
  62. return base.GrantClientCredentials(context);
  63. }
  64. }

这里重写了3个方法

- ValidateClientAuthentication

- GrantResourceOwnerCredentials

- GrantClientCredentials

当请求Access_Token时候必定经过ValidateClientAuthentication,这个通常客户端会带上clientId,lientSecret,在此验证两个数据的正确性,得知该客户端是否有权向本网站申请授权

当通过ValidateClientAuthentication后,则会根据请求中的grant_type来调用GrantResourceOwnerCredentials(password)或GrantClientCredentials(client_credentials)

GrantClientCredentials一般用于普通资源的授权,就是人人都能使用的资源.

GrantResourceOwnerCredentials 则是对用户有要求,需要登入才能使用资源,在这个方法中可以给用户Claim添加数据,比如Role,并再资源上打上Authentication(Role=”“)来限制

获得授权码后调用资源

这个是普通资源请求,按理要加上clientId,clientSecret可以直接加到Body中,也可以加到Headers的Authorization

注意这里的Body一定要是x-www-form-urlencoded,否则后端识别不出来,在ajax的时候可能会出问题

  1. _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",Convert.ToBase64String(Encoding.ASCII.GetBytes(clientId + ":" + clientSecret)));

如果数据都正确则能获得Access_Token

在这之后的请求需要要把Access_Token添加到Authorization中

未学习

  • refresh_token
  • 自定义授权失败响应信息

资料

时间: 2024-10-29 10:46:55

Owin.OAuth的相关文章

ASP.NET Web API与Owin OAuth:调用与用户相关的Web API

参考页面: http://www.yuanjiaocheng.net/webapi/web-api-route.html http://www.yuanjiaocheng.net/webapi/parameter-binding.html http://www.yuanjiaocheng.net/webapi/action-method-returntype.html http://www.yuanjiaocheng.net/webapi/web-api-reqresq-format.html

ASP.NET OWIN OAuth:refresh token的持久化

在前一篇博文中,我们初步地了解了refresh token的用途——它是用于刷新access token的一种token,并且用简单的示例代码体验了一下获取refresh token并且用它刷新access token.在这篇博文中,我们来进一步探索refresh token. 之前只知道refresh token是用于刷新access token的,却不知道refresh token凭什么可以刷新access token?知其然,却不知其所以然. 这是由于之前没有发现refresh token

OWIN OAuth 2.0 Authorization Server

OWIN OAuth 2.0 Authorization Server 源码在上面的地址中可以下载 打开客户端页面http://localhost:38500/ 客户端代码引用了DotNetOpenAuth.OAuth2 public class HomeController : Controller { private WebServerClient _webServerClient; public ActionResult Index() { ViewBag.AccessToken = Re

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

之前写过2篇关于refresh token的生成与持久化的博文:1)Web API与OAuth:既生access token,何生refresh token:2)ASP.NET OWIN OAuth:refresh token的持久化. 之后我们在CNBlogsRefreshTokenProvider中这样实现了refresh token的生成与持久化: public class CNBlogsRefreshTokenProvider : AuthenticationTokenProvider

在ASP.NET Web API 2中使用Owin OAuth 刷新令牌

在上篇文章介绍了Web Api中使用令牌进行授权的后端实现方法,基于WebApi2和OWIN OAuth实现了获取access token,使用token访问需授权的资源信息.本文将介绍在Web Api中启用刷新令牌的后端实现. 本文要用到上篇文章所使用的代码,代码编写环境为VS 2017..Net Framework 4.7.2,数据库为MS SQL 2008 R2. OAuth 刷新令牌 上文已经搞了一套Token授权访问,这里有多出来一个刷新令牌(Refresh Token),平白添加程序

ASP.NET Web API与Owin OAuth:使用Access Toke调用受保护的API

在前一篇博文中,我们使用OAuth的Client Credential Grant授权方式,在服务端通过CNBlogsAuthorizationServerProvider(Authorization Server的一个实现)成功发放了Access Token,并在客户端成功拿到了Access Token. 那Access Token有什么用呢?在OAuth中对Resource Server(比如Web API)访问权限的验证都是基于Access Token.不管是什么样的客户端来调用,Reso

【7】.net WebAPI Owin OAuth 2.0 密码模式验证实例

1.OAuth密码模式 2.在VS中创建WebAPI项目 在nuget中安装: Microsoft.AspNet.WebApi.Owin Microsoft.Owin.Host.SystemWeb 这两个类库并添加Owin启动类Startup using System; using System.Threading.Tasks; using Microsoft.Owin; using Owin; using Microsoft.Owin.Security.OAuth; [assembly: Ow

在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的授权方式就

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

如何基于Microsoft.Owin.Security.OAuth,使用Client CredentialsGrant授权方式给客户端发放access token? Client CredentialsGrant的授权方式就是只验证客户端(Client),不验证用户(Resource Owner),只要客户端通过验证就发accesstoken.举一个对应的应用场景例子,比如我们想提供一个“获取网站首页最新博文列表”的WebAPI给客户端App调用.由于这个数据与用户无关,所以不涉及用户登录与授权