我们在做后台接口开发的时候,为了保障接口访问安全,IP访问控制是必不可少的,这里运用filter的特性来完成接口访问控制。
Filter在Web API中经常会用到,主要用于记录日志,安全验证,全局错误处理等,通过Filter能统一地对一些通用逻辑进行处理。在默认的WebApi中,框架提供了2种Filter,分别继承actionfilterattribute,exceptionfilterattribute。actionfilter主要实现执行请求方法体之前和之后的事件处理,exceptionfilter主要实现触发异常方法。
这里使用actionfilter来完成IP访问控制:
1、在接口类/方法添加过滤器
[AccessFilter]
public class PasswordController : ApiController
{
public ResponseModel Get(string openId)
{
if (string.IsNullOrEmpty(openId))
{
LogHelper.Info(Resource.OpenIdInvalid);
response.Message = Resource.OpenIdInvalid;
return response;
}
}
}
2、新建ActionFilter类
public class AccessFilter : ActionFilterAttribute
{
/// <summary>
/// 过滤器主方法
/// </summary>
/// <param name="actionContext"></param>
public override void OnActionExecuting(HttpActionContext actionContext)
{
try
{
var ip = GetClientIp(actionContext.Request);
var constrollers = ClientConfigHelper.ClientModels;
var validClient = constrollers.FirstOrDefault(item => item.Ip.Equals(ip));
if (validClient == null || !validClient.Enabled)
{
HandleRequest(actionContext, EnumResponseCode.Unauthorized);
}
}
catch (Exception exception)
{
LogHelper.Error(Resource.ExecutingActionFilterError, exception);
}
}
/// <summary>
/// 获取请求的IP地址
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
private string GetClientIp(HttpRequestMessage request)
{
if (request.Properties.ContainsKey("MS_HttpContext"))
{
return ((HttpContextWrapper)request.Properties["MS_HttpContext"]).Request.UserHostAddress;
}
else if (request.Properties.ContainsKey(RemoteEndpointMessageProperty.Name))
{
RemoteEndpointMessageProperty prop;
prop = (RemoteEndpointMessageProperty)request.Properties[RemoteEndpointMessageProperty.Name];
return prop.Address;
}
else
{
return null;
}
}
/// <summary>
/// 请求处理
/// </summary>
/// <param name="actionContext"></param>
/// <param name="code"></param>
private void HandleRequest(HttpActionContext actionContext, EnumResponseCode code)
{
var message = EnumHelper.GetEnumDescription(code);
var result = new ResponseModel { Code = (int)code, Message = message };
actionContext.Response = actionContext.Request.CreateResponse(
HttpStatusCode.OK,
result,
actionContext.ControllerContext.Configuration.Formatters.JsonFormatter
);
}
}
3、获取配置文件授权IP地址信息
public class ClientConfigHelper
{
private ClientConfigHelper() { }
static ClientConfigHelper()
{
var path = string.Format("{0}App_Data\\controllers.config", AppDomain.CurrentDomain.BaseDirectory);
ClientModels = JsonHelper.DeserializeObjectFromFile<List<ClientModel>>(path);
}
public static List<ClientModel> ClientModels { get; private set; }
}