Asp.net Web Api 2 FORM Authentication Demo
最近看了一点 web api 2方面的书,对认证都是简单介绍了下,所以我在这里做个简单Demo,本文主要是FORM Authentication,顺带把基本认证也讲了。
一、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>密 码</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中了,不再赘述。
相关链接: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
好了到此结束。
Asp.net Web Api 2 FORM Authentication Demo的更多相关文章
- 购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(3)--Idetity,OWIN前后端验证
原文:购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(3)--Idetity,OWIN前后端验证 chsakell分享了前端使用AngularJS,后端使用ASP. ...
- 购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(2)--前端,以及前后端Session
原文:购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(2)--前端,以及前后端Session chsakell分享了前端使用AngularJS,后端使用ASP.NE ...
- 购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(1)--后端
原文:购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(1)--后端 chsakell分享了前端使用AngularJS,后端使用ASP.NET Web API的购物车 ...
- ASP.NET Web API实践系列01,以ASP.NET Web Form方式寄宿
创建一个空的ASP.NET Web Form项目. 右键项目,添加新项,创建Web API控制器类,TestController. 删除掉TestController默认的内容,编写如下: using ...
- 初试ASP.NET Web API/MVC API(附Demo)
写在前面 HTTP RESTful 创建Web API 调用Web API 运行截图及Demo下载 ASP.NET Web API是一个框架,可以很容易构建达成了广泛的HTTP服务客户端,包括浏览 ...
- [转]ASP.NET Web API(三):安全验证之使用摘要认证(digest authentication)
本文转自:http://www.cnblogs.com/parry/p/ASPNET_MVC_Web_API_digest_authentication.html 在前一篇文章中,主要讨论了使用HTT ...
- ASP.NET Web API(三):安全验证之使用摘要认证(digest authentication)
在前一篇文章中,主要讨论了使用HTTP基本认证的方法,因为HTTP基本认证的方式决定了它在安全性方面存在很大的问题,所以接下来看看另一种验证的方式:digest authentication,即摘要认 ...
- 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 ...
- 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 ...
随机推荐
- Alphabetic Removals(模拟水题)
You are given a string ss consisting of nn lowercase Latin letters. Polycarp wants to remove exactly ...
- TCP系列37—Keep Alive—1、TCP存活检测
一.TCP存活(keepalive)检测的背景 对于TCP设计来说,如果一个客户端和服务器端建立连接后,不在进行数据传输,那么这个连接将会一直存在下去,理论上即使中间的路由器崩溃重启.或者中间的网络线 ...
- lol人物模型提取(六)
模型昨天就已经做出来了,不过到上色这一块貌似又遇到了一些问题.由于模型的眼睛比较小,没法做出亮光效果,上不了UV,只能做哑光效果的. 亮光效果: 哑光效果: 很显然亮光效果更加好看一点 ...
- django设置首页
1.在views中添加一个def 为homepage basepath=os.getcwd()+'\\dockerApp\\app\\templates\\';def homepage(request ...
- cacti 添加mysql 监控 (远程服务器)
监控主机 192.168.24.69 ,以下用A表示 被监控主机 192.168.24.79,以下用B标识 记得在A服务器的cacti中导入监控mysql的templates文件 1.在B上安 ...
- ORA-00933 SQL命令未正确结束 INSERT INTO ... SELECT
最近在修改数据库存储过程时,出现了一个ORA-00933错误, 执行的是 INSERT INTO...SELECT 语句,具体语句如下: INSERT INTO BASP_DX.QLR@GT(BDCD ...
- Linux命令发送Http GET/POST请求
Get请求 curl命令模拟Get请求: 1.使用curl命令: curl "http://www.baidu.com" 如果这里的URL指向的是一个文件或者一幅图都可以直接下载到 ...
- 【Python】python基础语法 编码
编码 默认情况下,python以UTF-8编码,所有的字符串都是Unicode字符串,可以为代码定义不同的的编码. #coding:UTF-8 #OR #-*- coding:UTF-8 -*- p ...
- C# 面向对象——继承
继承:代码文字结合理解 class Program { static void Main(string[] args) { //Student s = new Student(); //Driver ...
- POJ1236:Network of Schools——题解
http://poj.org/problem?id=1236 首先还是缩点,然后入度为0的点的个数就是你要投文件个数. 然后我们对于入度和出度为0的点的个数取最大值即为答案. (简单证明:入度和出度为 ...