这位怪蜀黍 中午的时光真难熬!还好有你在!

WebApi Basic基础身份认证

 

一:为什么需要身份认证

没有身份认证,匿名用户只要知道了我们服务的url,就能随意访问接口

 

 

增加了身份认证后,只有拿到票据的请求才能访问接口

 

 

 

下面是代码示例

 

WEB前端

  登录API接口

 Home/Index.aspx界面

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace SW163WebClient.Admin
{
    /// <summary>
    /// 2022-6-1 小金
    /// </summary>
    public partial class Index: System.Web.UI.Page
    {
        public SW163UI.BasePage bg = new SW163UI.BasePage();
        public string UserName = string.Empty;
        public string Ticket = string.Empty;
        public int first = 1;
        protected void Page_Load(object sender, EventArgs e)
        {
            HttpCookie myCookie = HttpContext.Current.Request.Cookies["Web"];
            if (bg.CookieYESNo()) { Response.Redirect("Login.aspx"); }
            else
            {
                if (myCookie["UserName"] != null && myCookie["Ticket"] != null && myCookie["date"] != null)
                {
                    UserName = myCookie["UserName"];
                    Ticket = myCookie["Ticket"];
                    //第一次登录时间和当前时间对比,大于30分钟清除cookie;
                    DateTime time = Convert.ToDateTime(myCookie["date"]);
                    DateTime time1 = DateTime.Now;
                    TimeSpan timeSpan = time1 - time;
                    if (timeSpan.TotalMinutes >= 30)
                    {
                        UserName = "";
                        Ticket = "";
                        bg.ExitCookie();

                    }
                    else
                    {
                        //当前时间大于第一次登录时间1分钟,非第一次登录
                        if (Convert.ToDateTime(time1.ToString("yyyy-MM-dd HH:mm")) > Convert.ToDateTime(time.ToString("yyyy-MM-dd HH:mm")))
                        {
                            first = 2;
                            myCookie["Ticket"] = "2";
                        }


                    }
                }
                else
                {
                    bg.ExitCookie();
                    Response.Redirect("Login.aspx");
                }
            }
        }

        //退出登录
        protected void lbtnExit_Click(object sender, EventArgs e)
        {
            bg.ExitCookie();
        }
    }
}
复制代码
复制代码
<head>
    <meta charset="utf-8">
    <script type="text/javascript" src="js/jquery.min.js"></script>
     <script type="text/javascript">
         //打开页面的时候保存票据信息
         var UserName ="<%=UserName %>";
         var Ticket = "<%=Ticket%>";
         var first =<%=first%>;
     </script>
</head>

复制代码
复制代码
 <script>
        $(function () {
            $.ajax({
                type: "get",
                url: "/api/Charging/GetAllChargingData",
                data: {},
                beforeSend: function (XHR) {
                    //发送ajax请求之前向http的head里面加入验证信息
                    XHR.setRequestHeader('Authorization', 'BasicAuth ' + Ticket);
                },
                success: function (data, status) {
                    if (status == "success") {
                        if (first==1) {
                            layer.alert(UserName + ":欢迎回家!");
                        }
                    }
                },
                error: function (e) {

                     layer.alert("认证信息已过期!请重新登录", function () {
                        //清除kooie
                         $.ajax({
                             type: "post",
                             url: "/Tools/Login.ashx",
                             data: { "act":"clean_up"},
                             success: function (result)
                             {
                                 window.location.href = "Login.aspx";
                             }
                         })
                       
                    });
                },
                complete: function () {

                }

            });
        });

    </script>
复制代码

WebAPI项目里面自定义一个类RequestAuthorizeAttribute,去继承AuthorizeAttribute这个类。然后重写OnAuthorization方法,在这个方法里面取到请求头的Ticket信息,再效验用户名和密码是否正确

复制代码
/// <summary>
    /// ==========2022-6-1(小金)===============
    /// 自定义此特性用于接口的身份验证
    /// </summary>
    public class RequestAuthorizeAttribute : AuthorizeAttribute
    {
        //重写基类的验证方式,加入我们自定义的Ticket验证
        public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            //从http请求的头里面获取身份验证信息,验证是否是请求发起方的ticket
            var authorization = actionContext.Request.Headers.Authorization;
            if ((authorization != null) && (authorization.Parameter != null))
            {
                //解密用户ticket,并校验用户名密码是否匹配
                var encryptTicket = authorization.Parameter;
                if (ValidateTicket(encryptTicket))
                {
                    base.IsAuthorized(actionContext);
                }
                else
                {
                    HandleUnauthorizedRequest(actionContext);
                }
            }
            //如果取不到身份验证信息,并且不允许匿名访问,则返回未验证401
            else
            {
                var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
                bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute);
                if (isAnonymous) base.OnAuthorization(actionContext);
                else HandleUnauthorizedRequest(actionContext);
            }
        }

        //校验用户名密码
        private bool ValidateTicket(string encryptTicket)
        {
            //解密Ticket
            var strTicket = FormsAuthentication.Decrypt(encryptTicket).UserData;

            //从Ticket里面获取用户名和密码
            var index = strTicket.IndexOf("&");
            string strUser = strTicket.Substring(0, index);
            string strPwd = strTicket.Substring(index + 1);

            SW163BLL.Administrators blladmin = new SW163BLL.Administrators();
            DataTable dt = blladmin.GetList("UserName='" + strUser + "' and PassWord='" + SW163Common.DESEncrypt.Encrypt(strPwd) + "'").Tables[0];
            if (dt.Rows.Count > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

复制代码

在具体的Api接口增加我们上面定义的自定义特性

复制代码
/// <summary>
    /// ==========2022-6-1(小金)===============
    /// </summary>
    public class ChargingController : BaseApiController
    {
        /// <summary>
        /// 得到所有数据
        /// </summary>
        /// <returns>返回数据</returns>
        [HttpGet,Route("api/Charging/GetAllChargingData")]
        public string GetAllChargingData()
        {
            return "Success";
        }

        /// <summary>
        /// 得到当前Id的所有数据
        /// </summary>
        /// <param name="id">参数Id</param>
        /// <returns>返回数据</returns>
        [HttpGet, Route("api/Charging/GetAllChargingData")]
        public string GetAllChargingData(string id)
        {
            return "ChargingData" + id;
        }
    }

复制代码

在API添加身份认证公共父类,子类只需继承父类认证即可

复制代码
/// <summary>
    /// API 身份认证公共父类
    /// 
    /// ==========2022-6-1(小金)===============
    /// 
    /// origins配置允许访问的域名,多个域名以逗号分隔即可,域名一定要完整,
    /// 如果是ip地址前面要加上“http”,只使用IP的话一定会失效的。
    /// 参数headers配置所支持的资源。
    /// 参数methods配置支持的方法,get、post、put等。
    /// 如果允许任意域名、任意资源、任意方法访问自己的webapi,则三个参数全部使用星号”*”即可
    /// </summary>
    [RequestAuthorize]
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    public class BaseApiController : ApiController
    {
    }

复制代码

 

 

本文转自:https://www.cnblogs.com/landeanfen/p/5287064.html

 

posted @   蟾宝  阅读(160)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示