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);
                //创建一个Cookie
                HttpCookie 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: Account
        public 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 response
        public 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 record
                if (Int32.Parse(nonceCount) > cachedNonce.Item1)
                {
                    // nonce has not expired yet
                    if (cachedNonce.Item2 > DateTime.Now)
                    {
                        // update the dictionary to reflect the nonce count just received in this request
                        nonces[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 认证

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/684851.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

windows11 安装cnpm 报错 Error: EPERM: operation not permitted 没权限

全部试过&#xff1a; 您遇到的错误是EPERM: operation not permitted&#xff0c;这意味着npm在尝试重命名文件或目录时缺少必要的权限。这通常与操作系统的权限设置有关。为了解决这个问题&#xff0c;您可以尝试以下几个步骤&#xff1a; 以管理员身份运行命令行&#xff1…

Python 可变长参数的魔法:灵活函数设计的秘密

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 什么是可变长参数&#xff1f; 在 Python 中&#xff0c;可变长参数允许你向函数传入任意数量的参数&#xff0c;而无需预先定义它们的个数。这为编写更加灵活和通用的函数提供了可能。可变长参数主要有两种形式&am…

使用kafka tools工具连接带有用户名密码的kafka

使用kafka tools工具连接带有用户名密码的kafka 创建kafka连接&#xff0c;配置zookeeper 在Security选择Type类型为SASL Plaintext 在Advanced页面添加如下图红框框住的内容 在JAAS_Config加上如下配置 需要加的配置&#xff1a; org.apache.kafka.common.security.plain.Pla…

如何通过内容识别关键词保护商业机密防泄漏

在数字化商业环境中&#xff0c;商业机密的保护对于企业的竞争力至关重要。随着数据泄露事件的增多&#xff0c;企业越来越需要采取有效措施来保护其敏感信息。内容识别技术&#xff0c;特别是关键词识别&#xff0c;已成为防止商业机密泄漏的重要手段。本文将探讨如何利用这一…

微软新AI工具 Recall 被白帽公开锤了?

近日&#xff0c;一些网络安全研究人员演示了恶意软件是如何成功窃取 Windows Recall 工具收集到的数据。 2024年5月21日&#xff0c;微软发布全新的“CopilotPC”&#xff0c;这类 AI PC 通过与高通的最新芯片合作&#xff0c;实现了一个叫做“Recall”的功能。借助这个人工智…

性能监控工具

性能是任何一款软件都需要关注的重要指标。除了软件的基本功 能&#xff0c;性能可以说是评价软件优劣的最重要的指标之一。我们该如何有 效地监控和诊断性能问题呢?本章基于实践&#xff0c;着重介绍一些针对系统 和Java虚拟机的监控和诊断工具&#xff0c;以帮助读者在实际开…

Camtasia Studio2024破解汉化版crack安装包下载地址

在当今数字化时代&#xff0c;视频内容已成为传播信息和吸引观众的重要方式。无论是企业宣传、在线教育还是个人创作&#xff0c;一款功能强大的视频编辑软件都是必不可少的工具。而Camtasia Studio2024作为业界领先的视频编辑软件&#xff0c;其永久免费版及最新版本的功能更是…

四、 【源码】数据源的解析、创建和使用

源码地址&#xff1a;https://github.com/mybatis/mybatis-3/ 仓库地址&#xff1a;https://gitcode.net/qq_42665745/mybatis/-/tree/04-datasource-use 数据源的解析、创建和使用 流程&#xff1a; 1.Resources加载MyBatis配置文件生成Reader字符流 2.SqlSessionFactory…

【JMeter接口测试工具】第二节.JMeter基本功能介绍(上)【入门篇】

文章目录 前言一、获取所有学院信息接口执行二、线程组的介绍 2.1 并发和顺序执行 2.2 优先和最后执行线程组 2.3 线程组的设置细节三、HTTP请求的介绍四、查看结果树的配置使用总结 前言 一、获取所有学院信息接口执行 我们先针对一条简单的接口进行执行&#…

NodeJS体育用品销售管理系统-计算机毕业设计源码88807

摘 要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&#xff0c;科学化的管理&#xff0c;使信息存…

概率分析和随机算法

目录 雇佣问题 概率分析 随机算法 生日悖论 随机算法 概率分析 球与箱子 总结 雇佣问题 有n个候选人面试&#xff0c;如果面试者比目前雇佣者的分数高&#xff0c;评价更好&#xff0c;那么就辞掉当前雇佣者&#xff0c;而去聘用面试者&#xff0c;否则继续面试新的候…

浮点数的精度和精度丢失,如何规避,有简单操作

在日常工作中&#xff0c;如果做财务软件相关肯定会遇到这种问题&#xff0c;凭证金额表面上看是相等的&#xff0c;但程序运算出的结果却是FALSE。 例如&#xff1a;验证凭证金额借方总金额是否等于贷方总金额&#xff1f; 直接sum&#xff08;借方分录金额1.1借方分录金额2.…

inflight 守恒拥塞控制的稳定性

只要系统形成 E_best max(bw / delay) 共识&#xff0c;系统就是稳定的。 设两条流 f1&#xff0c;f2 共享瓶颈链路&#xff0c;用 cwnd 约束 inflight&#xff0c;其 cwnd 分别为 x&#xff0c;y&#xff0c;用简单的微分方程建模&#xff1a; d x d t c − b ∗ x − a ∗…

使用python把gif转为图片

使用python把gif转为图片 程序思路效果代码 程序思路 打开 GIF 文件。确保输出文件夹存在&#xff0c;如果不存在则创建。获取 GIF 的帧数。遍历每一帧&#xff0c;将其保存为单独的 PNG 图像&#xff0c;并打印保存路径。 效果 把这张派大星gif转为一张张图片&#xff1a; …

黑马python-JavaScript

1.JavaScript的定义&#xff1a; JavaScript是运行在浏览器端的脚步语言&#xff0c;是由浏览器解释执行的、简称js。它能够让网页和用户有交互功能&#xff0c;增加良好的用户体验效果 2.使用方式&#xff1a; 1.行内式&#xff08;主要用于事件&#xff09; <input type&q…

国产开发板——香橙派Kunpeng Pro的上手初体验

开发板&#xff08;Development Board&#xff09;是一种特殊的电子产品&#xff0c;它的主要目的是为了帮助开发者快速地设计、测试和验证电子产品的硬件和软件设计。开发板通常提供了一个完整的硬件平台&#xff0c;包括微控制器、存储器、接口和其他外围设备&#xff0c;开发…

程序员职业素养:AI新时代下的机遇与挑战

目录 一、引言二、程序员职业素养的五大要点1. 技术能力2. 沟通能力3. 团队合作4. 责任心5. 敬业精神 三、实际案例解析四、程序员职业素养在实际工作中的应用五、AI新时代的程序员的职业发展建议六、总结七、结语 一、引言 在当今这个科技飞速发展的时代&#xff0c;程序员这…

解决在Windows11上新安装的Docker Desktop一直显示“starting the Docker Engine“登录不上去的问题

解决在Windows11上新安装的Docker Desktop一直显示“starting the Docker Engine“登录不上去的问题 管理员权限运行cmd 还需要安装wsl(适用于Linux的Windows子系统)。注意windows powershell也要以管理员权限打开 这个是小羊用错窗口了&#xff0c;but好像也没错吧&#xff…

excel拖拽怎么使单元格序号不递增

拖拽下来不仅不递增&#xff0c;而且右下角没有倒三角可以设置改变&#xff0c;&#xff08;即没有下图这个&#xff09; 则&#xff0c;可以采用以下方法 excel数值拖拽不递增还有一个更快更快捷的方法&#xff0c;这就运用到了excel快捷键&#xff0c;我们把鼠标放到单元格的…

集成学习笔记

集成学习 简介 决策树 GBDT 拟合残差 一般 GBDT XGBOOST 弓 1 能表达样本落入的子节点&#xff0c;但是不能把表示结构 2 3.正则项 – 惩罚 防止过拟合&#xff0c;比如一个值总共有10颗树都是由同一颗树决定的&#xff0c;过拟合 5 找到一种方式不依赖于损失函数 …