在asp.net WebAPI 中 使用Forms认证和ModelValidata(模型验证)
一、Forms认证
1、在webapi项目中启用Forms认证
Why:为什么要在WebAPI中使用Forms认证?因为其它项目使用的是Forms认证。
What:什么是Forms认证?它在WebAPI中就是一个MessageHandle,具体请查找关键字“ASP.NET Forms”
How:如何启动Forms认证?
最简单的是通过配置启动Forms认证:
<system.web>
<authentication mode="Forms">
<forms name=".FormsCookie" loginUrl="/login.aspx" protection="All" timeout="43200" path="/" defaultUrl="http://www.cnblogs.com" domain=".cnblogs.com" cookieless="UseCookies" />
</authentication>
<httpCookies httpOnlyCookies="true" />
</system.web>
<system.webServer>
简单说说Forms认证的工作原理:首先在管道中,Forms读取请求中的相关的cookie,解密,进行认证,并把认证的结果写到请求上下文和线程的Identity属性中。然后请求继续往后面走,最终生成的响应在管道中返回时,Forms会判断如果响应为401,那么就location到配置中的loginUrl设置的地址,并改变status为302。
2、几个Attribute
Why:为什么要认识Attribute?因为Forms认证的结果是写到Identity属性中,一般我们要获取该属性,判断是否认证成功,如果失败返回401,等等进行很多处理。是不是很麻烦?对,封装起来,自己写一个吗?当然可以,其实微软大法早就考虑好了,针对一般的场景的处理逻辑都封装好了,他们分别叫做
AuthorizeAttribute、AllowAnonymousAttribute,都是Attribute。
What:这些Attribute是什么?顾名思义,AuthorizeAttribute只允许认证通过的请求,AllowAnonymousAttribute允许匿名请求。
How:那么该怎么用呢?很简单他们可以作用类型、方法上,所以可以全局注册、controller、action, so easy!
3、重写unauthorize中验证失败方法
Why:因为如果response status == 401,那么Forms会location到配置中的loginUrl,(即使没有手动配置它,也会生成一个默认值“login.aspx”),并且设置status为302。如果客户端是浏览器的话,那么就会直接进行跳转而无法捕获这个状态,这在很多场景下不合适,例如:spa(单页应用)中,我们不希望它自动跳转到登陆页面,而是给出提示,让用户自己选择是否登录。所以要重写Forms中身份验证失败的处理逻辑。
How:在AuthorizationFilterAttribute中有个虚方法HandleUnauthorizedRequest,重写它来实现自定义的处理逻辑。这样的设计思路挺不错,可以多借鉴。
/// <summary>
/// If unauthorize return 403 instead of 401, avoid redirect.
/// </summary>
public class ForbiddenLocationAuthorizeAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
{
HttpResponseMessage response = new HttpResponseMessage();
response.StatusCode = System.Net.HttpStatusCode.Forbidden;
actionContext.Response = response; }
}
使用403(Forbidden)来代替401,这样就可以避免Forms的自动跳转了。虽然这样做有些弊端,但这也不失为一个有效的解决办法。
二、ModelValidata(模型验证)
1、Why
凡是有用户输入的地方都少不了参数验证,这不光是个安全问题,也是为了保证数据完整正确。
2、What
WebAPI集成了模型验证机制,当请求被action执行之前,有一个模型绑定的步骤,它就是匹配action的参数,具体细节就不说了,ModelValidata就是在这里进行,它会根据Model中各个属性的DataAnnotations(数据注解)来进行验证,最终把结果保存在action的上下文的一个属性中,即actionContext.ModelState.IsValid。
3、How
a、为Model设置DataAnnotations
public class BannerDto
{
[JsonProperty(PropertyName = "id")]
[Required(ErrorMessage = "Id是必须的")]
public Guid Id { get; set; } [JsonProperty(PropertyName = "title")]
[Required(ErrorMessage = "标题不能为空")]
[MaxLength(, ErrorMessage = "标题不能超过200个字符")]
public string Title { get; set; } [JsonProperty(PropertyName = "src")]
[Required(ErrorMessage = "图片链接不能为空")]
[MaxLength(, ErrorMessage = "图片链接不能超过500个字符")]
public string ImageUri { get; set; } [JsonProperty(PropertyName = "href")]
[Required(ErrorMessage = "超链接不能为空")]
[MaxLength(, ErrorMessage = "超链接不能超过500个字符")]
public string Href { get; set; } [JsonIgnore]
public Guid? AuthorityId { get; set; } [JsonIgnore]
public bool IsDeleted { get; set; } = false; [JsonProperty(PropertyName ="createDate")]
public DateTime CreateDate { get; set; }
}
ps:[JsonProperty]、[JsonIgnore]是指定Json序列化的一些相关设置,设置别名、忽略等等。返回优雅的变量的名称,保证代码风格。
DataAnnotations的使用,请查看msdn,太简单了。设置好约束条件和ErrorMessage,当验证失败了,就会返回ErrorMessage。
b、使用Filter方式,为Action添加验证,好处就不多说了。
public class ValidataModelAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (!actionContext.ModelState.IsValid)
{
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
}
}
}
别忘了在HttpComfiguration中注入这个Filter
//模型验证
config.Filters.Add(new ValidataModelAttribute());
对于不希望不验证的Action可以使用OverrideActionFilters重写上级设置的所有Fiters。
ModelValidate失败的请求会得到400的响应,同时所有ErrorMessage都会在响应报文中,例如:
{"Message":"The request is invalid.","ModelState":{"sub.Href":["超链接不可为空"]}}
在asp.net WebAPI 中 使用Forms认证和ModelValidata(模型验证)的更多相关文章
- 关于ASP.NET WebAPI中HTTP模型的相关思考
对于.NET的分布式应用开发,可以供我们选择的技术和框架比较多,例如webservice,.net remoting,MSMQ,WCF等等技术.对于这些技术很多人都不会陌生,即时没有深入的了解,但是肯 ...
- ASP.NET Core 中的那些认证中间件及一些重要知识点
前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(一,二,三)奠定一下基础. 有关于 Authentication 的知识太广,所以本篇介绍几个在 A ...
- [转]ASP.NET Core 中的那些认证中间件及一些重要知识点
本文转自:http://www.qingruanit.net/c_all/article_6645.html 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系 ...
- ASP.NET Core 中jwt授权认证的流程原理
目录 1,快速实现授权验证 1.1 添加 JWT 服务配置 1.2 颁发 Token 1.3 添加 API访问 2,探究授权认证中间件 2.1 实现 Token 解析 2.2 实现校验认证 1,快速实 ...
- 在ASP.NET WebAPI 中使用缓存【Redis】
初步看了下CacheCow与OutputCache,感觉还是CacheOutput比较符合自己的要求,使用也很简单 PM>Install-Package Strathweb.CacheOutpu ...
- Using ASP.Net WebAPI with Web Forms
Asp.Net WebAPI is a framework for building RESTful HTTP services which can be used across a wide ran ...
- Asp.Net WebAPI 中Cookie 获取操作方式
1. /// <summary> /// 获取上下文中的cookie /// </summary> /// <returns></returns> [H ...
- 如何简单的在 ASP.NET Core 中集成 JWT 认证?
前情提要:ASP.NET Core 使用 JWT 搭建分布式无状态身份验证系统 文章超长预警(1万字以上),不想看全部实现过程的同学可以直接跳转到末尾查看成果或者一键安装相关的 nuget 包 自上一 ...
- [翻译] ASP.NET WebAPI 中的异常处理
原文链接:https://docs.microsoft.com/en-us/aspnet/web-api/overview/error-handling/exception-handling 本文介绍 ...
随机推荐
- 选择本地照片之后即显示在Img中(客户体验)
最近转战MVC项目,然后又再次遇到照片上传的实现,之前都是使用ASP.NET,虽然也有照片上传,而且出于客户体验考虑, 也实现了选择本地照片之后即时显示在IMG中,在这里就简单介绍其实现(ASP.NE ...
- 在 Linux 下将 PNG 和 JPG 批量互转的四种方法
计算机术语中,批处理指的是用一个非交互式的程序来执行一序列的任务[1]的方法.这篇教程里,我们会使用 Linux 命令行工具,并提供 4 种简单的处理方式来把一些 .PNG 格式的图像批量转换成 .J ...
- Python切片
切片是啥, 可以吃么 切片肿么用哈 辣么长,记不住 切片是啥, 可以吃么 嘛,所谓切片故名思意就有选取的意思啦, 跟java里面的subString()意思差不多, 从原始的字符串中按规则提取出新的字 ...
- Fuzzy Probability Theory---(2)Computing Fuzzy Probabilities
Let $X=\{x_1,x_2,...,x_n\}$ be a finite set and let $P$ be a probability function defined on all sub ...
- 【Java】:压缩成多个压缩卷
Java自带的库不支持压缩成多个压缩卷,找到了一个开源库 zip4j ,发现更好用 so easy package com.jws.common.mail; import java.io.File; ...
- Could not create the view: An unexpected exception was thrown 【转】
转:http://blog.csdn.net/shuangzixing520/article/details/35225105 今天打开Myeclipse10的时候,发现server窗口出现一堆问题, ...
- BZOJ 1047: [HAOI2007]理想的正方形
题目 单调队列是个很神奇的东西,我以前在博客写过(吧) 我很佩服rank里那些排前几的大神,700ms做了时限10s的题,简直不能忍.(但是我还是不会写 我大概一年半没写单调队列,也有可能根本没有写过 ...
- Tomcat7下出现The requested resource(/)is not available
1首先确保你的localhost是否正常运行解决方案:1观察项目是否部署2重新将tomcat7导入 2确保你的项目名后跟index.jsp是否正常运行解决方案:1右键项目名,web进行查询,观察部署的 ...
- jQuery学习-什么是jquery? Js与jquery之间的关系 Jquery选择器
1. 什么是jQuery以及学习的意义等 jQuery是一个js库 JS库是什么? 把常用的方法,进行封装,封装到一个单独的js文件当中,要用的时候直接调用. 学习jQuery主要学什么? 学习jQ ...
- java swing 去掉按钮文字周围的焦点框
闲来无事,写了个swing界面,运行后看到当点击按钮时,中间文字会出现一个刚好把文字围住的小方框,这是按钮获得焦点的标志,我是觉得一个字:丑!怎么去掉呢?万能的度娘告诉我,设置下button的setF ...