当前位置: 首页 > news >正文

webservice、WCF、webAPI、MVC权限认证

webservice 权限认证

》》soapHeader

SOAPHeader案例

服务引用下生成的服务方法参数中会自动加入一个soapHeader的参数,
WEB服务引用则没有,我感觉采用WEB服务引用基于这种验证比较方便,
因为只需将soapHeader实例赋值一次就可以多次调用不同的服务方法。

在这里插入图片描述

Asp.NET 认证

在asp.net中,将身份验证分成了两个部分,第一个部分是IIS的身份验证,在用户访问网站时,IIS首先就会对用户进行身份验证,这个身份验证的具体设置在IIS中,这也非本文的重点,在此也不再详细介绍了。只有IIS通过了用户的身份验证之后,
才会进行第二个部分的身份验证,这个部分的身份验证则由asp.net来完成。

》》》asp.net 身份认证的流程
在asp.net中,身份验证过程分为两部分,一部分是IIS中的身份验证,只有通过了IIS中的身份验证之后,才行进行asp.net中的身份验证。一个完整的窗体身份验证流程如下所示:

首先,用户通过浏览器向服务器发送一个网页请求,假设用户要访问index.aspx网页, 那么浏览器就会将请求发送给IIS服务器。
假设在该服务器中将IIS设置成可以匿名访问,那么IIS服务器将会允许访问index.aspx网页。
IIS服务器允许访问之后,将会进入asp.net身份验证。asp.net会去web.config文件中查看节点下的节点中是否拒绝所有匿名用户。如果拒绝了所有匿名用户,服务器则会去查找一个身份验证的Cookie。
如果服务器查找不到该身份验证的Cookie,就会将网页跳转到登录页面。这个登录页面为节点中的loginUrl属性值,默认为网站根目录下的login.aspx。在跳转到到登录页面时,服务器会将当前访问的网页的地址,如index.aspx,作为ReturnUrl参数值附加到login.aspx的URL中。如下所示:
login.aspx?ReturnUrl=%2findex.aspx
用户在登录页面输入用户名和密码(或别的登录信息),并将这些信息提交到服务器。
服务器接收到用户提交的信息之后,判断用户是否为合法用户(判断方式有很多种,但这不是本文的重点),如果用户为合法用户,则创建一个包含窗体身份验证票的Cookie。
在创建完包含窗体身份验证票的Cookie之后,可以使用代码将网页跳回登录前访问的页面,如index.aspx网页(这个时侯ReturnUrl参数就起作用了)。
在登录后访问其它网页时(如跳转后的index.aspx页面),服务器会检测包含窗体身份验证的Cookie,并对用户进行身份验证。身

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

》》 window 集成认证

在IIS里取消匿名访问权限,若允许匿名访问,就没有必须提供验证凭证了

  R2RServiceSerialNumber sN = new R2RServiceSerialNumber();sN.Url = "http://172.xxxxx/R2RServiceSerialNumber.asmx";sN.Credentials = new NetworkCredential("用户名", "密码"); //用户名密码  SerialNumber SN = sN.GetSerialNumber("续保");strSerialNumber = SN.CurrentSerialNumber;
》》 表单认证 FORM认证
<forms name="name" loginUrl="URL" defaultUrl="URL"protection="[All|None|Encryption|Validation]"timeout="[MM]"path="path"requireSSL="[true|false]"slidingExpiration="[true|false]">enableCrossAppRedirects="[true|false]"cookieless="[UseUri|UseCookie|AutoDetect|UseDeviceProfile]" domain="domain name"ticketCompatibilityMode="[Framework20|Framework40]"><credentials>...</credentials></forms>
name:指定要用于身份验证的 HTTP Cookie。如果正在一台服务器上运行多个应用程序并且每个应用程序都需要唯一的 Cookie,则必须在每个应用程序的 Web.config 文件中配置 Cookie 名称。默认值为 ".ASPXAUTH"。
loginUrl:指定如果找不到任何有效的身份验证 Cookie,将请求重定向到的用于登录的 URL。默认值为 login.aspx。
defaultUrl:定义在身份验证之后用于重定向的默认 URL。默认值为 "default.aspx"。 如果登录页面的URL中没有ReturnUrl参数(也就是说,直接访问的登录页面)如果没有设置该属性,默认情况下为default.aspx页面。
protection:指定 Cookie 使用的加密类型(如果有)。默认值为 All。
timeout:指定 Cookie 过期前逝去的时间(以整数分钟为单位)。如果 SlidingExpiration 属性为 true,则 timeout 属性是滑动值,会在接收到上一个请求之后的指定时间(以分钟为单位)后过期。 为防止危及性能并避免向开启 Cookie 警告的用户发出多个浏览器警告,当指定的时间逝去大半时将更新 Cookie。这可能导致精确性受损。默认值为 "30"30 分钟)。 
path:为应用程序发出的 Cookie 指定路径。默认值是斜杠 ( /),这是因为大多数浏览器是区分大小写的,如果路径大小写不匹配,浏览器不会送回 Cookie。
requireSSL:指定是否需要 SSL 连接来传输身份验证 Cookie。默认值为 False。 
slidingExpiration:指定是否启用可调过期时间。可调过期将 Cookie 的当前身份验证时间重置为在单个会话期间收到每个请求时过期。默认值为 True。
enableCrossAppRedirects:表明是否将通过身份验证的用户重定向到其他 Web 应用程序中的 URL。默认值为 False。 
cookieless:定义是否使用 Cookie 以及 Cookie 的行为。默认值为 UseDeviceProfile.
domain:指定在传出 Forms 身份验证 Cookie 中设置的可选域。此设置的优先级高于 httpCookies 元素中使用的域。默认值为空字符串 ("")。
ticketCompatibilityMode:指定在 Forms 身份验证中对于票证到期日期使用协调世界时 (UTC) 还是本地时间。默认值为 Framework20。
**子元素**
credentials:允许选择在配置文件中定义名称和密码凭据。您还可以实现自定义的密码架构,以使用外部源(如数据库)来控制验证。

在这里插入图片描述
在这里插入图片描述
Clear 代表 密码是 明文

credentials 案例

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
》》》

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
》》FormsAuthentication.SetAuthCookie()方法创建身份验证票据的方法,事实上,这是一个使用缺省的身份验证票据的方法。在asp.net中,Forms身份验证的方式是在用户登录时创建一个身份验证票,然后将这个身份验证票存放在Cookie中,以后整个网站都可以通过这个Cookie来判断用户是否已经登录。如果用户浏览器不支持Cookie,
1。asp.net也可以将票证放在URL的查询字符串中进行传递,
2。放在header里

在这里插入图片描述
退出系统要
FormsAuthentication.SignOut();

FormsAuthentication.RedirectToLoginPage()”将网页跳转到登录页面。
在这里插入图片描述
FormsAuthenticationTicket()的
第一个参数为身份验证票的版本号,通常为1;
第二个参数为经过验证的用户名;
第三个参数为票证发出时的本地时间;
第四个参数为票证过期时的本地时间;
第五个参数为是否创建永久的Cookie;
第六个参数,也就是最重要的参数,为要传递的用户数据 【比如用户角色】。如果不需要传递用户数据,可以设为null。但本人建议使用空字符串,否则为票证加密时可能会产生意想不到的问题。

创建完身份验证票之后,可以使用FormsAuthentication类的Encrypt()方法为身份验证票加密,加密后返回一个字符串。然后创建一个Cookie,FormsAuthentication.FormsCookieName属性可以返回存放身份验证票的Cookie名,也就是web.config中<Forms>小节的name属性值。当然,在这里还可以设置一些Cookie相关的属性,如Cookie的path、expires、domain等,这此就不多介绍了。最后,将Cookie写入到客户端。

在这里插入图片描述
》》获取数据
string ss=System.Web.Security.FormsAuthentication.FormsCookiePath;
string s= System.Web.Security.FormsAuthentication.FormsCookieName; 在web.config中Forms
在这里插入图片描述

在这里插入图片描述
》》》asp.net 不同目录,不用角色

在这里插入图片描述
在这里插入图片描述

》》Global.asax

   protected void Application_AuthenticateRequest(object sender, EventArgs e){//判断正在请求页的用户的身份验证信息是否为空if (HttpContext.Current.User != null){//判断用户是否已经进行了身份验证if (HttpContext.Current.User.Identity.IsAuthenticated){//判断当前用户身份验证的方式是否为Forms身份验证方式if (HttpContext.Current.User.Identity is FormsIdentity){//获得进行了Forms身份验证的用户标识FormsIdentity UserIdent = (FormsIdentity)(HttpContext.Current.User.Identity);//从身份验证票中获得用户数据string UserData = UserIdent.Ticket.UserData;//分割用户数据得到用户角色数组string[] rolues = UserData.Split(',');//从用户标识和角色组初始化GenericPrincipal类HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(UserIdent, rolues);}}}}

在这里插入图片描述

//用户名string UserName = TextBox1.Text;//密码string UserPassword = TextBox2.Text;//用户角色string UserRole = "";//用户身份验证if ((UserName == "1" && UserPassword == "1") || (UserName == "2" && UserPassword == "2") ){//判断用户权限switch (UserName){case "1":UserRole = "Admin";break;case "2":UserRole = "backup";break;                  }//创建一个身份验证票FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, "zen", DateTime.Now, DateTime.Now.AddMinutes(30), false, UserRole);//将身份验证票加密string EncrTicket = FormsAuthentication.Encrypt(ticket);//创建一个CookieHttpCookie myCookie = new HttpCookie(FormsAuthentication.FormsCookieName, EncrTicket);//将Cookie写入客户端Response.Cookies.Add(myCookie);//跳转到初始请求页或默认页面Response.Redirect(FormsAuthentication.GetRedirectUrl("zen", false));}
Asp.net Window 认证

在这里插入图片描述
在这里插入图片描述
》》需要在IIS 中 开启Window是身份证验证,其它的关闭
在这里插入图片描述
asp.net 项目 web.config 配置
在这里插入图片描述
在这里插入图片描述

public partial class zen : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){var authenticationType = System.Web.HttpContext.Current.User.Identity.AuthenticationType;var domainUserName = System.Web.HttpContext.Current.User.Identity.Name;Response.Write("域账号:" + domainUserName + "<br/>");Response.Write("认证类型:" + authenticationType + "<br/>");var user = this.GetUserInfo(domainUserName);if (user != null){Response.Write("登录名:" + user.SAMAccountName + "<br/>");Response.Write("短名称:" + user.GivenName + "<br/>");Response.Write("名称:" + user.CN + "<br/>");Response.Write("邮件:" + user.Email + "<br/>");}}private UserInfo GetUserInfo(string domainUserName){try{if (string.IsNullOrEmpty(domainUserName)){return null;}var userArr = domainUserName.Split('\\');var domain = userArr[0];var loginName = userArr[1];var entry = new DirectoryEntry(string.Concat("LDAP://", domain));var search = new DirectorySearcher(entry);search.Filter = string.Format("(SAMAccountName={0})", loginName);search.PropertiesToLoad.Add("SAMAccountName");search.PropertiesToLoad.Add("givenName");search.PropertiesToLoad.Add("cn");search.PropertiesToLoad.Add("mail");var result = search.FindOne();if (result != null){var info = new UserInfo();info.SAMAccountName = result.Properties["SAMAccountName"][0].ToString();info.GivenName = result.Properties["givenName"][0].ToString();info.CN = result.Properties["cn"][0].ToString();info.Email = result.Properties["mail"][0].ToString();return info;}}catch{ }return null;}public sealed class UserInfo{public string SAMAccountName;public string GivenName;public string CN;public string Email;}}

在这里插入图片描述

MVC 权限认证

》》》Forms 表单认证
在这里插入图片描述
在这里插入图片描述
》》访问网页时,先请求AuthorizeCore这个方法,
AuthorizeAttribute 命名空间System.Web.Mvc

 public class MyAuthorizeAttribute:AuthorizeAttribute{protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext){var cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];var ticket = FormsAuthentication.Decrypt(cookie.Value);var roles = ticket.UserData;var inRoles = false;foreach (var role in roles.Split(',')){if (Roles.Contains(role)){inRoles = true;break;}}return inRoles;}}

在这里插入图片描述
》》 Home视图下面Index 访问需要Admin 角色才能访问
在这里插入图片描述

在这里插入图片描述

<form  method="post"><table><tr><td>用户名</td><td><input name="username" type="text" /></td></tr><tr><td>密码</td><td><input name="password" type="password" /></td></tr><tr><td colspan="2" ><input type="submit"  value="登录"/></td></tr></table>
</form>

在这里插入图片描述

MVC Forms 表单认证

在这里插入图片描述
在这里插入图片描述

public class AccountController : Controller{// GET: Accountpublic ActionResult Login(){string name = Request["username"];string password = Request["password"];if (name == "zen" && password == "123456"){FormsAuthentication.SetAuthCookie(name, false);              return Redirect(FormsAuthentication.GetRedirectUrl(name,false));}else{return View();}}}

在这里插入图片描述
》》》》 上面是MVC 默认的 AuthorizeAttribute

》》》 自定义ActionFilterAttribute

在这里插入图片描述

public class RequiresAuthenticationAttribute: ActionFilterAttribute{public string Role { get; set; }public override void OnActionExecuting(ActionExecutingContext filterContext){if (!string.IsNullOrEmpty(Role)){if (!filterContext.HttpContext.User.Identity.IsAuthenticated){string returnUrl = filterContext.HttpContext.Request.Url.AbsolutePath;string redirectUrl = string.Format("?ReturnUrl={0}", returnUrl);string loginUrl = FormsAuthentication.LoginUrl + redirectUrl;filterContext.HttpContext.Response.Redirect(loginUrl, true);}else{bool isAuthenticated = filterContext.HttpContext.User.IsInRole(Role);if (!isAuthenticated){throw new UnauthorizedAccessException("You have no right to view the page!");}}}else{throw new InvalidOperationException("No Role Specified!");}}}

在这里插入图片描述
在这里插入图片描述

  protected void Application_AuthenticateRequest(object sender, EventArgs e){//判断正在请求页的用户的身份验证信息是否为空if (HttpContext.Current.User != null){//判断用户是否已经进行了身份验证if (HttpContext.Current.User.Identity.IsAuthenticated){//判断当前用户身份验证的方式是否为Forms身份验证方式if (HttpContext.Current.User.Identity is FormsIdentity){//获得进行了Forms身份验证的用户标识FormsIdentity UserIdent = (FormsIdentity)(HttpContext.Current.User.Identity);//从身份验证票中获得用户数据string UserData = UserIdent.Ticket.UserData;//分割用户数据得到用户角色数组string[] rolues = UserData.Split(',');//从用户标识和角色组初始化GenericPrincipal类HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(UserIdent, rolues);}}}}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

webapi 摘要认证

摘要认证 服务器(IIS)要加入域,不然IIS中的摘要身份认证 启动是灰色的,无法使用。
同时要访问的客户端 也要跟IIS加入同一个域,不然无法请求
在这里插入图片描述
下面大致看一下这部分的验证流程:

1:客户端请求 地址;
2:服务端返回401未验证的状态,并且在返回的信息中包含了验证方式Digest,realm的值,QOP(quality of protection)只设置成auth,nonce为一串随机值,在下面的请求中会一直使用到,当过了存活期后服务端将刷新生成一个新的nonce值;
3:客户端接受到请求返回后,将username:realm:password进行HASH运算,假设运算后的值为HA1。又将请求的路径/api/employees进行HASH运算,假设运算后的值为HA2。再将HA1:nonce:nc:cnonce:qop:HA2进行HASH运算,得到的值放在response中。这里的cnonce为客户端生成的nonce值,而nc用于统计,假设开始时为00000001,下次请求后就变成了00000002,不一定每次都加1,但是后面请求中的nc值肯定大于前一次请求中的nc值。
4:服务端收到请求后将验证nonce是否过期,如果过期,那么直接返回401,即第二步的状态。如果没有过期,那么比较nc值,如果比前一次nc值小或者前一次根本没有存储的nc值,那么也将直接返回401状态。如果前面的验证都通过,那么服务端也将按照步骤3中计算最终HASH值的步骤计算出HASH值与客户端的进行比较,然后比较客户端提交过来的HASH值与服务端计算出来的HASH进行比较,不匹配返回401,匹配获取请求的数据并返回状态200。
摘要验证主要就是通过上面的HASH比较的步骤避免掉了基本验证中的安全性问题。

》》》》 摘要式身份认证 流程
在这里插入图片描述
在这里插入图片描述

HTTP/1.0 401 Unauthorized
Server: HTTPd/0.9
Date: Sun, 10 Apr 2024 20:26:47 GMT
WWW-Authenticate: Digest realm=" 领域",
qop=“auth,auth-int”,
nonce=“dcd98b7102dd2f0e8b11d0f60”,
opaque=“5ccc069c3ebaf9f0171e9517f40e41”

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

需要注意的是,如果需要IIS支持摘要验证,需要把IIS摘要验证的特性勾上=》按照IIS要勾选
在这里插入图片描述

在这里插入图片描述

AuthenticationHandler

 public class AuthenticationHandler : DelegatingHandler{protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken){try{HttpRequestHeaders headers = request.Headers;if (headers.Authorization != null){Header header = new Header(request.Headers.Authorization.Parameter, request.Method.Method);if (Nonce.IsValid(header.Nonce, header.NounceCounter)){// Just assuming password is same as username for the purpose of illustration  string password = header.UserName;string ha1 = String.Format("{0}:{1}:{2}", header.UserName, header.Realm, password).ToMD5Hash();string ha2 = String.Format("{0}:{1}", header.Method, header.Uri).ToMD5Hash();string computedResponse = String.Format("{0}:{1}:{2}:{3}:{4}:{5}",ha1, header.Nonce, header.NounceCounter, header.Cnonce, "auth", ha2).ToMD5Hash();if (String.CompareOrdinal(header.Response, computedResponse) == 0){// digest computed matches the value sent by client in the response field.  // Looks like an authentic client! Create a principal.  var claims = new List<Claim>{new Claim(ClaimTypes.Name, header.UserName),new Claim(ClaimTypes.AuthenticationMethod, AuthenticationMethods.Password)};ClaimsPrincipal principal = new ClaimsPrincipal(new[] { new ClaimsIdentity(claims, "Digest") });Thread.CurrentPrincipal = principal;if (HttpContext.Current != null)HttpContext.Current.User = principal;}}}HttpResponseMessage response = await base.SendAsync(request, cancellationToken);if (response.StatusCode == HttpStatusCode.Unauthorized){response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue("Digest", Header.UnauthorizedResponseHeader.ToString()));}return response;}catch (Exception){var response = request.CreateResponse(HttpStatusCode.Unauthorized);response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue("Digest", Header.UnauthorizedResponseHeader.ToString()));return response;}}}

在这里插入图片描述

HashHelper

 public static class HashHelper{public static string ToMD5Hash(this byte[] bytes){StringBuilder hash = new StringBuilder();MD5 md5 = MD5.Create();md5.ComputeHash(bytes).ToList().ForEach(b => hash.AppendFormat("{0:x2}", b));return hash.ToString();}public static string ToMD5Hash(this string inputString){return Encoding.UTF8.GetBytes(inputString).ToMD5Hash();}}

Header

 public class Header{public Header() { }public Header(string header, string method){string keyValuePairs = header.Replace("\"", String.Empty);foreach (string keyValuePair in keyValuePairs.Split(',')){int index = keyValuePair.IndexOf("=");string key = keyValuePair.Substring(0, index);string value = keyValuePair.Substring(index + 1);switch (key){case "username": this.UserName = value; break;case "realm": this.Realm = value; break;case "nonce": this.Nonce = value; break;case "uri": this.Uri = value; break;case "nc": this.NounceCounter = value; break;case "cnonce": this.Cnonce = value; break;case "response": this.Response = value; break;case "method": this.Method = value; break;}}if (String.IsNullOrEmpty(this.Method))this.Method = method;}public string Cnonce { get; private set; }public string Nonce { get; private set; }public string Realm { get; private set; }public string UserName { get; private set; }public string Uri { get; private set; }public string Response { get; private set; }public string Method { get; private set; }public string NounceCounter { get; private set; }// This property is used by the handler to generate a// nonce and get it ready to be packaged in the// WWW-Authenticate header, as part of 401 responsepublic static Header UnauthorizedResponseHeader{get{return new Header(){Realm = "RealmOfBadri",Nonce = WebApplication9.Nonce.Generate()};}}public override string ToString(){StringBuilder header = new StringBuilder();header.AppendFormat("realm=\"{0}\"", Realm);header.AppendFormat(", nonce=\"{0}\"", Nonce);header.AppendFormat(", qop=\"{0}\"", "auth");return header.ToString();}}

》》nonce

  public class Nonce{private static ConcurrentDictionary<string, Tuple<int, DateTime>>nonces = new ConcurrentDictionary<string, Tuple<int, DateTime>>();public static string Generate(){byte[] bytes = new byte[16];using (var rngProvider = new RNGCryptoServiceProvider()){rngProvider.GetBytes(bytes);}string nonce = bytes.ToMD5Hash();nonces.TryAdd(nonce, new Tuple<int, DateTime>(0, DateTime.Now.AddMinutes(10)));return nonce;}public static bool IsValid(string nonce, string nonceCount){Tuple<int, DateTime> cachedNonce = null;nonces.TryGetValue(nonce, out cachedNonce);if (cachedNonce != null) // nonce is found{// nonce count is greater than the one in recordif (Int32.Parse(nonceCount) > cachedNonce.Item1){// nonce has not expired yetif (cachedNonce.Item2 > DateTime.Now){// update the dictionary to reflect the nonce count just received in this requestnonces[nonce] = new Tuple<int, DateTime>(Int32.Parse(nonceCount),cachedNonce.Item2);// Every thing looks ok - server nonce is fresh and nonce count seems to be // incremented. Does not look like replay.return true;}}}return false;}}

webapi Http基本认证 Basic

在这里插入图片描述

在这里插入图片描述
客户端向服务端发送一个携带基于用户名/密码的认证凭证的请求。认证凭证的格式为“{UserName}:{Password}”,并采用Base64编码,经过编码的认证凭证被存放在请求报头Authorization中,Authorization报头值类似:Basic MTIzNDU2OjEyMzQ1Ng==。服务端接收到请求之后,从Authorization报头中提取凭证并对其进行解码,最后采用提取的用户名和密码实施认证。认证成功之后,该请求会得到正常的处理,并回复一个正常的响应。

注:其实basic 的参数传输方式还是一种不错的数据传输加密方式哦,多采用这种前后端数据交互方式的项目颇多,只是一般与https一起使用。更加安全

1、Convert.FromBase64String这句是解密经过BASE64加密的报文中的Authorization值,然后得到带格式的用户登录数据:{UserName}:{Password}
得到用户userid就可以自定义验证用户合法性了

2、HandleUnauthorizedRequest重写这个方法是为了服务器返回basic认证的格式,即前台弹出的那个登录框,
而BASE64加密及报文传输这不能算是basic认证特有,我们的表单数据传输都可以用这种方式
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
》》》录入正确的账号密码 就可以访问了
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
那是https 是加密传输的。除此之外,内容在客户端和服务端都是明文显示的哦,大家要注意了
https 是最伟大的发明
在这里插入图片描述
在这里插入图片描述
》》》BasicAuthorizeAttribute

public class BasicAuthorizeAttribute: AuthorizeAttribute{protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext){if (actionContext.Request.Method == HttpMethod.Options) return true;if (actionContext.Request.Headers.Authorization != null && actionContext.Request.Headers.Authorization.Parameter != null){var authorizationParameter = Convert.FromBase64String(actionContext.Request.Headers.Authorization.Parameter);var basicArray = Encoding.Default.GetString(authorizationParameter).Split(':');var userid = basicArray[0];var password = basicArray[1];if (userid == "123456" && password == "123456"){return true;}}return false;}protected override void HandleUnauthorizedRequest(HttpActionContext actionContext){var responseMessage = new HttpResponseMessage(HttpStatusCode.Unauthorized);responseMessage.Headers.Add("WWW-Authenticate", "Basic");throw new HttpResponseException(responseMessage);}}

在这里插入图片描述

webapi basic 认证

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
》》 BasicAuthorizeAttribute类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Security;namespace WebApplication10
{/// <summary>/// Basic 验证/// </summary>public class BasicAuthorizeAttribute:AuthorizeAttribute{/// <summary>/// 发生请求签去完成验证,在请求前触发此方法/// </summary>/// <param name="actionContext"></param>public override void OnAuthorization(HttpActionContext actionContext){// 从当前http请求Request对象的头部信息里面获取Authorization属性var authorization = actionContext.Request.Headers.Authorization;// 判断控制器获取action方法上面是否有AllowAnonymousAttribute特性,如果有,则允许匿名登录           if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>(true).Count != 0||actionContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>(true).Count != 0){base.OnAuthorization(actionContext);}else if (authorization != null && authorization.Parameter != "null" && authorization.Parameter != "undefined"){//验证if (ValidateTicket(authorization.Parameter)){base.IsAuthorized(actionContext);}else{// 无权this.HandleUnauthorizedRequest(actionContext);}}else{// 无权this.HandleUnauthorizedRequest(actionContext);}}private bool ValidateTicket(string encrytTicket){if (encrytTicket == "null" || encrytTicket == "undefined"){return false;}//解密Ticketvar strTicket = FormsAuthentication.Decrypt(encrytTicket).UserData;//模拟与数据库匹配return string.Equals(strTicket, string.Format("{0}{1}","zen","11"));}protected override void HandleUnauthorizedRequest(HttpActionContext actionContext){var challengeMessage = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);challengeMessage.Headers.Add("WWW-Authenticate" , "Basic");base.HandleUnauthorizedRequest(actionContext);}protected override bool IsAuthorized(HttpActionContext actionContext){return false;}}
}

在这里插入图片描述
在这里插入图片描述


@{Layout = null;
}<!DOCTYPE html><html>
<head><meta name="viewport" content="width=device-width" /><script src="~/Scripts/jquery-1.10.2.min.js"></script><title>Login</title>
</head><body><div>        <table><tr><td>用户名</td><td><input name="username" id="username" type="text" /></td></tr><tr><td>密码</td><td><input name="password" type="password"  id="password"/></td></tr><tr><td colspan="2"><input type="button" id ="btnlogin" value="登录" /></td><td colspan="2"><input type="button" id="btnlogin1" value="登录2" /></td></tr></table>     </div><script type="text/javascript">$(function () {var ticket = null;$("#btnlogin").on("click", function () {$.ajax({url: "/api/users/Login",type: "get",data: {"username": $("#username").val(),"password": $("#password").val()},dataType: "json",success: function (data) {var result = JSON.parse(data);if (result.Result) {ticket = result.Ticket;alert(ticket)} else {alert("faild");}}     })})$("#btnlogin1").on("click", function () {$.ajax({url: "/api/users/GetInfoByName",type: "GET",data: {"username": $("#username").val()},dataType: "json",beforeSend: function (XHR){XHR.setRequestHeader("Authorization", "BasicAuth " + ticket);},success: function (data) {alert(data)}})})})</script>
</body>
</html>

在这里插入图片描述
在这里插入图片描述
》》users控制器

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Security;
using WebApplication10.Models;namespace WebApplication10.Controllers
{//每增加一个控制器,都需要在相应的控制器上面加[BasicAuthorize]特性,可以定义一个公共的控制器父类,该父类继承自ApiController,然后其他控制器继承该父类。[BasicAuthorize]public class UsersController : ApiController{        private List<Info> _userList = null;public UsersController(){_userList = new List<Info> {new Info { user="ares" , password="123"},new Info { user="zen" , password="123"},};}[AllowAnonymous][HttpGet]public string Login(string username, string password){           //模拟数据库if (username.Equals("zen") && password.Equals("11")){//(int version, string name, DateTime issueDate, DateTime expiration, bool isPersistent, string userData, string cookiePath);FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(0,                                              //版本        versionusername,                                       //用户标识    nameDateTime.Now,                                   // 颁发日期   issueDateDateTime.Now.AddHours(1),                       // 过期日期   expirationtrue,                                           // 是否持久性 isPersistentstring.Format("{0}{1}", username, password),    // 票据字符串 userDataFormsAuthentication.FormsCookiePath             // 存储路径   cookiePath);var result = new { Result = true, Ticket = FormsAuthentication.Encrypt(ticket) };return JsonConvert.SerializeObject(result);}else{var result = new { Result = false };return JsonConvert.SerializeObject(result);}}[HttpGet]public string GetInfoByName(string username){            return JsonConvert.SerializeObject(_userList.Where((s) => s.user == username));}}
}

相关文章:

  • 型号FM152A,FM148R和利时
  • 【软件工程】第七章
  • Flink⼤状态作业调优实践指南:状态报错与启停慢篇
  • 中缀表达式和前缀后缀
  • “安全生产月”专题报道:AI智能监控技术如何助力安全生产
  • C/C++ 引用和指针的区别及使用场景
  • QT中将资源文件(image、qss、qm等)封装到静态库中,程序该如何引用静态库中的资源文件
  • mysql8 .net sqlsuger 批量插入dbScope.Fastest<T>().PageSize(2000).BulkCopy(T)>
  • Elasticsearch 认证模拟题 - 10
  • 【ARM Cache 与 MMU 系列文章 7.7 – ARMv8/v9 MMU Table 表分配原理及其代码实现 1】
  • 什么叫防御式编程
  • 写入文件内容
  • 软件架构x86 、 x86_64、 arm64、aarch64
  • 【MySQL数据库】my.ini文件参数中文注释
  • 大疆智图_空三二维重建成果传输
  • 网络传输文件的问题
  • 4. 路由到控制器 - Laravel从零开始教程
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • HTML5新特性总结
  • Javascript基础之Array数组API
  • JavaScript新鲜事·第5期
  • MySQL Access denied for user 'root'@'localhost' 解决方法
  • Node项目之评分系统(二)- 数据库设计
  • WebSocket使用
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 力扣(LeetCode)22
  • 盘点那些不知名却常用的 Git 操作
  • 前端
  • 入口文件开始,分析Vue源码实现
  • 思维导图—你不知道的JavaScript中卷
  • 为什么要用IPython/Jupyter?
  • 为视图添加丝滑的水波纹
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • 阿里云移动端播放器高级功能介绍
  • 如何在招聘中考核.NET架构师
  • ​【经验分享】微机原理、指令判断、判断指令是否正确判断指令是否正确​
  • (2)STL算法之元素计数
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (CPU/GPU)粒子继承贴图颜色发射
  • (void) (_x == _y)的作用
  • (备份) esp32 GPIO
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (多级缓存)缓存同步
  • (二十三)Flask之高频面试点
  • (离散数学)逻辑连接词
  • (每日一问)计算机网络:浏览器输入一个地址到跳出网页这个过程中发生了哪些事情?(废话少说版)
  • (一)基于IDEA的JAVA基础12
  • (转载)PyTorch代码规范最佳实践和样式指南
  • (最简单,详细,直接上手)uniapp/vue中英文多语言切换
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • .htaccess 强制https 单独排除某个目录
  • .NET Core 和 .NET Framework 中的 MEF2
  • .Net Core 生成管理员权限的应用程序