OAuth在WebApi中的使用,前后台分离的调用方式

前段时间由于公司架构服务层向WebApi转换,就研究了OAuth在WebApi中的使用,这中间遇到了很多坑,在此记录一下OAuth的正确使用方式。

1、  OAuth是做什么的?

  在网上浏览时,大家都见过这样的功能:网站A提供了第三方登录服务,比如使用新浪微博、QQ账户登录。用户使用第三方账户登陆后,第三方返回Token给网站A,当网站A调用第三方服务请求登录用户信息时需传递该Token给第三方,第三方才允许该服务请求。之后的每次请求无需再次认证,直接使用该Token即可。这就是OAuth的典型应用。

2、  简单使用介绍 (具体使用OAuth的方法请参考:在ASP.NET中基于Owin OAuth使用Client Credentials Grant授权发放Token)

  2.1、用户登录的过程即是获取Token的过程,前端用户登录示例代码如下:

 1 $.ajax({
 2             type: "POST",
 3             url: api_address + "token", //api_address为WebApi服务地址,由于OAuth的使用中设置了属性TokenEndpointPath = new PathString("/token"),所以请求到“token”链接时即可自动进入认证流程。
 4             data: { grant_type: "password", username: username, password: password, ran: Math.random() },//传递用户名、密码、认证方式
 5             dataType: "json",
 6             success: function (result) {
 7                 if (result.access_token && result.access_token.length > 0) {
 8                       //result.access_token即是有效的服务调用凭证,可以把该值存入到Cookie中,以备下次使用。
 9 callback(1, "登录成功。");
10                 }
11                 else {
12                     callback(0, "未知错误!");
13                 }
14             },
15             error: function (XMLHttpRequest, textStatus, errorThrown) {
16                 callback(0, XMLHttpRequest.responseJSON.error);
17             }
18         });

登录代码

  2.2、当认证方式为password时,已下方法为认证流程中的一步。(认证通过才会返回Token)

 1 public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
 2 {
 3     var username= context.UserName;
 4     var password=context.Password;
 5     if(用户名与密码不合法)
 6     {
 7     context.setError(“用户名或密码错误!”);//认证不通过
 8     }
 9     else
10     {
11     var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
12     oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
13     //可以加入用户信息及其他必要信息到Token中,以便在api服务中使用(使用中HttpContext.Current.User.Identity即为oAuthIdentity对象,WebApi的Controller中可直接使用User.Identity)。
14     oAuthIdentity.AddClaim(new Claim("UserID", user.UserID.ToString()));
15     var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties());
16       context.Validated(ticket);//认证通过
17     }
18     return base.GrantResourceOwnerCredentials(context);
19 }    

认证代码

3、 已经获取了Token,如何使用?

  网上的大部分示例都是使用HttpClient调用的方式,而前后端的完全分离作为一种发展趋势,我们需要Jquery的调用方式。

 1 $.ajax({
 2             type: “method”,//get,post,put,delete
 3             url:api_address + “api/Test”,//如果调用webapi中的TestController
 4             data: {data},
 5             dataType: "json",
 6             headers: {
 7                 "Authorization": "Bearer " + “token” //把登录获取的Token加入到http请求头中
 8             },
 9             success: function (result) {
10                 callback(result);
11             },
12             error: function (XMLHttpRequest, textStatus, errorThrown) {
13                 //。。。。。。
14             }
15 });

调用Api

4、Api的访问权限该如何做?

  认证中我们把用户登录成功作为认证通过的标志,但不同角色的用户具有不同的访问权限(个人认为认证中应使用最小权限验证,如示例中的登录成功),如何控制有些Controller不能被低权限用户访问。

1 [Authorize]
2 public class TestController: ApiController
3 {
4     // GET api/<controller>
5     public HttpResponseMessage Get(int appid)
6     {
7         return null;
8     }
9 }

一个典型的ApiController

  [Authorize]表示访问该Controller的请求必须经过认证(请求头中具有Token信息),这里我们可以自定义一个特性去验证用户权限,并替换特性AuthorizeAttribute。(这里仅提供思路,具体做法请自己摸索,不保证以下代码的正确性)

 1 public class CustomeAuthorizeAttribute:System.Web.Http.AuthorizeAttribute
 2 {
 3         protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext)
 4     {
 5         if(base.IsAuthorized(actionContext))
 6         {
 7             //这里对用户的权限进行验证,actionContext可以获得请求的是哪一个Controller
 8             var user = HttpContext.Current.User.Identity;//Token中带有的用户信息
 9              if (可以访问)
10             {
11                  return true;
12             }
13              return false;
14            }
15            return false;
16         }
17 }
18                 

示例自定义特性(拦截器)

时间: 2024-10-13 08:24:33

OAuth在WebApi中的使用,前后台分离的调用方式的相关文章

Hybrid App开发模式中, IOS/Android 和 JavaScript相互调用方式

IOS:Objective-C 和 JavaScript 的相互调用 iOS7以前,iOS SDK 并没有原生提供 js 调用 native 代码的 API.但是 UIWebView 的一个 delegate 方法使我们可以做到让 js 需要调用时,通知 native.在 native 执行完相应调用后,可以用stringByEvaluatingJavaScriptFromString 方法,将执行结果返回给 js.这样,就实现了 js 与 native 代码的相互调用.具体让 js 通知 na

Python中包(package)的调用方式

 一.什么是Python Package 如何区分你看到的目录是一个Python Package包呢?其实很简单,你只要看这个名录下是否有“__init__.py”这个文件就好了,如果有那么就是Python Package包,如果没有,就说嘛你看到的就是个普通的目录,如下图,你就可以看出来"calcuate"和"Log"就是一个Python Package包,而"yinzhengjie"就是一个目录,而判断的依据就是是否包含_init__.py文

vue+webpack项目中使用dev-server搭建虚拟服务器,请求json文件数据,实现前后台分离开发

在项目开发中,前后台分离,做了假数据,项目使用vue2.0重构,后台也推到重来了,为了不耽误开发进程,我做了虚拟的数据请求,使用vue-cli脚手架搭建的项目文件中dev-server搭建虚拟api请求,访问自己mock的假数据虚拟请求后台的模式,具体做法如下 在build/dev-server.js文件中 在var app = express()这个实例的下面添加如下代码 // 本地json-server服务器搭建代码 // 引入数据库文件 var appData = require('../

使用OAuth打造webapi认证服务供自己的客户端使用

一.什么是OAuth OAuth是一个关于授权(Authorization)的开放网络标准,目前的版本是2.0版.注意是Authorization(授权),而不是Authentication(认证).用来做Authentication(认证)的标准叫做openid connect,我们将在以后的文章中进行介绍. 二.名词定义 理解OAuth中的专业术语能够帮助你理解其流程模式,OAuth中常用的名词术语有4个,为了便于理解这些术语,我们先假设一个很常见的授权场景: 你访问了一个日志网站(thir

Yii2的相关学习记录,前后台分离及migrate使用(七)

最近一直忙其它的(其实是懒!),将<深入理解Yii2>看了一遍,一些当初没明白的稍微明了了点,然后又看yii2的图片上传等处理.富文本.restful什么的,但由于没进行到这里,只看也不管用啊,所以还是按照步骤一步步来,先说说前后台分离.(其实普通的内容管理站点用不着下面所说的彻底分离什么的,看看也无妨) 个人感觉前后台的情况有这么几种,首先是前后台是否是用一个验证体系,其次是前后台是否共用一个数据表.一般来说下面三种比较常用吧: A.共用一个验证体系和一个数据表. B.两个验证体系和共用一个

使用OAuth打造webapi认证服务供自己的客户端使用(转)

转自:http://www.cnblogs.com/richieyang/p/4918819.html#!comments 一.什么是OAuth OAuth是一个关于授权(Authorization)的开放网络标准,目前的版本是2.0版.注意是Authorization(授权),而不是Authentication(认证).用来做Authentication(认证)的标准叫做openid connect,我们将在以后的文章中进行介绍. 二.名词定义 理解OAuth中的专业术语能够帮助你理解其流程模

使用OAuth打造webapi认证服务供自己的客户端使用(二)

在上一篇”使用OAuth打造webapi认证服务供自己的客户端使用“的文章中我们实现了一个采用了OAuth流程3-密码模式(resource owner password credentials)的WebApi服务端.今天我们来实现一个js+html版本的客户端. 一.angular客户端 angular版本的客户端代码来自于http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-

Yii2前后台分离如何实现?

本文和大家分享的主要是php中的Yii2框架前后台分离相关知识,一起来看看吧,希望对大家有所帮助. Yii2前后台都需要注册的时候会产生前后台登录一个另一个同步登录和退出,这是因为登录和退出之前的sitecontroller里面公用了common/model下面的LoginForm.php和user.php需要分开写: 1.将common/models/User.php在当前目录下copy一份,命名为Admin.php,修改类的名称为Admin 2.将common/models/LoginFor

为什么要进行前后台分离

从事前端开发工作也有一定的时间了,在这段时间里,由一个基本的前端开发开始,做到前端经理:基本上算是走过了所有前端开发都走过的路,今天主要分享下我这一路走来,对前端的理解. 我开始接触前端的时候,其实称不上是所谓的开发,更多的是现在多数人对前端的理解-美工,当时负责的工作就是将PSD转化为HTML页面,并做些基本的交互.所以,我们组一致都挂在设计组下面,因为大家对其理解,其实是偏设计的东西,和所谓的开发根本挂不上钩.结果导致的就是一系列的连锁问题--前端不被看重,前端的工资水平就很难提升,前端转岗