如何对项目暴露的webapi 认证进行安全认证

很多时候我们在接收到客户端提交过来的请求之前,要验证一下数据合法性再执行操作。
数据注解Data Annotations
在WepApi中可以使用命名空间的属性,在你的model类中设置属性,来实现验证。
考虑以下场景:
using System.ComponentModel.DataAnnotations;
namespace MyApi.Models
&&& public class Product
&&&&&&& public int Id {
&&&&&&& [Required]
&&&&&&& public string
&&&&&&& public decimal
Price {get;
&&&&&&& [Range(0,
&&&&&&& public double
如果你在MVC中使用过模型验证,那么看起来很眼熟,[Required]特性表示Name不能为null,[Range]特性表示Weight必须在0-999范围内。
假设收到客户端POST过来的json数据:
&Price&:2.99,
&Weight&:5 }
我们可以看到数据并没有包含Name,而Name我们是标记了[Required]特性的。当WebApi将其转换为Product实体的时候,就会发生验证冲突。
在你的Action中可以验证Model是否合法:
public class
ProductsController :
ApiController
&&&&&&& public
HttpResponseMessagePost(Product
&&&&&&&&&&& if (ModelState.IsValid)
&&&&&&&&&&& {
&&&&&&&&&&&&&&& // Dosomething with the product (not shown).
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
HttpResponseMessage(HttpStatusCode.OK);
&&&&&&&&&&& }
&&&&&&&&&&& else
&&&&&&&&&&& {
&&&&&&&&&&&&&&& return
Request.CreateErrorResponse(HttpStatusCode.BadRequest,
ModelState);
&&&&&&&&&&& }
但是模型验证不能保证完全不会出现问题,所以你需要在程序的其他层中增加验证,比如在Model层增加外键关联等等(EF)。
如果你使用的是EF可以参照文章,其中介绍了很多类似的问题。
“Under-Posting”(参数缺失)
传过来的数据中参数缺失的情况,例如:
&& {&Id&:4,
&Name&:&Gizmo&}
这里没有传Pirce,Weight参数,此时Json
Formatter会指定默认的值;
&Over-Posting&(参数多余)
传过来的参数多
&Name&:&Gizmo&,
&Color&:&Blue&}
可以看到传过来一个不存在Color属性,既然这样,formatter会忽略该值,XMLformatter也一样。
注意,当你打算将某个属性作为只读属性的时候可能有问题。
public class UserProfile
&&& public string Name {
&&& public UriBlog {
&&& public bool IsAdmin {
你不希望用户可以修改IsAdmin这个值,因为这样会篡改为管理员权限!
最好的办法就是使用DTO对象,说白了就是封装一层面向展示层的对象,将IsAdmin剔除,这样用户就不会修改该值了。
public class UserProfileDTO
&&& public string Name {
&&& public UriBlog {
&&& // Leave out &IsAdmin&
&处理验证错误
&& 1.当验证错误的时候WebApi不会自动向客户端返回错误,而是有Action编写代码实现向客户端返回错误。
&& 2.你也可以自己创建一个action filter去验证模型状态(model
state),如果发生错误则会想客户端返回错误信息,action也不会执行。
namespace MyApi.Filters
&&& public class ValidateModelAttribute:
ActionFilterAttribute
&&&&&&& public override void
OnActionExecuting(HttpActionContext actionContext)
&&&&&&&&&&& if (actionContext.ModelState.IsValid
&&&&&&&&&&& {
&&&&&&&&&&&&&&& actionContext.Response = actionContext.Request.CreateErrorResponse(
&&&&&&&&&&&&&&&&&&& HttpStatusCode.BadRequest,actionContext.ModelState);
&&&&&&&&&&& }
HTTP/1.1 400 Bad Request
Content-Type: application/ charset=utf-8
Date: Tue, 16 Jul :29 GMT
Content-Length: 331
&&&Message&: &The request isinvalid.&,
&&&ModelState&: {
&&&&&product&: [
&&&&&&&Required property'Name' not found in JSON. Path '', line 1, position 17.&
&&&&&product.Name&: [
&&&&&&&The Name field isrequired.&
&&&&&product.Weight&: [
&&&&&&&The field Weight mustbe between 0 and 999.&
如何应用这个filter呢?需要在&HttpConfiguration.Filters&集合中添加刚才创建的filter
public static class WebApiConfig
&&&&&&& public static void
Register(HttpConfiguration config)
&&&&&&&&&&& config.Filters.Add(new
ValidateModelAttribute());
3.另外一个方式就是添加特性(简便省事儿)
public class ProductsController :
ApiController
&&& [ValidateModel]
&&& public HttpResponseMessagePost(Product
&&&&&&& // ...
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:572次
排名:千里之外/MR-YY/p/5972380.html
/zhangxiaolei521/p/5986996.html
/csqb-/p/4864650.html
阅读(...) 评论()ASP.NET Web API(二):安全验证之使用HTTP基本认证
我的图书馆
ASP.NET Web API(二):安全验证之使用HTTP基本认证
&在前一篇文章中,我们初步接触了微软的REST API: Web API。
我们在接触了Web API的后就立马发现了有安全验证的需求,所以这篇文章我们先来讨论下安全验证一个最简单的方法:使用HTTP基本认证。
HTTP基本认证原理
在HTTP协议进行通信的过程中,HTTP协议定义了基本认证过程以允许HTTP服务器对WEB浏览器进行用户身份认证的方法,当一个客户端向HTTP服务器进行数据请求时,如果客户端未被认证,则HTTP服务器将通过基本认证过程对客户端的用户名及密码进行验证,以决定用户是否合法。
其基本的实现方式是:
客户端在用户输入用户名及密码后,将用户名及密码以BASE64加密,加密后的密文将附加于请求信息中,如当用户名为Parry,密码为123456时,客户端将用户名和密码用":"合并,并将合并后的字符串用BASE64加密,并于每次请求数据时,将密文附加于请求头(Request Header)中。
HTTP服务器在每次收到请求包后,根据协议取得客户端附加的用户信息(BASE64加密的用户名和密码),解开请求包,对用户名及密码进行验证,如果用户名及密码正确,则根据客户端请求,返回客户端所需要的数据;否则,返回错误代码或重新要求客户端提供用户名及密码。
Web API使用HTTP基本认证进行安全验证
我们还是基于的示例进行测试。
首先我们基于System.Web.Http.AuthorizeAttribute类实现一个HTTP基本认证的类,并实现两个方法:OnAuthorization和HandleUnauthorizedRequest。
添加一个类HTTPBasicAuthorizeAttribute,继承于System.Web.Http.AuthorizeAttribute,先来实现OnAuthorization。
&1&public&override&void&OnAuthorization(System.Web.Http.Controllers.HttpActionContext&actionContext)
&3&&&&&if&(actionContext.Request.Headers.Authorization&!=&null)
&5&&&&&&&&&string&userInfo&=&Encoding.Default.GetString(Convert.FromBase64String(actionContext.Request.Headers.Authorization.Parameter));
&6&&&&&&&&&//用户验证逻辑
&7&&&&&&&&&if&(string.Equals(userInfo,&string.Format("{0}:{1}",&"Parry",&"123456")))
&8&&&&&&&&&{
&9&&&&&&&&&&&&&IsAuthorized(actionContext);
10&&&&&&&&&}
11&&&&&&&&&else
12&&&&&&&&&{
13&&&&&&&&&&&&&HandleUnauthorizedRequest(actionContext);
14&&&&&&&&&}
16&&&&&else
18&&&&&&&&&HandleUnauthorizedRequest(actionContext);
actionContext.Request.Headers.Authorization.Parameter就是Client BASE64后的字符串,我们对其进行反编码后,为了测试方便只进行简单的用户验证,这里你可以引入自己系统的验证逻辑。
同时还要实现HandleUnauthorizedRequest以实现验证失败时继续提示验证,代码如下:
1&protected&override&void&HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext&actionContext)
3&&&&&var&challengeMessage&=&new&System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
4&&&&&challengeMessage.Headers.Add("WWW-Authenticate",&"Basic");
5&&&&&throw&new&System.Web.Http.HttpResponseException(challengeMessage);
完成了此类后,只要在需要启用HTTP基本认证的Controller的类加上此属性即可,就像下面这样。
我们现在来测试验证过程。
当我们再来请求此API时,就会提示需要输入用户名和密码。
这时使用Fiddler进行抓包查看HTTP Header,就会发现了WWW-Authenticate的头。
在提供了正确的用户名和密码后,我们发现HTTP已将Parry:123456进行BASE64编码后的密文添加在了Request Header里面。
提交后成功地请求到了数据,如果输入的验证信息不正确,还是返回HTTP Status Code为401的未验证状态以继续验证。
输入正确的用户信息后请求到的数据。
HTTP基本认证的优缺点
优点是逻辑简单明了、设置简单。
缺点显而易见,即使是BASE64后也是可见的明文,很容易被破解、非法利用,使用HTTPS是一个解决方案。
还有就是HTTP是无状态的,同一客户端每次都需要验证。
针对这种情况,我们下一篇文章讨论下第二种验证方式:摘要认证(digest authentication)。
觉得文章还行的话就推荐下吧,哈哈。源码下载&
发表评论:
TA的最新馆藏[转]&}

我要回帖

更多关于 webapi 如何暴露接口 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信