我们在做API接口时,接收方的签名校验,最简单的莫过于字符串对比了。以下是一个继承于Attribute类的自定义类。在这个类里,我们即可以做一些简单的校验操作,还可以自定义错误信息。当然,如果需要更为复杂的逻辑校验,完全在这个基础之上扩展实现。而在需要应用的时候,只需要简单地添加属性到相应的接口即可。
上代码:
public class RequestAuthorizeAttribute : Attribute
{
private const string _NOLIMIT_IP = "*.*.*.*";//此处设置一个无限制字符串,即任何请求方都可以调用,通常用来做测试
public RequestAuthorizeAttribute() { }
public void OnAuthorization(AuthorizationFilterContext context)
{
var logger = NLog.LogManager.GetCurrentClassLogger();
if (context == null)
throw new ArgumentNullException("OnAuthorization AuthorizationContext context can not be null.");
else
{
//从http请求的头里面获取身份验证信息,验证是否是通过
var headers = context.HttpContext.Request.Headers;
var whiteList = AppSettingsHelper.Configuration["WhiteList"]?.Split(new char[] { ';' }).ToList();//从配置文件中获取白名单列表
if (whiteList != null && whiteList.Count > 0)
{
if (!whiteList.Contains(_NOLIMIT_IP))
{
var curIP = context.HttpContext.Connection.RemoteIpAddress.ToString();
if (!whiteList.Contains(curIP))
{
logger.Error($"IP {curIP} UnAuthorizate.");
context.Result = new UnauthorizedObjectResult(new KerryResponse<string>()
{
code = 400,
message = "IP UnAuthorizate."
});
return;
}
}
}
if (headers.ContainsKey("Authorization"))//请求方需要把签名放到Header的Authorization参数中传送过来
{
var auths = AppSettingsHelper.Configuration["Authorization"].Split(new char[] { ';' }).ToList();//拿到允许的签名列表
if (auths.Contains(headers["Authorization"]))
{
//Passed
}
else
{
logger.Error($"Login failed, Incorrect token {headers["Authorization"]}.");
context.Result = new UnauthorizedObjectResult(new KerryResponse<string>()
{
code = 403,
message = "Login failed, user password is incorrect or user is disabled"
});
}
}
else
{
//Header无签名参数,抛出异常
context.Result = new UnauthorizedObjectResult(new KerryResponse<string>()
{
code = 403,
message = "Parameter missing"
});
}
}
}
}
如下所示,应用到需要签名认证的接口上面:
[HttpGet, RequestAuthorize]
public async Task<IActionResult> Get()
{
return Ok();
}
好了,很简单但十分有用而高效的签名认证功能就实现了。
实属班门弄斧不自量,权作抛砖引玉撩一笑。