[Asp.Net web api]基於自定義Filter的安全認證

摘要

對第三方開放的接口,處於安全的考慮須要對其進行安全認證,是不是合法的請求。目前在項目中也遇到這種狀況,提供的接口由於涉及到客戶銘感數據,因此在調用的時候,不能直接暴露,須要有一個認證的機制。因此對接口安全認證的方式,進行了調研,這裏提供一個自定義安全認證的Filter例子。web

一個例子

在mvc中,若是須要對某個頁面若是用戶不登陸則沒法訪問,咱們的作法多是校驗session或者使用特性[Authorize]windows

    [Authorize]
    public class UserController : Controller
    {
        // GET: User
        public ActionResult Index()
        {
            //if (Session["user"]==null)
            //{
            //    return RedirectToAction("login");
            //}
            return View();
        }
    }

在mvc中,這種認證方式基於windows或者form認證。但在提供web api給移動端app調用的時候,windows或者form認證就不太合適了。但咱們能夠自定義一種filter對當前訪問的用戶進行認證。api

自定義Filter特性安全

    /// <summary>
    /// 基於http basic認證
    /// </summary>
    public class CustomerBasicAuthrizeAttribute : AuthorizationFilterAttribute
    {
        //重寫OnAuthorization 方法

        public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            //若是action帶有容許匿名訪問的特性,則直接返回,再也不進行安全認證
            if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any())
            {
                return;
            }
            if (actionContext.Request.Headers.Authorization != null)
            {
                if (actionContext.Request.Headers.Authorization.Scheme != "Basic")
                {
                    actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized,
                        new HttpException("no token"));
                }
                else
                {
                    string base64Para = actionContext.Request.Headers.Authorization.Parameter;
                    //解碼base64字符串
                    byte[] buffer = Convert.FromBase64String(base64Para);
                    string decodeBase64 = Encoding.UTF8.GetString(buffer);
                    if (!string.IsNullOrEmpty(decodeBase64))
                    {
                        string[] paras = decodeBase64.Split(':');
                        if (paras.Length > 0)
                        {
                            string userName = paras[0];
                            string pwd = paras[1];
                            if (userName == "wolfy" && pwd == "123456")
                            {
                            }
                            else
                            {
                                actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized,
                                    new HttpException("userName or pwd is error."));
                            }
                        }
                        else
                        {
                            actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized,
                                new HttpException("no token"));
                        }

                    }
                    else
                    {
                        actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized,
                            new HttpException("no token"));
                    }
                }

            }
            else
            {
                actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized,
                    new HttpException("no Authorization header"));
            }

            base.OnAuthorization(actionContext);
        }
    }

使用postman測試session

認證成功mvc

第三方調用的時候,能夠爲其生成一對appname和appsecret放在供客戶端進行使用。客戶端使用的時候在請求頭的Authorization中添加base64字符串就能夠了。對於basic對應的值,是base64字符串,若是感受還不安全能夠嘗試使用SSL方式。app

SSL協議詳解

相關文章
相關標籤/搜索