ASP.NET Web API 2基于令牌的身份验证
基于令牌的认证
我们知道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基于令牌的身份验证相关推荐
- 购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(3)--Idetity,OWIN前后端验证
原文:购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(3)--Idetity,OWIN前后端验证 chsakell分享了前端使用AngularJS,后端使用ASP. ...
- flask身份验证_Flask基于令牌的身份验证
flask身份验证 This tutorial takes a test-first approach to implementing token-based authentication in a ...
- 数字化时代,基于令牌的身份验证是如何工作?
一.背景 数字化转型给用户带来了安全问题,以保护他们的身份免受假冒.据美国诺顿称,平均每年有 80 万个帐户被黑客入侵.需要用于身份验证的高安全性系统和网络安全法规. 传统方法依赖于使用用户名和密码的 ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程
最近发现web api很火,园内也有各种大神已经在研究,本人在asp.net官网上看到一个系列教程,原文地址:http://bitoftech.net/2013/11/25/detailed-tuto ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【十】——使用CacheCow和ETag缓存资源...
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 本文将使用一个开源框架CacheCow来实现针对Http请求资源缓存,本文主要介绍服务器端的 ...
- java 令牌_WEB API - 使用Bearer令牌进行身份验证
我创建了一个允许外部认证/注册的MVC应用程序 . 它创建了所有必要的组件(Owin,EF,Regiter,Login,Logout),我能够在应用程序中执行所有基本活动 . 现在,我想将Web应用程 ...
- ASP.NET Web API 安全筛选器
原文:https://msdn.microsoft.com/zh-cn/magazine/dn781361.aspx 身份验证和授权是应用程序安全的基础.身份验证通过验证提供的凭据来确定用户身份,而授 ...
- 【转】在ASP.NET Web API 2中使用Owin基于Token令牌的身份验证
基于令牌的身份验证 基于令牌的身份验证主要区别于以前常用的基于cookie的身份验证,基于cookie的身份验证在B/S架构中使用比较多,但是在Web Api中因其特殊性,基于cookie的身份验证已 ...
- 我对 ASP.NET Web API 的随想
其实自己实现一个类似与 ASP.NET Web API 的轻量级 Web 服务(PS:不是说 Web Service 技术)也不是很难的事,就算不用 ASP.NET MVC,用 ASP.ASP.NET ...
- ASP.NET Web API与Owin OAuth:使用Access Toke调用受保护的API(二)
在前一篇博文中,我们使用OAuth的Client Credential Grant授权方式,在服务端通过CNBlogsAuthorizationServerProvider(Authorization ...
最新文章
- 基于WF4的新平台-表单格式
- 浅谈Nginx服务器的内部核心架构设计
- 其他类型的链表和线性表的总结(一级)
- python __call__一般用在哪些地方_Python __call__内置函数的作用和用法
- 公司新来的小可爱,竟然把内存搞崩了!
- llinux c 语言延时,linux下写个C语言程序,要求有0.5微秒以下的延时,要怎样写
- 2020后半年iPhone取消附赠耳机?分析师上调AirPods出货量预估
- csp2020 j2民间数据下载_摊开母婴市场数据集看一看
- python类的数组属性_Python学习之数组类型一:
- rgmanager 介绍
- slice python_Python slice()
- (转)ASP.NET 3.5 企业级开发
- 中国为什么不能成为国际数据中心枢纽
- 计算机运算法则图鉴,AP微积分BC TI-Nspire计算器使用指南 正确使用计算器5分到手轻而易举...
- linux 安装mysql(rpm文件安装)
- 【python10个小实验】1. 画一个简单的三角形
- 天清江月白,心静海鸥知
- Shannon 香农编码 信息论实验 c++
- 计算机专业基础需要注意的点
- 【RVM预测】基于粒子群算法优化相关向量机RVM实现数据回归预测附matlab代码