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‘");
        }
    }
}

 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
    }
}

 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();
            }
        }
    }
}

 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());
        }
    }
}

 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;
        }
    }
}

 WebApiConfig

3、测试

时间: 2024-11-09 00:10:20

3、Web Api 身份验证的相关文章

Web API 身份验证 不记名令牌验证 Bearer Token Authentication

1. Startup.Auth.cs文件 添加属性 public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; } 添加静态构造函数 /// <summary> /// 构造函数 /// </summary> static Startup() { OAuthBearerOptions = new OAuthBearerAuthenticationOptions(); }

asp.net Web API 身份验证 不记名令牌验证 Bearer Token Authentication 简单实现

1. Startup.Auth.cs文件 添加属性 1 public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; } 添加静态构造函数 1 2 3 4 5 6 7 /// <summary> /// 构造函数 /// </summary> static Startup() {     OAuthBearerOptions = new OAuthBearerAuthent

基于JWT的web api身份验证及跨域调用实践

随着多终端的出现,越来越多的站点通过web api restful的形式对外提供服务,很多网站也采用了前后端分离模式进行开发,因而在身份验证的方式上可能与传统的基于cookie的Session Id的做法有所不同,除了面临跨域提交cookie的烦人问题外,更重要的是,有些终端可能根本不支持cookie. Json Web Token(jwt)是一种不错的身份验证及授权方案,简单的说就是调用端调用api时,附带上一个由api端颁发的token,以此来验证调用者的授权信息.但由于时间关系,不对jwt

ASP.NET Web API身份验证和授权

英语原文地址:http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api 本文是作者所理解和翻译的内容. 这篇文章包括两部分:身份验证和授权. 身份验证用来确定一个用户的身份.例如,Alice用她的用户名和密码登陆系统,服务器用她的用户名和密码来确定她的身份. 授权是判断一个用户是否允许执行某一操作.例如,Alice有获取资源的许可,但不能创建资源. 身份验证 We

Asp.Net Web Api 身份验证之Form验证

1.原理是使用ActionFilterAttribute对请求进行拦截,对Cookies进行解密.登录则对用户信息进行加密保存在Cookies中. 自定义身份验证特性 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] public class FormAuthAttribute : ActionFilterAttribute { pu

asp.net core web api token验证和RestSharp访问

对与asp.net core web api验证,多种方式,本例子的方式采用的是李争的<微软开源跨平台移动开发实践>中的token验证方式. Asp.net core web api项目代码: 首先定义三个Token相关的类,一个Token实体类,一个TokenProvider类,一个TokenProviderOptions类 代码如下: /// <summary> /// Token实体 /// </summary> public class TokenEntity

ASP.NET Web API模型验证以及异常处理方式

ASP.NET Web API的模型验证与ASP.NET MVC一样,都使用System.ComponentModel.DataAnnotations. 具体来说,比如有:[Required(ErrorMessage="")][Range(0, 999)][Bind(Exclude="")][DisplayName("")][StringLength(1024)]... 验证扩展可以看这里:http://dataannotationsextens

web api token验证理解

最近一直在学习web api authentication,以Jwt为例,可以这样理解,token是身份证,用户名和密码是户口本,身份证是有有效期的(jwt 有过期时间),且携带方便(自己带有所有信息 self contained),户口本不会过期(用户名和密码什么时候都有用),携带不方便(用户名和密码从数据库验证),jwt同样也有身份证的缺点,丢了别人有些地方可以用,户口本改名字了,身份证还可以用(同样,用户名和密码修改后jwt不修改).针对身份证的缺点,可以设置较短过期时间,另外token

Web Service身份验证

Web Service是政府,企业,个人提供的在线应用服务,其他公司.软件都能通过Internet来访问并使用服务.针对于有些公司某些数据只允许授权的企业或人使用,所以我们需要进行身份验证 第一种方式:在Web Service引入SoapHeader 1.如下图,我们实现一个用于实现身份验证的类MySoapHeader,定义两个成员变量(UserName和Password),定义函数ValideUser用来检测使用服务的程序的Soap标头的数据是否被授权使用服务 //实现一个用来验证身份的类 p