.net 常用认证方法 forgery token 认证
来源:互联网 发布:软件开发费用报价 编辑:程序博客网 时间:2024/06/05 12:43
常用的在 asp .net 与 MVC .net中常用的就是 from 认证 与 Windows认证。
对于form认证, 我们需要在web.config下面 system.web节点 加入认证配置。
<authentication mode="Forms"> <forms loginUrl="~/Account/Login" name=".Acc" protection="All" timeout="30" cookieless="UseCookies" slidingExpiration="true" ticketCompatibilityMode="Framework40" /> </authentication> <httpCookies httpOnlyCookies="true" /> <sessionState timeout="30" cookieName=".Acc_SessionId" />
在需要认证的方法 或者 class上面,使用 Authorize 属性方法,不需要认证可以用AllowAnonymous 属性,不需要认证。默认情况 不加也是匿名认证。登录成功后,我们会设置form认证的用户名,完成授权。
FormsAuthentication.SetAuthCookie(userName, false);
有时候需要自己重写认证方法,可以在是class 继承实现类中,重写 OnAuthorization 方法,也可以,使用属性类 的方法 来重写。 下面可以判断请求的方式是ajax还是直接通过http 过来的请求。
protected override void OnAuthorization(AuthorizationContext filterContext) { base.OnAuthorization(filterContext); if (filterContext.Result != null) { return; } if (filterContext.ActionDescriptor.GetCustomAttributes(typeof(NotRenewSessionAttribute), true).Any()) { return; } if (filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(NotRenewSessionAttribute), true).Any()) { return; } if (!User.Identity.IsAuthenticated || string.IsNullOrEmpty(ApplicationContext.UserName) || string.IsNullOrEmpty(ApplicationContext.GetSessionId())) { if (Request.IsAjaxRequest()) { filterContext.HttpContext.Response.StatusCode = 200; var ajaxResultModel = new AjaxResultModel(); ajaxResultModel.Message = Messages.Admin.SessionTimeoutOrKilled.Format(); SessionException exception = new SessionException(Errors.ErrorCodes.E0501, SessionStatus.Inactive, ajaxResultModel.Message); ExceptionInfo exceptionInfo = new ExceptionInfo(exception); //ajaxResultModel.ExceptionInfo = exceptionInfo; ajaxResultModel.Code = AjaxStatusCode.SessionTimeout; ajaxResultModel.IsSuccess = false; ajaxResultModel.MessageInfo = ajaxResultModel.Message; filterContext.Result = Json(new { data = ajaxResultModel }, JsonRequestBehavior.AllowGet);//new JsonResult { Data = ajaxResultModel, JsonRequestBehavior = JsonRequestBehavior.AllowGet }; } else { filterContext.Result = new HttpUnauthorizedResult(); } } } protected override void OnActionExecuting(ActionExecutingContext filterContext) { if (filterContext.Result != null) { return; } if (filterContext.ActionDescriptor.GetCustomAttributes(typeof(NotRenewSessionAttribute), true).Any()) { return; } if (filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(NotRenewSessionAttribute), true).Any()) { return; } string sessionId = this.ApplicationContext.GetSessionId(); if (!string.IsNullOrEmpty(sessionId)) { try { SessionManager.Renew(sessionId); } catch (SessionException) { this.ApplicationContext.SetSessionId(null); throw; } } else { throw new SessionException(Errors.ErrorCodes.E0503); } base.OnActionExecuting(filterContext); } protected override void HandleUnknownAction(string actionName) { if (this.GetType() != typeof(AcceleratorBaseController)) { //handle unknow controller Response.RedirectToRoute(new { controller = "Home", action = "PageNotFound" }); } }这里分享下,session 共享问题,前段时间发现,两个站点都在同一台server的iis服务器上面,当登录一个站点时候,另一个如果使用默认form认证的时候,另一个站点也是被授权了,这就是因为他们的session是共享的导致,最后原因发现因为在web配置文件中,两个站点配置了同一样的machineKey导致的,system.web节点。
<machineKey decryption="AES" decryptionKey="CFE8BCC5155F55D55FAECDB2E5E75867EEAE527D917949A5465248105C2867A1" validation="SHA1" validationKey="9C594C1C1A1C796A7C72C1D4D2568C9E8618BDFF8EBB92C8091CE68B02D5EE7307D1FFB4FDBA174E87C7F3878CC3260EBB7ED713BCB6ADE628E6E89578731E4DC1" />
可以在iis的站点目录下找到machine key配置,然后重新生成key。即可解决问题。这样两个站点就不会同用一个session了。
对于windows 认证,只要在web config下面开启 windows认证即可,你可以直接制定用户,登录时候会弹出默认的windows认证的验证,需要认证。
推荐测试工具,https://insomnia.rest/download/
<system.web> <authentication mode="Windows" /> <!--<authentication mode="Windows"> <forms > <credentials passwordFormat="Clear"> <user name="administrator" password="password1"></user> </credentials> </forms> </authentication>-->
<!--<authorization> <allow users="domain\Administrator"/> <deny users="?"/> </authorization>-->
如果是ajax 或者http过来的请求,httpWebRequest.Credentials 把用户名和password传过去即可。
public static string PostSecurityRequest(string remoteUrl, string postData, string userName, string password, string domain, int timeOut = 60000, string encode = "UTF-8", string contentType = "application/x-www-form-urlencoded") { string str = ""; System.Net.HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(remoteUrl); byte[] bytes = Encoding.GetEncoding(encode).GetBytes(postData); httpWebRequest.Method = "Post"; httpWebRequest.ContentType = contentType; httpWebRequest.ContentLength = (long)bytes.Length; httpWebRequest.Timeout = timeOut; httpWebRequest.UseDefaultCredentials = false; httpWebRequest.PreAuthenticate = false; httpWebRequest.Credentials = new NetworkCredential(userName, password, domain); Stream requestStream = httpWebRequest.GetRequestStream(); requestStream.Write(bytes, 0, bytes.Length); requestStream.Close(); Stream responseStream = httpWebRequest.GetResponse().GetResponseStream(); if (responseStream != null) { StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding(encode)); str = streamReader.ReadToEnd(); streamReader.Close(); responseStream.Close(); } return str; }
对于防止CSRF跨站请求伪造攻击,我可以可以使用.net的自带【ValidateAntiForgeryToken】 进行验证,只需要加在增删改的方法上面,在from标签里面加入token post到后台即可@Html.AntiForgeryToken()。
对于ajax请求 可以直接获取token post到后台。
var forgeryToken = $("input[name=__RequestVerificationToken]").val();
data: { formId: formId, __RequestVerificationToken: forgeryToken },
中间项目使用angular js 前端, 研究了一下如何使用该功能,我们可以自定义验证方法,把token 在header中传过去。 在master 全局页面中加入token在页面。使用ajax和anjular 封装好的http请求。
@functions{ public string GetAntiForgeryToken() { string cookieToken, formToken; AntiForgery.GetTokens(null, out cookieToken, out formToken); return cookieToken + ":" + formToken; } }
<input id="antiForgeryToken" type="hidden" value="@GetAntiForgeryToken()" />
accept: () => { $.ajax({ url: './Request', headers: {'RequestVerificationToken': $("#antiForgeryToken")[0].value}, data: formData, type: 'POST', contentType: false, processData: false, dataType: 'json', async: false, cache: false }).always(function (jqXHR: any, textStatus: any, errorThrown: any) { var data = (jqXHR.responseJSON || jqXHR).data; if (data.IsSuccess) { messageFlag = "success"; } else { messageFlag = "failure"; errorMessage = data.MessageInfo; } });
导入jquery, declare var $: any;
options: RequestOptions; constructor(private http: Http) { let headers = new Headers(); headers.append('X-Requested-With', 'XMLHttpRequest'); if ($("#antiForgeryToken")) { headers.append('RequestVerificationToken', $("#antiForgeryToken")[0].value); } this.options = new RequestOptions({ headers: headers }); }
在头文件里加入 ajax 请求,和token值。在方法上使用自定义方法验证。
[MyValidateAntiForgeryToken]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] public class MyValidateAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter { private void ValidateRequestHeader(HttpRequestBase request) { string cookieToken = String.Empty; string formToken = String.Empty; string tokenValue = request.Headers["RequestVerificationToken"] ?? ""; if (!String.IsNullOrEmpty(tokenValue)) { string[] tokens = tokenValue.Split(':'); if (tokens.Length == 2) { cookieToken = tokens[0].Trim(); formToken = tokens[1].Trim(); } } AntiForgery.Validate(cookieToken, formToken); } public void OnAuthorization(AuthorizationContext filterContext) { try { if (filterContext.HttpContext.Request.IsAjaxRequest()) { ValidateRequestHeader(filterContext.HttpContext.Request); } else { AntiForgery.Validate(); } } catch (HttpAntiForgeryException e) { throw new HttpAntiForgeryException("Anti forgery token cookie not found"); } } }
- .net 常用认证方法 forgery token 认证
- keystonemiddleware中的token 认证
- token认证,基础知识
- Token认证机制
- Token认证问题
- .NET 认证
- django使用token认证authenticate
- Json Web Token身份认证
- hack web认证的常用方法
- 认证
- 认证
- 认证
- 认证
- 在ASP.NET Core中实现一个Token base的身份认证
- 在ASP.NET Core中使用Angular2,以及与Angular2的Token base身份认证
- 基于Token的WEB后台认证机制
- 基于Token的WEB后台认证机制
- 基于Token的WEB后台认证机制
- 在VS2010 VC++项目中引用Lib静态库(以Openssl为例)
- vector容器结构体类型查找
- 多元服务实力"圈粉" 九成政务大厅走向"一站式"审批
- Python基础篇之If语句
- Guava官方文档-RateLimiter类
- .net 常用认证方法 forgery token 认证
- Android系统中标准Intent的使用
- DedeCMS提示你访问的用户可能已经被删除的问题
- 22个值得收藏的android开源代码-UI篇
- SubGrid 例子(摘选自easyUI api)
- Angular4_控制台错误
- haslayout详解
- 稳压电源 连载16:模板和参考电路.
- 小马的git使用记