最近看了一点 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. java通过控制鼠标实现屏幕广播

    在java实现屏幕共享的小程序中提到截取屏幕时是没鼠标,为了看到教师端界面上的鼠标,可以在截取屏幕的时候,把鼠标绘制到每一张截图上去,但是由于截图的时候是一张张截取的,所以看到的鼠标难免会有点卡,之前 ...

  2. ubuntu 安装 hustoj

    https://github.com/zhblue/hustoj 准备工作: http://www.java123.net/v/961634.html 1.首先打开命令行,切换到root身份,获得最新 ...

  3. javaIO--文件操作类

    文件操作类主要是使用File类的各种方法对文件和目录进行操作.包括文件名.文件长度.最后修改时间和是否只读等,提供获得当前文件的路径名.判断文件是否存在.创建.删除文件和目录等一系列的操作方法. 下面 ...

  4. Java中的线程状态转换和线程控制常用方法

    Java 中的线程状态转换: [注]:不是 start 之后就立刻开始执行, 只是就绪了(CPU 可能正在运行其他的线程). [注]:只有被 CPU 调度之后,线程才开始执行, 当 CPU 分配给你的 ...

  5. ACM 第十六天

    计算几何 练习题: F - Beauty Contest POJ - 2187 Bessie, Farmer John's prize cow, has just won first place in ...

  6. 【OSG】 报错:丢失osg100-osgDB.dll

    如果你bin目录已经添加到了环境变量的path里面,还报这个错的话. 或许你重启一下电脑就可以了..我就这么解决的.

  7. ZOJ 1666 G-Square Coins

    https://vjudge.net/contest/67836#problem/G People in Silverland use square coins. Not only they have ...

  8. 关于FEer发展方向的思考

    今天学习了HTTP权威指南这本书,虽然标题是对FEer发展的思考,不过我打算稍后再说这个议题,先对今天学习的内容做个总结. 首先:原来访问服务器的方式有多重,核心是URI,也就是统一资源定位,按照访问 ...

  9. activity属性设置大全

    activity属性设置大全 android:allowTaskReparenting=["true" | "false"]         是否允许activ ...

  10. Java调用WebService之Axis实现

    import org.apache.axis.client.Call; import org.apache.axis.client.Service; /** * @ClassName: TestAxi ...