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 ...
随机推荐
- “Hello world!”贡献分分配规则
规则1:得到总分后取14分,剩下分数进行平分.(备注:例如得了50分,取出14分,剩下36分组内进行平分) 规则2:对于会议准时参加者每人加0.5分.(备注:按通知开会时间为准,准时到者实行加分.) ...
- mysql 复杂查询
1.同一个表下多次查询: sql语句: select b.* ,(select name from exh_common.medicine_type a where b.p_id = a.id) as ...
- asp.net .net4.0使用异步编程
"; Action<object> ac = (object obj) => { Debug.WriteLine("睡眠开始:" + DateTime. ...
- UBUNTU如何安装tar.gz版的flash
adobe flash player的官方下载页面为:https://get.adobe.com/cn/flashplayer/ 不过近期通过APT方式以及ubuntu的软件中心都安装不了flashp ...
- java — 排序算法
1.冒泡排序 比较相邻元素,如果第一个比第二个大,就交换位置,每一次交换,当前 package BubbleSort; public class Test { public static void m ...
- 深入了解View的绘制流程
1. ViewRoot ViewRoot是连接WindowManager与DecorView的纽带,View的整个绘制流程的三大步(measure.layout.draw)都是通过ViewRoot完 ...
- linux线程同步实例
[Linux多线程]三个经典同步问题 - 神奕的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/lisonglisonglisong/article/details ...
- PAT L1-044 稳赢
https://pintia.cn/problem-sets/994805046380707840/problems/994805086365007872 大家应该都会玩“锤子剪刀布”的游戏:两人同时 ...
- Node js MySQL简单操作
//win7环境下node要先安装MySQL的相关组件(非安装MySQL数据库),在cmd命令行进入node项目目录后执行以下语句 //npm install mysql var mysql = re ...
- mysql8基本配置,差点被各种坑蒙圈
1. 下载免安装版mysql地址 https://dev.mysql.com/downloads/mysql/ 2. 基本配置 (1)解压zip包,将bin目录添加到环境变量 (2)在mysql根目录 ...