今天给大家分享在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的更多相关文章

  1. ASP.NET Web API基于OData的增删改查,以及处理实体间关系

    本篇体验实现ASP.NET Web API基于OData的增删改查,以及处理实体间的关系. 首先是比较典型的一对多关系,Supplier和Product. public class Product { ...

  2. [转]ASP.NET Web API基于OData的增删改查,以及处理实体间关系

    本文转自:http://www.cnblogs.com/darrenji/p/4926334.html 本篇体验实现ASP.NET Web API基于OData的增删改查,以及处理实体间的关系. 首先 ...

  3. 【翻译】使用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 ...

  4. Knockout, Web API 和 ASP.Net Web Forms 进行简单数据绑定

    使用Knockout, Web API 和 ASP.Net Web Forms 进行简单数据绑定   原文地址:http://www.dotnetjalps.com/2013/05/Simple-da ...

  5. 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 创 ...

  6. 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 ...

  7. ASP.NET Web API和ASP.NET Web MVC中使用Ninject

    ASP.NET Web API和ASP.NET Web MVC中使用Ninject 先附上源码下载地址 一.准备工作 1.新建一个名为MvcDemo的空解决方案 2.新建一个名为MvcDemo.Web ...

  8. 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 ...

  9. Web API 2 入门——使用Web API与ASP.NET Web窗体(谷歌翻译)

    在这篇文章中 概观 创建Web窗体项目 创建模型和控制器 添加路由信息 添加客户端AJAX 作者:Mike Wasson 虽然ASP.NET Web API与ASP.NET MVC打包在一起,但很容易 ...

随机推荐

  1. Greenplum 4.3 For Centos 6.5 安装指南

    1.greenplum数据库安装前期准备工作 1.1 安装Linux l  内存:最小1GB,推荐2GB或以上. l  交换空间: 内存大小是1-2GB时,交换空间是内存的1.5倍,内存大小2-16G ...

  2. PHP正则中的捕获组与非捕获组

    今天遇到一个正则匹配的问题,忽然翻到有捕获组的概念,手册上也是一略而过,百度时无意翻到C#和Java中有对正则捕获组的特殊用法,搜索关键词有PHP时竟然没有相关内容,自己试了一下,发现在PHP中也是可 ...

  3. matlab2015b调用摄像头

    参考链接:http://blog.csdn.net/lyqmath/article/details/7307429 本人电脑是宏碁T5000 调用代码: % By lyqmathclc; clear ...

  4. Mongodb 字段类型转换

    db.diningmembers.find({modifedDate:{$type:9}}).forEach(function(x){x.tel = String(x.tel);db.diningme ...

  5. 迅为iTOP-4418开发板兼容八核6818开发板介绍

    核心板介绍 三星四核S5P4418与八核6818完美兼容 1GB内存/2GB内存可选 电源管理:AXP228,支持动态调频,超低功耗 核心板引出脚最全:四组连接器共320个PIN脚 核心板连接器高度仅 ...

  6. 边工作边刷题:70天一遍leetcode: day 84-2

    要点:这题是combination的应用,从左向右想比从右向左容易. 因为有结果从小到大的要求,暗示用combintion而不是permutation 其实就是从小到大验证因子,每个因子和其对称因子立 ...

  7. redis 一二事 - 搭建集群缓存服务器

    在如今并发的环境下,对大数据量的查询采用缓存是最好不过的了,本文使用redis搭建集群 (个人喜欢redis,对memcache不感冒) redis是3.0后增加的集群功能,非常强大 集群中应该至少有 ...

  8. uGUI练习(一) Anchor

    一.练习步骤 如果用过NGUI的Anchor,我们知道在2.x的版本有UIAnchor组件(下图左),3.x版本中,每个UIWidget有自带的Anchors(下图右) 而uGUI的Anchor用起来 ...

  9. Volley(五)—— 自定义Request

    详细解读Volley(四)—— 自定义Request Volley中提供了几个Request,如果我们有特殊的需求,完全可以自定义Request的,自定义Request自然要继承Request,那么本 ...

  10. (copy)C#时间日期操作

    copy to:http://www.cnblogs.com/loveme123/archive/2012/06/27/2565547.html  一.C# 日期格式 DateTime dt = Da ...