我尝试在Azure API管理器中的API上设置入站策略,该策略在将POST请求体传递给后端之前验证POST请求正文中的JSON。
我应该使用JSON模式并对其进行验证(如何?)或者我是否应该编写自己的代码,使用context.Request.Body来检查请求正文中的每个字段,或者尝试使用它是完全错误的验证APIM中的请求正文,是否留给后端?
答案 0 :(得分:1)
我们目前正在使用<set-body>
在API操作策略中进行验证,以进行验证(并在需要时重塑主体)。在此政策中,我们收集了所有错误,然后抛出异常:
<set-body>@{
var body = context.Request.Body.As<JObject>(true);
string businessSystemID = context.Request.Headers.GetValueOrDefault("SenderBusinessSystemID", "");
var result = new JObject();
string cleanUp = body.ToString().Replace("\r\n","");
var root = JObject.Parse(cleanUp);
var valid = false;
var errors = new JArray();
var returnValue = new JObject();
returnValue["errors"] = errors;
if(root["CostAllocation"] != null)
{
if(businessSystemID != string.Empty)
{
root["CostAllocation"]["SenderBusinessSystemID"] = businessSystemID;
}
if(root["CostAllocation"]["ReferenceID"] != null)
{
var referenceIDValidator = @"^[A-Z0-9]{0,35}$";
var referenceID = root["CostAllocation"]["ReferenceID"];
valid = new Regex(referenceIDValidator, RegexOptions.IgnoreCase).Match(referenceID.ToString()).Success;
if(!valid)
{
var error = new JObject();
error["property"] = "ReferenceID";
error["validator"] = referenceIDValidator;
error["value"] = referenceID;
error["message"] = "No valid 'ReferencedId'";
errors.Add(error);
}
}
if(root["CostAllocation"]["UserID"] != null)
{
var userIDValidator = @"^[\w]{4,12}$";
var userID = root["CostAllocation"]["UserID"];
valid = new Regex(userIDValidator, RegexOptions.IgnoreCase).Match(userID.ToString()).Success;
if(!valid)
{
var error = new JObject();
error["property"] = "UserID";
error["validator"] = userIDValidator;
error["value"] = userID;
error["message"] = "No valid 'UserID'";
errors.Add(error);
}
}
...
if(errors.Count > 0)
{
throw new Exception(returnValue.ToString());
}
return root.ToString(Newtonsoft.Json.Formatting.None);
}</set-body>
在<on-error>
中捕获到异常,并对其进行了格式化:
<on-error>
<choose>
<when condition="@(context.LastError.Message.Contains("Expression evaluation failed")==true)">
<set-status code="400" reason="Bad request" />
</when>
<otherwise>
<set-status code="500" reason="Error" />
</otherwise>
</choose>
<set-body template="none">@{
return context.LastError.Message.Replace("Expression evaluation failed.","").Trim();
}</set-body>
<base />
</on-error>
我们知道,使用这种方法的编码工作量很大,宁愿首选API Management直接支持的JSON模式检查。在后端处理模式检查,并通过传递请求增加延迟,这对我们来说不是一个选择。
我目前正在考虑的一个选项是在API CI / CD流程中解析JSON模式,生成通用验证并在API操作策略中将其替换。
答案 1 :(得分:0)
验证有效载荷非常好。请注意,这样做需要在APIM端缓存整个请求主体,默认情况下不会这样做。策略表达式中没有JSON模式验证器,因此您必须使用手动验证。