基于令牌的认证

我们知道WEB网站的身份验证一般通过session或者cookie完成的,登录成功后客户端发送的任何请求都带上cookie,服务端根据客户端发送来的cookie来识别用户。

WEB API使用这样的方法不是很适合,于是就有了基于令牌的认证,使用令牌认证有几个好处:可扩展性、松散耦合、移动终端调用比较简单等等,别人都用上了,你还有理由不用吗?

下面我们花个20分钟的时间来实现一个简单的WEB API token认证:

Step 1: 新建一个空的WEB API项目,项目名称就设置为WebApi

Step 2: 在Models目录下新建一个 Product 类 :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;namespace WebApi.Models
{public class Product{public int Id { get; set; }public string Name { get; set; }public string Category { get; set; }public decimal Price { get; set; }}
}

Step 3:在Controllers目录下新建一个 ProductsController 类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;using WebApi.Models;namespace WebApi.Controllers
{[RoutePrefix("api/Products")]public class ProductsController : ApiController{Product[] products = new Product[]  {  new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },  new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },  new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }  };public IEnumerable<Product> GetAllProducts(){return products;}public Product GetProductById(int id){var product = products.FirstOrDefault((p) => p.Id == id);if (product == null){throw new HttpResponseException(HttpStatusCode.NotFound);}return product;}public IEnumerable<Product> GetProductsByCategory(string category){return products.Where(p => string.Equals(p.Category, category,StringComparison.OrdinalIgnoreCase));}}
}

F5运行后就可以使用这个简单的WebApi了,测试api可以使用Postman工具:

获取所有数据  http://localhost:1234/api/products

获取内码为1的数据  http://localhost:1234/api/products/1

查询category=的数据  http://localhost:1234/api/products?category=Groceries

可以看到这个产品的API是公开访问的,没有任何验证,这样不是很安全,下一步我将加上token验证。

Step 4:安装所需的NuGet包:

打开NuGet包管理器控制台,然后输入如下指令:

Install-Package Microsoft.AspNet.WebApi.Owin -Version 5.1.2
Install-Package Microsoft.Owin.Host.SystemWeb -Version 2.1.0
Install-Package Microsoft.AspNet.Identity.Owin -Version 2.0.1Install-Package Microsoft.Owin.Cors -Version 2.1.0Install-Package EntityFramework -Version 6.0.0 

Step 5:在项目根目录下添加Owin“Startup”类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;using Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.OAuth;[assembly: OwinStartup(typeof(WebApi.Startup))]
namespace WebApi
{public class Startup{public void Configuration(IAppBuilder app){HttpConfiguration config = new HttpConfiguration();ConfigureOAuth(app);WebApiConfig.Register(config);app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);app.UseWebApi(config);}public void ConfigureOAuth(IAppBuilder app){OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions(){AllowInsecureHttp = true,TokenEndpointPath = new PathString("/token"),AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),Provider = new SimpleAuthorizationServerProvider()};app.UseOAuthAuthorizationServer(OAuthServerOptions);app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());}}
}

Step 6:删除Global.asax 

我们已经设置了Setup类,就不需要Global了,删掉干净;

Step 7:在项目根目录下添加验证类 SimpleAuthorizationServerProvider,为了简单用户的验证部分我们省略掉;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;using System.Threading;
using System.Threading.Tasks;
using Microsoft.Owin;
using Microsoft.Owin.Security.OAuth;
using System.Security.Claims;namespace WebApi
{public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider{public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context){context.Validated();}public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context){context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });/** 对用户名、密码进行数据校验,这里我们省略using (AuthRepository _repo = new AuthRepository()){IdentityUser user = await _repo.FindUser(context.UserName, context.Password);if (user == null){context.SetError("invalid_grant", "The user name or password is incorrect.");return;}}*/var identity = new ClaimsIdentity(context.Options.AuthenticationType);identity.AddClaim(new Claim("sub", context.UserName));identity.AddClaim(new Claim("role", "user"));context.Validated(identity);}}
}

Step 7:让CORS起作用

在ASP.NET Web API中启用OAuth的Access Token验证非常简单,只需在相应的Controller或Action加上[Authorize]标记

修改ProductsController类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;using WebApi.Models;namespace WebApi.Controllers
{public class ProductsController : ApiController{Product[] products = new Product[]  {  new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },  new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },  new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }  };[Authorize][Route("")]public IEnumerable<Product> GetAllProducts(){return products;}[Authorize]public Product GetProductById(int id){var product = products.FirstOrDefault((p) => p.Id == id);if (product == null){throw new HttpResponseException(HttpStatusCode.NotFound);}return product;}[AllowAnonymous]public IEnumerable<Product> GetProductsByCategory(string category){return products.Where(p => string.Equals(p.Category, category,StringComparison.OrdinalIgnoreCase));}}
}

现在我们再次直接GET http://localhost:23477/api/products/ 会返回401错误,请求被拒绝

获取token, POST   http://localhost:23477/token

参数BODY x-www-form-urlencoded 格式:

grant_type=password

username=admin

password=123456

返回200状态,内容为:

{"access_token": "eLjAu3Alm2YWjJKXmX_fLY07P6vbIzxasFECkDap3KIE0Ydp7IGhTgrzWLtPdgrK46rfAB-OmJSG5C8Bh-PkfG3XrGS0uDea2KBXyoWSR11evTGJiVIyXny3Ih2DkH04qH2T_Ar4kIjcAngPtUnsEVex26tV4QHIrjCq5SlkOdfdAa9Pnl98QVwYH47yO-zlc55bwMgpR2J4fQLyNzWVHNZpH3DbOcHQ3Yenemr6XhM","token_type": "bearer","expires_in": 86399
}

只要在http请求头中加上Authorization:bearer Token就可以成功访问API就成功了:

GET   http://localhost:23477/api/products/

Authorization : bearer eLjAu3Alm2YWjJKXmX_fLY07P6vbIzxasFECkDap3KIE0Ydp7IGhTgrzWLtPdgrK46rfAB-OmJSG5C8Bh-PkfG3XrGS0uDea2KBXyoWSR11evTGJiVIyXny3Ih2DkH04qH2T_Ar4kIjcAngPtUnsEVex26tV4QHIrjCq5SlkOdfdAa9Pnl98QVwYH47yO-zlc55bwMgpR2J4fQLyNzWVHNZpH3DbOcHQ3Yenemr6XhM

这样我们就完成了简单的WEB API的token验证~

不过这个程序有个问题,如果GetProductById也加上验证那么根据ID获取product的接口 http://localhost:23477/api/products/1 会报错

需要修改成 http://localhost:23477/api/products?id=1

不知道是哪里出的问题

本文代码: http://pan.baidu.com/s/1jGxZVKU

PostMan工具请移步这里看介绍 http://www.cnblogs.com/wade-xu/p/4228954.html

转载于:https://www.cnblogs.com/relax/p/4956441.html

ASP.NET Web API 2基于令牌的身份验证相关推荐

  1. 购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(3)--Idetity,OWIN前后端验证

    原文:购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(3)--Idetity,OWIN前后端验证 chsakell分享了前端使用AngularJS,后端使用ASP. ...

  2. flask身份验证_Flask基于令牌的身份验证

    flask身份验证 This tutorial takes a test-first approach to implementing token-based authentication in a ...

  3. 数字化时代,基于令牌的身份验证是如何工作?

    一.背景 数字化转型给用户带来了安全问题,以保护他们的身份免受假冒.据美国诺顿称,平均每年有 80 万个帐户被黑客入侵.需要用于身份验证的高安全性系统和网络安全法规. 传统方法依赖于使用用户名和密码的 ...

  4. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程

    最近发现web api很火,园内也有各种大神已经在研究,本人在asp.net官网上看到一个系列教程,原文地址:http://bitoftech.net/2013/11/25/detailed-tuto ...

  5. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【十】——使用CacheCow和ETag缓存资源...

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 本文将使用一个开源框架CacheCow来实现针对Http请求资源缓存,本文主要介绍服务器端的 ...

  6. java 令牌_WEB API - 使用Bearer令牌进行身份验证

    我创建了一个允许外部认证/注册的MVC应用程序 . 它创建了所有必要的组件(Owin,EF,Regiter,Login,Logout),我能够在应用程序中执行所有基本活动 . 现在,我想将Web应用程 ...

  7. ASP.NET Web API 安全筛选器

    原文:https://msdn.microsoft.com/zh-cn/magazine/dn781361.aspx 身份验证和授权是应用程序安全的基础.身份验证通过验证提供的凭据来确定用户身份,而授 ...

  8. 【转】在ASP.NET Web API 2中使用Owin基于Token令牌的身份验证

    基于令牌的身份验证 基于令牌的身份验证主要区别于以前常用的基于cookie的身份验证,基于cookie的身份验证在B/S架构中使用比较多,但是在Web Api中因其特殊性,基于cookie的身份验证已 ...

  9. 我对 ASP.NET Web API 的随想

    其实自己实现一个类似与 ASP.NET Web API 的轻量级 Web 服务(PS:不是说 Web Service 技术)也不是很难的事,就算不用 ASP.NET MVC,用 ASP.ASP.NET ...

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

    在前一篇博文中,我们使用OAuth的Client Credential Grant授权方式,在服务端通过CNBlogsAuthorizationServerProvider(Authorization ...

最新文章

  1. 基于WF4的新平台-表单格式
  2. 浅谈Nginx服务器的内部核心架构设计
  3. 其他类型的链表和线性表的总结(一级)
  4. python __call__一般用在哪些地方_Python __call__内置函数的作用和用法
  5. 公司新来的小可爱,竟然把内存搞崩了!
  6. llinux c 语言延时,linux下写个C语言程序,要求有0.5微秒以下的延时,要怎样写
  7. 2020后半年iPhone取消附赠耳机?分析师上调AirPods出货量预估
  8. csp2020 j2民间数据下载_摊开母婴市场数据集看一看
  9. python类的数组属性_Python学习之数组类型一:
  10. rgmanager 介绍
  11. slice python_Python slice()
  12. (转)ASP.NET 3.5 企业级开发
  13. 中国为什么不能成为国际数据中心枢纽
  14. 计算机运算法则图鉴,AP微积分BC TI-Nspire计算器使用指南 正确使用计算器5分到手轻而易举...
  15. linux 安装mysql(rpm文件安装)
  16. 【python10个小实验】1. 画一个简单的三角形
  17. 天清江月白,心静海鸥知
  18. Shannon 香农编码 信息论实验 c++
  19. 计算机专业基础需要注意的点
  20. 【RVM预测】基于粒子群算法优化相关向量机RVM实现数据回归预测附matlab代码

热门文章

  1. 关于redis内存分析,内存优化
  2. 实战java虚拟机配套代码
  3. oracle中树形数据,ORACLE树形数据解决方法
  4. java数字小游戏_java数字小游戏
  5. 2.4配置自定义拦截器
  6. 使用Ant定义生成文件
  7. 【渝粤教育】国家开放大学2018年春季 8647-21T工程经济与管理 参考试题
  8. 【渝粤教育】电大中专药物分析技术基础 (2)_1作业 题库
  9. 【渝粤教育】电大中专消费者行为学 (2)作业 题库
  10. C++ Primer Plus 第二章编程练习