• 3、Web Api 身份验证


     由于接口传递的是企业内部数据,在数据安全性方面需要把控,因此当客户端调用接口时,必须提供身份标识,验证通过之后方可调用接口,以确保数据的安全性。由于WebApi的身份校验是面向切面编程的,即当你需要进行身份校验时,执行逻辑为:Client->Filter身份校验->接口,当校验通过时,即可正常调用

    当校验不通过时,将返回401身份验证失败。

    一、身份校验 Basic

    1、在Api项目下创建Filter文件夹

    2、编写验证程序

    using System;
    using System.Net;
    using System.Net.Http;
    using System.Security.Principal;
    using System.Text;
    using System.Threading;
    using System.Web.Http.Filters;
    
    namespace SCM.API
    {
        public class APIAuthorizeAttribute :AuthorizationFilterAttribute
        {
            public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
            {
                base.OnAuthorization(actionContext);
    
                if (Thread.CurrentPrincipal.Identity.IsAuthenticated)
                {
                    return;
                }
    
                var authHeader = actionContext.Request.Headers.Authorization;
    
                if (authHeader != null)
                {
                    if (authHeader.Scheme.Equals("basic", StringComparison.OrdinalIgnoreCase) && !String.IsNullOrWhiteSpace(authHeader.Parameter))
                    {
                        var credArrar = GetCredentials(authHeader);
                        var userName = credArrar[0];
                        var key = credArrar[1];
                        string ip = System.Web.HttpContext.Current.Request.UserHostAddress;
                        if (1 == 1) //!IsresourceOwner(userName, actionContext)
                        {
                            if (APIAuthorizeInfoValidate.ValidateApi(userName, key))
                            {
                                var currentPrincipal = new GenericPrincipal(new GenericIdentity(userName), null);
                                Thread.CurrentPrincipal = currentPrincipal;
                                return;
                            }
                        }
                    }
                }
                HandleUnauthorizeRequest(actionContext);
            }
    
            private string[] GetCredentials(System.Net.Http.Headers.AuthenticationHeaderValue authHeader)
            {
                //Base 64 encoded string
                var rawCred = authHeader.Parameter;
                var encoding = Encoding.GetEncoding("iso-8859-1");
                var cred = encoding.GetString(Convert.FromBase64String(rawCred));
    
                var credArray = cred.Split(':');
                return credArray;
            }
    
            private bool IsresourceOwner(string username, System.Web.Http.Controllers.HttpActionContext actionContext)
            {
                var routeData = actionContext.Request.GetRouteData();
                var resourceUsername = routeData.Values["username"] as string;
    
                if (resourceUsername == username)
                {
                    return true;
                }
                return false;
            }
    
            private void HandleUnauthorizeRequest(System.Web.Http.Controllers.HttpActionContext ActionContext)
            {
                
                ActionContext.Response = ActionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
                ActionContext.Response.Headers.Add("WWW-Authenticate", "Basic Scheme='eLearning' location='http://192.168.60.31:81/help'");
            }
        }
    }
    View Code APIAuthorizeAttribute
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Web;
    using Newtonsoft.Json;
    using SCM.API.Common;
    using System.Data.OracleClient;
    
    namespace SCM.API
    {
        public class APIAuthorizeInfo
        {
            public string api_usr_user { get; set; }
            public string api_key { get; set; }
        }
    
        public class APIAuthorizeInfoValidate
        {
            [DllImport("Iphlpapi.dll")]
    
            static extern int SendARP(Int32 DestIP, Int32 SrcIP, ref Int64 MacAddr, ref Int32 PhyAddrLen);
            [DllImport("Ws2_32.dll")]
    
            static extern Int32 inet_addr(string ipaddr);
    
            /// <summary>
            /// 身份验证:用户、口令、IP、MAC
            /// </summary>
            /// <param name="username">用户名</param>
            /// <param name="key">口令</param>
            /// <param name="ip">IP</param>
            /// <param name="mac">MAC</param>
            /// <returns></returns>
            public static bool ValidateApi(string username, string key)
            {
                string ip = APIAuthorizeInfoValidate.GetWebClientIp();   //获取用户IP
                string mac = APIAuthorizeInfoValidate.GetMacAddress(ip);   //获取用户MAC地址
                WebConfigHelper con = new WebConfigHelper();
                var _APIAuthorizeInfo = JsonConvert.DeserializeObject<List<APIAuthorizeInfo>>(WebConfigHelper.ApiAuthorize);
                var ips = WebConfigHelper.IPs.Contains(",") ? WebConfigHelper.IPs.Split(',') : new string[] { WebConfigHelper.IPs };
                var macs = WebConfigHelper.Macs.Contains(",") ? WebConfigHelper.Macs.Split(',') : new string[] { WebConfigHelper.Macs };
                if (_APIAuthorizeInfo != null && _APIAuthorizeInfo.Count > 0)
                {
                    foreach (var v in _APIAuthorizeInfo)
                    {
                      //  if ( v.api_usr_user == username && v.api_key == key && ips.Contains(ip) && macs.Contains(mac) )
                        if (v.api_usr_user == username && v.api_key == key )
                        {
                            string sql = @"update api_mstr set api_rmks = :api_rmks where API_USR_USER = :API_USR_USER";
                            OracleParameter[] pars = {
                                                         new OracleParameter("api_rmks",OracleType.VarChar),
                                                         new OracleParameter("API_USR_USER",OracleType.VarChar)
                                                     };
                            pars[0].Value = ip;
                            pars[1].Value = v.api_usr_user;
                            int i = OracleHelper.ExecuteSql(sql,pars);
                            return true;
                        }
                    }
                }
                return false;
            }
    
            /// <summary>
            /// 身份验证:用户、口令、IP
            /// </summary>
            /// <param name="username"></param>
            /// <param name="key"></param>
            /// <param name="ip"></param>
            /// <returns></returns>
            public static bool ValidateApi(string username, string key, string ip)
            {
                ip = GetWebClientIp(); //获取用户内部IP
                WebConfigHelper con = new WebConfigHelper();
                var _APIAuthorizeInfo = JsonConvert.DeserializeObject<List<APIAuthorizeInfo>>(WebConfigHelper.ApiAuthorize);
                var ips = WebConfigHelper.IPs.Contains(",") ? WebConfigHelper.IPs.Split(',') : new string[] { WebConfigHelper.IPs };
                if (_APIAuthorizeInfo != null && _APIAuthorizeInfo.Count > 0)
                {
                    foreach (var v in _APIAuthorizeInfo)
                    {
                        if (v.api_usr_user == username && v.api_key == key && ips.Contains(ip))
                        {
                            return true;
                        }
                    }
                }
                return false;
            }
    
            ///<summary>  
            /// SendArp获取MAC地址  
            ///</summary>  
            ///<param name="RemoteIP">目标机器的IP地址如(192.168.1.1)</param>  
            ///<returns>目标机器的mac 地址</returns>  
            public static string GetMacAddress(string RemoteIP)
            {
    
                StringBuilder macAddress = new StringBuilder();
    
                try
                {
                    Int32 remote = inet_addr(RemoteIP);
                    Int64 macInfo = new Int64();
                    Int32 length = 6;
                    SendARP(remote, 0, ref macInfo, ref length);
                    string temp = Convert.ToString(macInfo, 16).PadLeft(12, '0').ToUpper();
                    int x = 12;
                    for (int i = 0; i < 6; i++)
                    {
                        if (i == 5)
                        {
                            macAddress.Append(temp.Substring(x - 2, 2));
                        }
                        else
                        {
                            macAddress.Append(temp.Substring(x - 2, 2) + "-");
                        }
    
                        x -= 2;
                    }
                    return macAddress.ToString();
                }
                catch
                {
                    return macAddress.ToString();
                }
            }
    
            /// <summary>
            /// 获取用户IP
            /// </summary>
            /// <returns></returns>
            public static string GetWebClientIp()
            {
                string userIP = "";
    
                try
                {
                    if (System.Web.HttpContext.Current == null
                || System.Web.HttpContext.Current.Request == null
                || System.Web.HttpContext.Current.Request.ServerVariables == null)
                        return "";
    
                    string CustomerIP = "";
    
                    //CDN加速后取到的IP   
                    CustomerIP = System.Web.HttpContext.Current.Request.Headers["Cdn-Src-Ip"];
                    if (!string.IsNullOrEmpty(CustomerIP))
                    {
                        return CustomerIP;
                    }
    
                    CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
    
    
                    if (!String.IsNullOrEmpty(CustomerIP))
                        return CustomerIP;
    
                    if (System.Web.HttpContext.Current.Request.ServerVariables["HTTP_VIA"] != null)
                    {
                        CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                        if (CustomerIP == null)
                            CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
                    }
                    else
                    {
                        CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
    
                    }
    
                    if (string.Compare(CustomerIP, "unknown", true) == 0)
                        return System.Web.HttpContext.Current.Request.UserHostAddress;
                    return CustomerIP;
                }
                catch { }
    
                return userIP;
            }
    
            public static string GetWebClientIp1()
            {
                try
                {
                    string result = String.Empty;
                    result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                    if (result != null && result != String.Empty)
                    {
                        //可能有代理
                        if (result.IndexOf(".") == -1)    //没有“.”肯定是非IPv4格式
                            result = null;
                        else
                        {
                            if (result.IndexOf(",") != -1)
                            {
                                //有“,”,估计多个代理。取第一个不是内网的IP。
                                result = result.Replace(" ", "").Replace("'", "");
                                string[] temparyip = result.Split(",;".ToCharArray());
                                for (int i = 0; i < temparyip.Length; i++)
                                {
                                    if (IsIPAddress(temparyip[i])
                                        && temparyip[i].Substring(0, 3) != "10."
                                        && temparyip[i].Substring(0, 7) != "192.168"
                                        && temparyip[i].Substring(0, 7) != "172.16.")
                                    {
                                        return temparyip[i];    //找到不是内网的地址
                                    }
                                }
                            }
                            else if (IsIPAddress(result)) //代理即是IP格式 ,IsIPAddress判断是否是IP的方法,
                                return result;
                            else
                                result = null;    //代理中的内容 非IP,取IP
                        }
    
                    }
    
                    string IpAddress = (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null && HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != String.Empty) ? HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] : HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
    
                    if (null == result || result == String.Empty)
                        result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
    
                    if (result == null || result == String.Empty)
                        result = HttpContext.Current.Request.UserHostAddress;
    
                    return result;
                }
                catch 
                {
                    return null;
                }
            }
    
    
            #region bool IsIPAddress(str1) 判断是否是IP格式
            /**/
            /// <summary>  
            /// 判断是否是IP地址格式 0.0.0.0  
            /// </summary>  
            /// <param name="str1">待判断的IP地址</param>  
            /// <returns>true or false</returns>  
            public static bool IsIPAddress(string str1)
            {
                if (str1 == null || str1 == string.Empty || str1.Length < 7 || str1.Length > 15) return false;
                string regformat = @"^d{1,3}[.]d{1,3}[.]d{1,3}[.]d{1,3}$";
                Regex regex = new Regex(regformat, RegexOptions.IgnoreCase);
                return regex.IsMatch(str1);
            }
            #endregion
        }
    }
    View Code APIAuthorizeInfoValidate
    using System.Data;
    using System.Data.OracleClient;
    
    namespace SCM.API.Common
    {
        public class WebConfigHelper
        {
            public static string ApiAuthorize { get; set; }
            public static string IPs { get; set; }
            public static string Macs { get; set; }
    
            public WebConfigHelper()
            {
                string sql = @"select * from api_mstr";
                using (OracleConnection conn = new OracleConnection(GetConnString.ConnectionString))
                {
                    conn.Open();
                    OracleCommand cmd = new OracleCommand(sql, conn);
                    OracleDataAdapter myda = new OracleDataAdapter(cmd);
                    DataTable dt = new DataTable();
                    myda.Fill(dt);
                    ApiAuthorize = "[";
                    for (int i = 0; i <= dt.Rows.Count - 1; i++)
                    {
                        ApiAuthorize += "{api_usr_user :'" + dt.Rows[i]["api_usr_user"].ToString()+"',";
                        ApiAuthorize += "api_key :'" + dt.Rows[i]["api_key"].ToString() + "'},";
                        IPs += dt.Rows[i]["api_ip"].ToString() + ",";
                        Macs += dt.Rows[i]["api_mac"].ToString() + ",";
                    }
                    IPs = IPs.Substring(0, IPs.Length - 1);
                    Macs = Macs.Substring(0, Macs.Length - 1);
                    ApiAuthorize = ApiAuthorize.Substring(0, ApiAuthorize.Length - 1);
                    ApiAuthorize += "]";
                    myda.Dispose();
                }
            }
        }
    }
    View Code WebConfigHelper

    配置全局变量

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Http;
    using System.Web.Mvc;
    using System.Web.Optimization;
    using System.Web.Routing;
    
    namespace SCM.API
    {
        // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明,
        // 请访问 http://go.microsoft.com/?LinkId=9394801
    
        public class WebApiApplication : System.Web.HttpApplication
        {
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
    
                WebApiConfig.Register(GlobalConfiguration.Configuration);
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);
                
                HandlerConfig.RegisterHandlers(GlobalConfiguration.Configuration.MessageHandlers);
                // 使api返回为json 
                GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
                GlobalConfiguration.Configuration.Filters.Add(new APIAuthorizeAttribute());
            }
        }
    }
    View Code Global.asax

    配置WebApiConfig

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Http;
    
    namespace SCM.API
    {
        public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
                config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{action}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
    
                //配置返回的时间类型数据格式
                ReturnJsonSerialiZerSettings();
                
    
                config.Filters.Add(new APIAuthorizeAttribute());
            }
    
            /// <summary>
            /// 返回Json序列化设置
            /// </summary>
            private static void ReturnJsonSerialiZerSettings()
            {
                var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
                json.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Local;
                json.SerializerSettings.DateFormatString = "yyyy'-'MM'-'dd' 'HH':'mm':'ss";
                json.SerializerSettings.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;
            }
        }
    }
    View Code WebApiConfig

    3、测试

  • 相关阅读:
    邪恶的强制数据转换
    知识普及
    判断是否为一个数字
    parseInt
    webpack学习记录
    数组隐藏属性
    elasticSearch基本使用
    elasticsearch安装和部署
    neo4j索引
    spark yarn 提交作业
  • 原文地址:https://www.cnblogs.com/su1643/p/7183474.html
Copyright © 2020-2023  润新知