最近看了一点 web api 2方面的书,对认证都是简单介绍了下,所以我在这里做个简单Demo,本文主要是FORM Authentication,顺带把基本认证也讲了。

Demo

一、FORM Authentication

1、新建asp.net 空项目->Web API,如下图所示:

2、先创建一个简单无认证示例:

(1)、Models文件夹下新建Product类,

    /// <summary>
/// 产品
/// </summary>
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
}

(2)、Controllers文件夹下新建ProductsController类,

 public class ProductsController : ApiController
{
Product[] products = new Product[]
{
new Product { Id = , Name = "Tomato Soup", Category = "Groceries", Price = },
new Product { Id = , Name = "Yo-yo", Category = "Toys", Price = 3.75M },
new Product { Id = , Name = "Hammer", Category = "Hardware", Price = 16.99M }
}; public IEnumerable<Product> GetAll()
{ return products;
} public IHttpActionResult Get(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
return NotFound();
}
return Ok(product);
} }

(3)、创建index.html页面,前端脚本如下,

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Web API2 Studt</title> </head>
<body> <div>
<h2>All Products</h2>
<ul id="products"></ul>
</div>
<div>
<h2>Search by ID</h2>
<input type="text" id="prodId" size="" />
<input type="button" value="Search" onclick="find();" /> <p id="product" />
</div>
<script src="JS/jquery-2.0.3.min.js"></script>
<script> var uri = 'api/products'; $(document).ready(function () {
// Send an AJAX request
$.getJSON(uri)
.done(function (data) {
// On success, 'data' contains a list of products.
$.each(data, function (key, item) {
// Add a list item for the product.
$('<li>', { text: formatItem(item) }).appendTo($('#products'));
});
}).fail(function (jqXHR, textStatus, err) { if (err == 'Forbidden')
{self.location = 'login.html';} });
}); function formatItem(item) {
return item.Name + ': $' + item.Price;
} function find() { var id = $('#prodId').val();
$.getJSON(uri + '/' + id)
.done(function (data) {
$('#product').text(formatItem(data));
})
.fail(function (jqXHR, textStatus, err) {
$('#product').text('Error: ' + err);
});
} </script>
</body>
</html>

(4) index.html设为起始页,启动后访问成功,

3、添加FORM Authentication认证, 

(1)、Controllers文件夹下新建FormAuth类,

using System;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using System.Web.Security; namespace WebApi2Demo.Controllers
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class FormAuth : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
try
{
if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Count > )
{
base.OnActionExecuting(actionContext);
return;
} var cookie = actionContext.Request.Headers.GetCookies();
if (cookie == null || cookie.Count < )
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
return;
} FormsAuthenticationTicket ticket = null; foreach (var perCookie in cookie[].Cookies)
{
if (perCookie.Name == FormsAuthentication.FormsCookieName)
{
ticket = FormsAuthentication.Decrypt(perCookie.Value);
break;
}
} if (ticket == null)
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
return;
} // TODO: 添加其它验证方法 base.OnActionExecuting(actionContext);
}
catch
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
}
} }
}

(2)、将FormAuth特性添加到ProductsController类上面,如下图:

(3)、编译网站后,刷新index.html页面,跳转到了login.html(需要新建)页面,

看看前端js,

如果错误提示“Forbidden”,则跳转到login.html页面,这正是FormAuth中响应的HttpStatusCode(Forbidden = 403),

用Fiddler2看看,

  (4)、添加登陆认证,

1)、 新建LogOn类,

 public class LogOn
{ public string Username { get; set; } public string Password { get; set; }
}

2)、新建登陆认证类,

  public class AccountController : ApiController
{
[HttpPost]
public HttpResponseMessage Post(LogOn model)
{ string password;
if (model.Username == "zzhi")
{
if (model.Password == "")
{
FormsAuthentication.SetAuthCookie(model.Username, false);
return Request.CreateResponse(HttpStatusCode.OK, "Success");
}
return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Invalid username or password.");
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Invalid username or password.");
}
} }

3)、login.html 脚本如下,

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>登陆</title>
<script src="JS/jquery-2.0.3.min.js"></script>
<script>
var uri = 'api/Account'; function login() { var username = $("#username").val();
var password = $("#password").val(); $.post(uri, { Username: username, Password: password })
.success(function (result) {
alert(result);
window.location.href = "index.html";
})
.fail(function (XMLHttpRequest, textStatus, err) {
alert(XMLHttpRequest.status);
alert(XMLHttpRequest.text);
alert(err);
this.reload();
}); } </script>
</head>
<body>
<label>用户名</label><input id="username" type="text" />
<br />
<label>密&nbsp;&nbsp;码</label><input id="password" type="password" />
<br />
<button onclick="login()">登陆</button>
</body>
</html>

编译网站后刷新login.html,输入用户名:zzhi,密码:12345,提示登陆成功,然后跳转到index.html页面。

TEST:关闭网页,再次启动网站,直接进入index.html页面并请求数据成功,fiddler2看看,

(5)、控制台访问API 2,代码如下:

  internal class Program
{
private static void Main(string[] args)
{
Process(); Console.Read(); } private static async void Process()
{
string token = GetSecurityToken("zzhi", "", "http://localhost:45690/api/Account", ".ASPXAUTH");
string address = "http://localhost:45690/api/products";
if (!string.IsNullOrEmpty(token))
{
HttpClientHandler handler = new HttpClientHandler {CookieContainer = new CookieContainer()};
handler.CookieContainer.Add(new Uri(address), new Cookie(".ASPXAUTH", token));
using (HttpClient httpClient = new HttpClient(handler))
{
HttpResponseMessage response = httpClient.GetAsync(address).Result;
IEnumerable<Product> Products = await response.Content.ReadAsAsync<IEnumerable<Product>>(); foreach (Product c in Products)
{
Console.WriteLine(c.Name);
}
} }
} private static string GetSecurityToken(string userName, string password, string url, string cookieName)
{ using (HttpClient httpClient = new HttpClient())
{
Dictionary<string, string> credential = new Dictionary<string, string>();
credential.Add("Username", userName);
credential.Add("Password", password);
HttpResponseMessage response = httpClient.PostAsync(url, new FormUrlEncodedContent(credential)).Result;
IEnumerable<string> cookies;
if (response.Headers.TryGetValues("Set-Cookie", out cookies))
{
string token = cookies.FirstOrDefault(value => value.StartsWith(cookieName));
if (null == token)
{
return null;
}
return token.Split(';')[].Substring(cookieName.Length + );
}
return null;
}
}
}

(6)、跨域访问

1)、在web项目中(我的web项目名字:WebApi2Demo)通过Nuget添加 web api 2 corss-Origin 引用,如下图:

2)、WebApiConfig.cs 配置如下:

 var cors = new EnableCorsAttribute("*", "*", "*");//跨域访问
config.EnableCors(cors); config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);

3)、ProductsController.cs 去掉[FormAuth]特性。

ASP.net里面的Form认证,是通过在Cookie写入登陆信息,然后浏览器发送请求后服务端再去验证Cookie是否存在,从而达到认证用户的目的。但是我们现在涉及到一个跨域的问题,而Cookie是不能跨站共享的。即使RESTful那边设置了cookie,也不会到当前请求的域下面。到了第二次请求的时候,还是得不到认证信息。

这里我做了个简单测试,如果你不注释[FormAuth]特性,跨域是请求不到数据的。

那么如何跨域认证呢,一种简单方式是基本认证。

可以通过Demo中的WebCorsTest项目进行测试。

 二、基本认证,基本认证放在Demo中了,不再赘述。

Demo

相关链接RESTful api跨域认证

 Api 2 资料:

ASP.NET Web API 2 Recipes_ A Problem-Solution Approach.pdf

ASP.NET Web API 2_ Building a REST Service from Start to Finish.pdf

Pro ASP.NET Web API HTTP Web Services in ASP.NET.pdf

inside-asp-ney-web-api-2.pdf

好了到此结束。

Asp.net Web Api 2 FORM Authentication Demo的更多相关文章

  1. 购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(3)--Idetity,OWIN前后端验证

    原文:购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(3)--Idetity,OWIN前后端验证 chsakell分享了前端使用AngularJS,后端使用ASP. ...

  2. 购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(2)--前端,以及前后端Session

    原文:购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(2)--前端,以及前后端Session chsakell分享了前端使用AngularJS,后端使用ASP.NE ...

  3. 购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(1)--后端

    原文:购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(1)--后端 chsakell分享了前端使用AngularJS,后端使用ASP.NET Web API的购物车 ...

  4. ASP.NET Web API实践系列01,以ASP.NET Web Form方式寄宿

    创建一个空的ASP.NET Web Form项目. 右键项目,添加新项,创建Web API控制器类,TestController. 删除掉TestController默认的内容,编写如下: using ...

  5. 初试ASP.NET Web API/MVC API(附Demo)

    写在前面 HTTP RESTful 创建Web API 调用Web API 运行截图及Demo下载 ASP.NET Web API是​​一个框架,可以很容易构建达成了广泛的HTTP服务客户端,包括浏览 ...

  6. [转]ASP.NET Web API(三):安全验证之使用摘要认证(digest authentication)

    本文转自:http://www.cnblogs.com/parry/p/ASPNET_MVC_Web_API_digest_authentication.html 在前一篇文章中,主要讨论了使用HTT ...

  7. ASP.NET Web API(三):安全验证之使用摘要认证(digest authentication)

    在前一篇文章中,主要讨论了使用HTTP基本认证的方法,因为HTTP基本认证的方式决定了它在安全性方面存在很大的问题,所以接下来看看另一种验证的方式:digest authentication,即摘要认 ...

  8. Authentication and Authorization in ASP.NET Web API

      You've created a web API, but now you want to control access to it. In this series of articles, we ...

  9. Implement JSON Web Tokens Authentication in ASP.NET Web API and Identity 2.1 Part 3 (by TAISEER)

    http://bitoftech.net/2015/02/16/implement-oauth-json-web-tokens-authentication-in-asp-net-web-api-an ...

随机推荐

  1. “Hello world!”贡献分分配规则

    规则1:得到总分后取14分,剩下分数进行平分.(备注:例如得了50分,取出14分,剩下36分组内进行平分) 规则2:对于会议准时参加者每人加0.5分.(备注:按通知开会时间为准,准时到者实行加分.) ...

  2. mysql 复杂查询

    1.同一个表下多次查询: sql语句: select b.* ,(select name from exh_common.medicine_type a where b.p_id = a.id) as ...

  3. asp.net .net4.0使用异步编程

    "; Action<object> ac = (object obj) => { Debug.WriteLine("睡眠开始:" + DateTime. ...

  4. UBUNTU如何安装tar.gz版的flash

    adobe flash player的官方下载页面为:https://get.adobe.com/cn/flashplayer/ 不过近期通过APT方式以及ubuntu的软件中心都安装不了flashp ...

  5. java — 排序算法

    1.冒泡排序 比较相邻元素,如果第一个比第二个大,就交换位置,每一次交换,当前 package BubbleSort; public class Test { public static void m ...

  6. 深入了解View的绘制流程

    1.  ViewRoot ViewRoot是连接WindowManager与DecorView的纽带,View的整个绘制流程的三大步(measure.layout.draw)都是通过ViewRoot完 ...

  7. linux线程同步实例

    [Linux多线程]三个经典同步问题 - 神奕的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/lisonglisonglisong/article/details ...

  8. PAT L1-044 稳赢

    https://pintia.cn/problem-sets/994805046380707840/problems/994805086365007872 大家应该都会玩“锤子剪刀布”的游戏:两人同时 ...

  9. Node js MySQL简单操作

    //win7环境下node要先安装MySQL的相关组件(非安装MySQL数据库),在cmd命令行进入node项目目录后执行以下语句 //npm install mysql var mysql = re ...

  10. mysql8基本配置,差点被各种坑蒙圈

    1. 下载免安装版mysql地址 https://dev.mysql.com/downloads/mysql/ 2. 基本配置 (1)解压zip包,将bin目录添加到环境变量 (2)在mysql根目录 ...