今天给大家分享在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. jquery-qrcode生成二维码

    一.jquery-qrcode jquery-qrcode是一个为浏览器生成二维码的jquery插件.我们很容易将它集成到我们的应用.该插件也可以独立使用,也比较小.它是直接在客户端生成二维码生成.所 ...

  2. Linux系统之压缩、解压缩,vi编辑器,系统初始化服务和系统监控

    一.正文处理,压缩与解压缩 1.内容重定向>与>> >:覆盖,将>号左边的结果覆盖到>号右边的文件中,如果文件不存在,则先创建一个新的空文件并覆盖 >> ...

  3. Android中Spanner获取选中内容和选中位置,根据位置选择对象

    作为一名菜鸟,关于spanner获取选中的内容文字代码,网上后很多 但是根据给出的位置来自动选择对象,这个代码一直没找到 后来找人问了问,才知道就一句话的事,特意在这里记录下 array.xml  X ...

  4. STL的erase()陷阱-迭代器失效总结

    下面材料整理自Internet&著作. STL中的容器按存储方式分为两类,一类是按以数组形式存储的容器(如:vector .deque):另一类是以不连续的节点形式存储的容器(如:list.s ...

  5. 【jQuery Demo】jQuery打造动态下滑菜单

    作者:漫凯维奇      来源:[教程]jQuery打造动态下滑菜单 Tip:这只是一个转载,源代码可以在上面的来源博文中下载 此教程将分步讲解如何使用JQuery和CSS打造一个炫酷动感菜单.效果如 ...

  6. [转载]ExtJs4 笔记(3) Ext.Ajax 对ajax的支持

    作者:李盼(Lipan)出处:[Lipan] (http://www.cnblogs.com/lipan/)     本篇主要介绍一下ExtJs常用的几个对JS语法的扩展支持,包括Ajax封装,函数事 ...

  7. HDU 2082 找单词 --生成函数

    跟上题是一个思路:http://www.cnblogs.com/whatbeg/p/3728545.html 只不过是上一题的扩展. 代码: #include <iostream> #in ...

  8. html中的src与href的区别

    写代码的时候就经常把这两个属性弄混淆,到底是href还是src,href标识超文本引用,用在link和a等元素上,href是引用和页面关联,是在当前元素和引用资源之间建立联系,src表示引用资源,表示 ...

  9. 10SpringMvc_springmvc快速入门小案例(注解版本)

    第一步:新建案例工程:

  10. 由源码密码文件转转化成keystore

      1.android 源码目录build\target\product\security 取platform.pk8 platform.x509.pem放到一个目录下 E:\sign\convert ...