今天给大家分享在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. 读书笔记——Windows环境下32位汇编语言程序设计(13)关于EXCEPTION_DEBUG_INFO结构体

    在动手自己尝试编写书上第13章的例子Patch3时,遇到了一个结构体EXCEPTION_DEBUG_INFO. 这个结构体在MASM的windows.inc中的定义和MSDN中的定义不一样. (我使用 ...

  2. 基于python的flask的应用实例注意事项

    1.所有的html文件均保存在templates文件夹中 2.运行网页时python manage.py runserver

  3. Syslog

    一.简介 syslog是一种工业标准的协议,可用来记录设备的日志.在UNIX系统,路由器.交换机等网络设备中,系统日志(System Log)记录系统中任何时间发生的大小事件.管理者可以通过查看系统记 ...

  4. Swift 学习笔记 enum 枚举类型

    异端,异端啊,我感觉这是map吧? enum ATMStatus { case Success(Int) case Error(String) } func withdraw(amount: Int) ...

  5. GitHub中wiki的Markdown编辑方法!!

    Hello MarkDown!正常的文本 一级大标题用一个#号 一级中等标题用两个#号 一级小标题用三个#号(一次类推,一共有6级标题) 下面是无序列表 无序标题1-只需要在标题前面加上*号就可以了或 ...

  6. 最小的k个数

    // 最小的k个数.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> #include & ...

  7. Geoserver发布Oracle数据

    在Geoserver安装包中,默认是不能发布Oracle数据库里的数据的,只能发布postgis.shp等数据,详细如截图: 如果想发布oracle数据,得安装相应版本的关于oracle数据源的插件, ...

  8. 对"构建之法“的理解和困惑

    对"构建之法"的理解和困惑        本人"学沫沫"一个,对于之前的编程学习虽不大"感冒",但秉着对自己负责的态度进行了基础学习.   ...

  9. Git版本控制工具(一)----git的安装及创建版本库

    ​[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...

  10. C/C++ 常用工具集

    1. c++filt  //注意:就是这个名字 "c++file". 能把c++的函数签名转换成代码形参格式: 如:# c++filt _ZNSt4priv17_Rb_tree_i ...