Web API使用记录系列(四)OAuth授权与身份校验

  呼,开干第四篇,基于OWIN搭建OAuth认证授权服务器与接口身份校验。

  OAuth包含授权码模式、密码模式、客户端模式和简化模式,这里我们文章记录的是密码模式和客户端模式

  目录

  引用安装

  授权处理-发放Token

    用户名密码授权

    客户端授权

  身份校验-校验失败自定义返回信息

  TestClient增加token获取

  一、引用安装

  除了Owin使用时安装的引用外,还需要安装以下引用  

  Microsoft.Owin.Security.OAuth

  Microsoft.Owin.Security.Cookies

  Microsoft.AspNet.Identity.Owin

  二、搭建授权认证

  修改StartUp,添加关键词partial

  在App_Start下新建StartUp.Auth,同样使用关键词partial,添加ConfiguerAuth,代码如下:

  

 1 public partial class StartUp
 2     {
 3         /// <summary>
 4         /// OAuth配置
 5         /// </summary>
 6         /// <param name="app"></param>
 7         public void ConfigureAuth(IAppBuilder app)
 8         {
 9             app.UseOAuthBearerTokens(new OAuthAuthorizationServerOptions
10             {
11                 AllowInsecureHttp = true,
12                 TokenEndpointPath = new PathString("/api/token"),//授权地址
13                 AccessTokenExpireTimeSpan = TimeSpan.FromHours(24), //过期时间
14                 AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
15                 Provider = new SampleAuthorizationServerProvider() //授权服务
16             });
17         }
18     }

  SampleAuthorizationServerProvider是提供授权服务的方法,继承自OAuthAuthorizationServerProvider,包含客户端认证和用户名密码认证,代码如下

 1 /// <summary>
 2     /// 授权服务
 3     /// </summary>
 4     public class SampleAuthorizationServerProvider : OAuthAuthorizationServerProvider
 5     {
 6         #region 客户端授权
 7         /// <summary>
 8         /// 客户端验证
 9         /// </summary>
10         /// <param name="context"></param>
11         /// <returns></returns>
12         public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
13         {
14             string clientId = "";
15             string clientSecret = "";
16             //获取传入的客户端id和客户端校验码
17             context.TryGetFormCredentials(out clientId, out clientSecret);
18             if (clientId == "发放的客户端id" && clientSecret == "发放的客户端校验码")
19             {
20                 context.Validated(clientId);
21             }
22             else
23             {
24                 context.SetError("invalid_client", "client is not valid");
25             }
26             return base.ValidateClientAuthentication(context);
27         }
28
29         /// <summary>
30         /// 客户端授权-生成access token
31         /// </summary>
32         /// <param name="context"></param>
33         /// <returns></returns>
34         public override Task GrantClientCredentials(OAuthGrantClientCredentialsContext context)
35         {
36             var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
37             oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, "app"));//可以继续加一些其它信息
38             var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties() { AllowRefresh = false });
39             context.Validated(ticket);
40             return base.GrantClientCredentials(context);
41         }
42         #endregion
43
44         #region 用户名密码授权
45         public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
46         {
47             if (context.UserName == "用户名" && context.Password == "用户密码")
48             {
49                 var props = new AuthenticationProperties(new Dictionary<string, string>
50                 {
51                     {
52                         "userName", context.UserName
53                     }
54                 });
55                 var identity = new ClaimsIdentity("userinfo");
56                 identity.AddClaim(new Claim("DisplayName", "张三"));
57                 identity.AddClaim(new Claim("DutyName", "总监"));
58
59                 var ticket = new AuthenticationTicket(identity, props);
60
61                 context.Validated(ticket);
62             }
63             else
64             {
65                 context.SetError("invalid_user", "username or password error");
66             }
67             return base.GrantResourceOwnerCredentials(context);
68         }
69         #endregion
70
71     }

  在根目录App_Start中增加  ConfigureAuth(app);

  请求Token(以客户端验证为示例)

 1           $.ajax({
 2                 url: ‘/api/token‘,
 3                 type: ‘post‘,
 4                 data: {
 5                     "grant_type": "client_credentials",
 6                     "client_id": $("#clientid").val(),
 7                     "client_secret": $("#clientscuret").val()
 8                 },
 9                 dataType: "json",
10                 success: function (data) {
11                     var accessToken = data.access_token;
12                     console.log("获取到的token:"+accessToken);
13                 }
14             });    

  三、身份认证与身份认证失败自定义返回

  增加身份认证,只需要在需要使用的controller上增加 特性 [Authorize]

  不需要启用验证的使用特性 [AllowAnonymous]

  认证失败返回401,但为了和我们项目的返回数据结构一致,我们需要在认证失败的时候修改返回,新建过滤器继承AuthorizeAttribute,完事将使用Authorized的地方替换为自定义的过滤器

  

 1 public class CustomAuthorizeAttribute:AuthorizeAttribute
 2     {
 3         protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
 4         {
 5             base.HandleUnauthorizedRequest(actionContext);
 6             actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.OK)
 7             {
 8                 Content = new StringContent("项目返回的数据格式数据")
 9             };
10         }
11     }

  四、TestClient

  为了方便在线测试接口添加token的方便,我们需要给弹出的调用窗口增加authorization的header信息、获取token的操作;并将获取到的token存储到cookie,打开窗口时存在自填充,省去每次的获取操作

  》文件TestClientDialogs文件,在<div class="panel"> 内添加如下代码

  

 1 <div style="margin-bottom:10px;background:#EFEFEF;border:1px solid #ccc;padding:10px">
 2             <div>
 3                 客户端id:
 4                 <input type="text" id="clientid" value="admin" />
 5                 客户端securet:
 6                 <input type="password" id="clinetsecuret" value="admin" />
 7                 <a href=‘javascript:;‘ id="btngettk">获取 Token</a>
 8             </div>
 9             <div style="padding:5px;background:#ffd800;" id="getmsg"> <span> 正在获取Token,请稍后...</span></div>
10         </div>
11
12         <hr />

  》WebApiTestClient.js中修改如下(TestClientViewModel方法末尾添加):

 1 //支持弹出窗口自动填充token
 2         var accessToken;
 3         try {
 4             accessToken = $.cookie("token");
 5         } catch (e) {
 6             console.log(e);
 7         }
 8         addOrReplaceHeader(self.RequestHeaders, "authorization", "Bearer " + accessToken);
 9         //不存在token时点击获取按钮获取token
10         $("#getmsg").hide();
11         $("#btngettk").click(function () {
12             $("#getmsg").show();
13             $.ajax({
14                 url: ‘/api/token‘,
15                 type: ‘post‘,
16                 data: {
17                     "grant_type": "client_credentials",
18                     "client_id": $("#txtusername").val(),
19                     "client_secret": $("#txtpwd").val()
20                 },
21                 dataType: "json",
22                 success: function (data) {
23                     var headers = self.RequestHeaders;
24                     var accessToken = data.access_token;
25                     $.cookie("token", accessToken, { path: "/", expires: 1 });
26                     addOrReplaceHeader(headers, "authorization", "Bearer " + accessToken);
27                     $("#getmsg").hide();
28                 }
29             });
30
31         })

  

本系列使用记录到此,有用到的再补充,有不对的地方希望大家帮忙指正修改,感谢!

原文地址:https://www.cnblogs.com/xihao/p/10630024.html

时间: 2024-09-30 14:23:06

Web API使用记录系列(四)OAuth授权与身份校验的相关文章

在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),平白添加程序

Web API在OWIN下实现OAuth

Web API在OWIN下实现OAuth OAuth(Open Authorization) 为用户资源的授权提供了一个安全的.开放而又简易的标准.与以往的授权方式不同之处是OAuth的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此OAuth是安全的. 本节目录: Owin下WebAPI SelfHost 创建AccessToken 使用AccessToken Owin下WebAPI SelfHost 1.创建一个控

WEB API项目实战系列-导航篇(十足干货分享)

这个系列的目的是想把最近两年在WEB API的实践方面积累的干货倒出来, 分享给大家. 同时也欢迎正在使用WEB API或者即将OR打算在项目中使用WEB API的朋友探讨交流,以让我有足够的热情完成这个系列.   这个实战适用于哪些情况? 1. 首要适用于APP服务器端开发,主要为APP提供服务端,与APP交互,完成各种数据交换. 2. 前后端分离的时候作为后端存在,承担业务处理的职责,减少前端的业务处理. 3. 为不同系统提供统一的数据交换,XML,JSON作为最常用的两种系统间数据交换格式

[ASP.NET] 结合Web API在OWIN下实现OAuth

OAuth(Open Authorization) 为用户资源的授权提供了一个安全的.开放而又简易的标准.与以往的授权方式不同之处是OAuth的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此OAuth是安全的. 本节目录: Owin下WebAPI SelfHost 创建AccessToken 使用AccessToken Owin下WebAPI SelfHost 1.创建一个控制台项目(其实类库都可以)ApiServe

Asp.Net Web API 2第十四课——Content Negotiation(内容协商)

前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文描述ASP.NET Web API如何实现内容协商. HTTP规范(RFC 2616)将内容协商定义为“在有多个表现可用时,为一个给定的响应选择最佳表现的过程”.在HTTP中内容协商的主要机制是以下请求报头: Accept:响应可接收的媒体类型,如“application/json”.“application/xml”,

Web API (scroll系列)、(仿淘宝侧边栏效果实现)、(mouseenter与mouseover的区别)、(动画的原理)、(缓动动画)

一 .三大系列中的scroll系列 : (1)scrollLeft |  scrollTop  :水平   |   垂直方向滚动出去的距离  : (2)scrollWidth |  scrollHeight   :内容的真是宽度  |  高度   : (3)滚动整个页面的时候  :   window . pageYOffset   : 二 .仿淘宝侧边栏效果实现 : 1.  找到关心的元素对象  : (1)banner区域  元素对象  : (2)侧边栏的元素对象   : (3)主体部分元素对象

[Web API] Web API 2 深入系列(5) 特性路由

小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03 目录 1. 特性路由注册 2. 路由解析 - 生成DataTokens - 选择HttpController - 选择Action 特性路由的目的在于更好的提供restful架构的接口,最近好忙(懒),所以更新速度慢. 特性路由注册 [Rout

Asp.Net Web API 2 官网菜鸟学习系列导航[持续更新中]

前言 本来一直参见于微软官网进行学习的, 官网网址http://www.asp.net/web-api.出于自己想锻炼一下学习阅读英文文章的目的,又可以学习下微软新发布的技术,其实也很久了,但自己菜鸟一枚,对自己来说都是新技术了.鉴于以上两个原因,本人打算借助google翻译和有道词典,来翻译学习这个系列,并通过博客园来记录自己的翻译学习过程.由于自己阅读水平的确太菜,在借助工具的情况下,有时候搞出来的也是蹩脚的语句,自己读着都难受,尤其是到了Web API路由的那两篇,所以自己想着是不是有别人

Dynamics CRM2016 Web API之更新记录

本篇继续探索web api,介绍如何通过web api更新记录. 下面是一段简单的更新代码,更新了几个不同类型的字段,entity的赋值和前篇创建时候的一样的. var entity = {}; entity["name"] = '测试更新';//文本 entity["new_gender"] = 100000001;//选项集 entity["new_birth"] = new Date();//日期 entity["[email p