Web API 基于ASP.NET Identity的Basic Authentication
今天给大家分享在Web API下,如何利用ASP.NET Identity实现基本认证(Basic Authentication),在博客园子搜索了一圈Web API的基本认证,基本都是做的Forms认证,很少有Claims认证(声明式认证),而我们在用ASP.NET Identity实现登录,认证,授权的时候采用的是Claims认证。
在Web API2.0中认证接口为IAuthenticationFilter,我们只需实现该接口就行。创建BasicAuthenticationAttribute抽象基类,实现IAuthenticationFilter接口:
public abstract class BasicAuthenticationAttribute : Attribute, IAuthenticationFilter
{
protected abstract Task<IPrincipal> AuthenticateAsync(string userName, string password, HttpAuthenticationContext context,
CancellationToken cancellationToken);
public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
context.Principal = null;
AuthenticationHeaderValue authenticationHeader = context.Request.Headers.Authorization;
if (authenticationHeader != null && authenticationHeader.Scheme == "Basic")
{
if (!string.IsNullOrEmpty(authenticationHeader.Parameter))
{
Tuple<string, string> data = GetUserNameAndPassword(authenticationHeader.Parameter);
context.Principal = await AuthenticateAsync(data.Item1, data.Item2,context, cancellationToken);
}
} if (context.Principal == null)
{
context.ErrorResult = new UnauthorizedResult(new[] {new AuthenticationHeaderValue("Basic")},
context.Request);
}
}
public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
{
return Task.FromResult();
}
public bool AllowMultiple
{
get { return false; }
}
private Tuple<string, string> GetUserNameAndPassword(string authenticationParameter)
{
if (!string.IsNullOrEmpty(authenticationParameter))
{
var data = Encoding.ASCII.GetString(Convert.FromBase64String(authenticationParameter)).Split(':');
return new Tuple<string, string>(data[], data[]);
}
return null;
}
}
其中Task<IPrincipal> AuthenticateAsync(string userName, string password, HttpAuthenticationContext context, CancellationToken cancellationToken)方法为抽象方法,用户可以重载实现自己的认证方式,Forms认证,Windows认证,Claims认证等等都可以。
AuthenticationHeaderValue authenticationHeader= context.Request.Headers.Authorization用于获取HTTP请求头部的认证信息。
authenticationHeader.Scheme == "Basic"用于指定认证模式为基本认证。
authenticationHeader.Parameter用户获取用户加密过后的用户名和密码。
如果认证不为空,且是Basic认证,头部参数不为空,则调用认证的具体代码,如果认证不通过,则调用HTTP认证上下文的ErroResult属性:
context.ErrorResult = new UnauthorizedResult(new[] {new AuthenticationHeaderValue("Basic")},context.Request);设置了该属性,浏览器则自动弹出用户登录的窗口。要想浏览器自动弹出登录窗口,必须在WebApiConfig配置类中指定令牌身份验证,即调用如下代码:config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));否则无法弹出登录窗体。
Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)方法在认证通过成功和失败后都会调用此方法,你可以在这里实现自己想要的逻辑,比如设置context.ErrorResult属性,在这里就不做处理了,因为AuthenticateAsync方法已经做了处理了。
GetUserNameAndPassword方法用于处理加密过后的用户名和密码。
接下来就是实现自己的认证逻辑了,这里采用Asp.net Identity的Claims认证。
public class IdentityBasicAuthenticationAttribute : BasicAuthenticationAttribute
{
protected override async Task<IPrincipal> AuthenticateAsync(string userName, string password,
HttpAuthenticationContext context, CancellationToken cancellationToken)
{
IPrincipal principal = null;
var userManager = context.Request.GetOwinContext().GetUserManager<AppUserManager>();
var user = await userManager.FindAsync(userName, password);
if (user != null)
{
ClaimsIdentity identity =
await userManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(identity);
principal = claimsPrincipal;
}
return principal;
}
}
var userManager = context.Request.GetOwinContext().GetUserManager<AppUserManager>()用于当前的用户管理器,用户的增删改查操作都依赖于此对象。
var user = await userManager.FindAsync(userName, password)用户根据用户名和密码找到用户。
ClaimsIdentity identity = await userManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie)创建用户,然后 通过ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(identity)创建声明,并且返回认证类型。
至于如何创建UserManager,如何通过Entityframwork来生成Asp.net Identity用户,角色和认证相关表,这里就不多说了,园子里面多的去了。
记得在登录代码中把用户名和密码加密后放到Cookie中,登陆后,在访问某个需要认证的Action时候记得在HTTP请求头部中写入Cookie信息,这样认证的Filter才能取到用户信息,登录创建Cookie代码片段如下:
CookieHeaderValue cookie = new CookieHeaderValue("userToken", authorization)
{
Path = "/",
Domain = Request.RequestUri.Host,
Expires = DateTimeOffset.Now.AddDays(7)
};
responseMessage.Headers.AddCookies(new[] {cookie});
客户短AJax调用需要验证的Action方法如下:
function ajaxOp(url, type, data) {
$.ajax({
url: url,
type: type,
data: data,
beforeSend: function(xhr) {
xhr.setRequestHeader('Authorization', 'Basic ' + $.cookie("userToken"));
}
});
}
其中 beforeSend: function(xhr) {xhr.setRequestHeader('Authorization', 'Basic ' + $.cookie("userToken"))属性设置用于获取Cookie信息放到请求头部。
需要调用的Action记得加上 [IdentityBasicAuthentication]特性。
好了,就到这里吧。
Web API 基于ASP.NET Identity的Basic Authentication的更多相关文章
- ASP.NET Web API基于OData的增删改查,以及处理实体间关系
本篇体验实现ASP.NET Web API基于OData的增删改查,以及处理实体间的关系. 首先是比较典型的一对多关系,Supplier和Product. public class Product { ...
- [转]ASP.NET Web API基于OData的增删改查,以及处理实体间关系
本文转自:http://www.cnblogs.com/darrenji/p/4926334.html 本篇体验实现ASP.NET Web API基于OData的增删改查,以及处理实体间的关系. 首先 ...
- 【翻译】使用Knockout, Web API 和 ASP.Net Web Forms 进行简单数据绑定
原文地址:http://www.dotnetjalps.com/2013/05/Simple-data-binding-with-Knockout-Web-API-and-ASP-Net-Web-Fo ...
- Knockout, Web API 和 ASP.Net Web Forms 进行简单数据绑定
使用Knockout, Web API 和 ASP.Net Web Forms 进行简单数据绑定 原文地址:http://www.dotnetjalps.com/2013/05/Simple-da ...
- 002.Create a web API with ASP.NET Core MVC and Visual Studio for Windows -- 【在windows上用vs与asp.net core mvc 创建一个 web api 程序】
Create a web API with ASP.NET Core MVC and Visual Studio for Windows 在windows上用vs与asp.net core mvc 创 ...
- Asp.Net Web API VS Asp.Net MVC
http://www.dotnet-tricks.com/Tutorial/webapi/Y95G050413-Difference-between-ASP.NET-MVC-and-ASP.NET-W ...
- ASP.NET Web API和ASP.NET Web MVC中使用Ninject
ASP.NET Web API和ASP.NET Web MVC中使用Ninject 先附上源码下载地址 一.准备工作 1.新建一个名为MvcDemo的空解决方案 2.新建一个名为MvcDemo.Web ...
- Using MongoDB with Web API and ASP.NET Core
MongoDB is a NoSQL document-oriented database that allows you to define JSON based documents which a ...
- Web API 2 入门——使用Web API与ASP.NET Web窗体(谷歌翻译)
在这篇文章中 概观 创建Web窗体项目 创建模型和控制器 添加路由信息 添加客户端AJAX 作者:Mike Wasson 虽然ASP.NET Web API与ASP.NET MVC打包在一起,但很容易 ...
随机推荐
- 软件测试Lab2
1.本次上机实验任务:使用webDriver完后自动化测试 2.本次上机实验目的:掌握webDriver的用法和配置. 3.本次上机实验内容: 3.1Selenium的安装: 首先我们上Seleniu ...
- CentOS下SSH无密码登录的配置
1.确认本机sshd的配置文件(需要root权限) $ gedit /etc/ssh/sshd_config 找到以下内容,并去掉注释符"#" RSAAuthentication ...
- esxi安装全过程及基本配置
esxi6.0下载地址 链接: http://pan.baidu.com/s/1jIfg2yU 密码: qacv 支持检测可以参考:http://www.linuxidc.com/Linux/2012 ...
- hdu 3987 Harry Potter and the Forbidden Forest 求割边最少的最小割
view code//hdu 3987 #include <iostream> #include <cstdio> #include <algorithm> #in ...
- 【ubuntu】中文输入法安装二三事
本来很愉快地刷着JS程序,很有感慨啊,想写篇博客记一下学习笔记,结果忘记了博客账号,后来通过邮箱找回了之后想要开始写..发现ubuntu的中文输入法不能用啊(其实不是不能用,就是小白没搞清楚状况,双系 ...
- Centos 6.5(64bit)上安装Vertica single node
在Win8上使用虚拟机Virtualbox安装Centos6.5,想在上面安装vertica. 以下记录了我在安装的过程中遇到的问题与一些解决方案. 1.安装Centos的时候遇到了一个恼人的问题,即 ...
- 自动化测试selenium+java 第一章
selenium元素的定位以及操作 1. 元素的定位 Selenium 自动化,我们需要做的最基本的事情就是在页面找到元素并通过脚本程 序去操作这个元素,实现模拟人工操作.我们有多种定位元素的方式可以 ...
- 城堡 (spfa+cheng)
[问题描述] 给定一张?个点?条边的无向连通图,每条边有边权.我们需要从?条边中选出? − 1条, 构成一棵树. 记原图中从 1 号点到每个节点的最短路径长度为? ? ,树中从 1 号点到每个节点的最 ...
- 创建自定义的Cocos2d-x场景
操作步骤 1.创建cocos2d-x工程 2.新建 Scene1.cpp Scene1.h Scene1.h代码 #ifndef __SCENE1_H__#define __SCENE1_H__ #i ...
- angularjs的ng-repeat指令下的scope作用域
ng-repeat指令在迭代的时候,每次迭代都会创建一个新的scope,比如下面的代码: <div ng-repeat="list in lists" ng-controll ...