Azure Ad 无法使用 microsoft.systemForCrossDomainIdentityManagement nuget 包上的补丁更新用户
Azure Ad fails to update users using Patch on microsoft.systemForCrossDomainIdentityManagement nuget package
我们创建了一个 SCIM 集成,使用
microsoft.systemForCrossDomainIdentityManagement
此处描述的 nuget 包:
我们已经使用 Postman 测试了 API,它们可以正常工作,但是当我们使用 Azure AD 测试它们时,补丁请求失败。
查看日志并缩小范围,我们发现请求的格式与 microsoft.systemForCrossDomainIdentityManagement 预期的格式不同。
来自 AD 的一个补丁请求如下(将失败):
{ "schemas":["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [ {"op":"Replace","path":"displayName","value":" User
X"} ]}
虽然有效的请求是这样的:
{"schemas":["urn:ietf:params:scim:api:messages:2.0:PatchOp"]
,
"Operations":[
{"op":"Replace","path":"displayName","value":
[ {"$ref":null,"value":"User x"}]}]
}}
- 请注意 2 个请求之间的区别,第一个调用是字符串,第二个请求是对象列表。
我们应该如何解决这个问题?
Nuget 包接收请求并传送 IPatchRequest,因此请求甚至不会接收到我们的代码部分,并且这两部分都是 Microsoft :|
由于一个多月后微软没有回复,我知道他们唯一解决这个问题的方法是在调用到达微软的代码部分(使用中间件)之前拦截调用并更改将其转换为他们期望的格式:\
我已经在下面的 link 中进一步讨论了问题和解决方案,但我仍在等待 Microsoft 的修复:\
http://pilpag.blogspot.com/2019/02/enabling-scim-using-microsoftsystemforc.html
简单的解决方法如下:
public class PatchRequestUpdaterMiddleware : OwinMiddleware
{
private const string OperationValueFinderRegex = "({[\s\w\":,.\[\]\\]*op[\s\w\":,.\[\]\\]*\"value\"\s*:\s*)(\"[\w\s\-,.@?!*;\'\(\)]+\")"; //{"op":"x","value":"Andrew1"}
public override async Task Invoke(IOwinContext context)
{
if (context.Request.Method.ToLower() != "patch")
{
await Next.Invoke(context);
return;
}
var streamReader = new StreamReader(context.Request.Body);
string body = streamReader.ReadToEnd();
body = Regex.Replace(body, OperationValueFinderRegex, m => $"{m.Groups[1].Value}[{{\"value\":{m.Groups[2].Value}}}]"); //{"op":"x","value":"Ashkan"} ==>> {"op":"x","value":[{"value":"Ashkan"}]}
context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));
await Next.Invoke(context);
}
}
然后将其添加到您创建的提供者中:
class myProvider:ProviderBase
{
....
private void OnServiceStartup(IAppBuilder appBuilder, HttpConfiguration configuration)
{
...
appBuilder.Use<PatchRequestUpdaterMiddleware>();
...
}
我们创建了一个 SCIM 集成,使用
microsoft.systemForCrossDomainIdentityManagement
此处描述的 nuget 包:
我们已经使用 Postman 测试了 API,它们可以正常工作,但是当我们使用 Azure AD 测试它们时,补丁请求失败。
查看日志并缩小范围,我们发现请求的格式与 microsoft.systemForCrossDomainIdentityManagement 预期的格式不同。
来自 AD 的一个补丁请求如下(将失败):
{ "schemas":["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [ {"op":"Replace","path":"displayName","value":" User X"} ]}
虽然有效的请求是这样的:
{"schemas":["urn:ietf:params:scim:api:messages:2.0:PatchOp"] ,
"Operations":[ {"op":"Replace","path":"displayName","value":
[ {"$ref":null,"value":"User x"}]}]
}}
- 请注意 2 个请求之间的区别,第一个调用是字符串,第二个请求是对象列表。
我们应该如何解决这个问题?
Nuget 包接收请求并传送 IPatchRequest,因此请求甚至不会接收到我们的代码部分,并且这两部分都是 Microsoft :|
由于一个多月后微软没有回复,我知道他们唯一解决这个问题的方法是在调用到达微软的代码部分(使用中间件)之前拦截调用并更改将其转换为他们期望的格式:\
我已经在下面的 link 中进一步讨论了问题和解决方案,但我仍在等待 Microsoft 的修复:\ http://pilpag.blogspot.com/2019/02/enabling-scim-using-microsoftsystemforc.html
简单的解决方法如下:
public class PatchRequestUpdaterMiddleware : OwinMiddleware
{
private const string OperationValueFinderRegex = "({[\s\w\":,.\[\]\\]*op[\s\w\":,.\[\]\\]*\"value\"\s*:\s*)(\"[\w\s\-,.@?!*;\'\(\)]+\")"; //{"op":"x","value":"Andrew1"}
public override async Task Invoke(IOwinContext context)
{
if (context.Request.Method.ToLower() != "patch")
{
await Next.Invoke(context);
return;
}
var streamReader = new StreamReader(context.Request.Body);
string body = streamReader.ReadToEnd();
body = Regex.Replace(body, OperationValueFinderRegex, m => $"{m.Groups[1].Value}[{{\"value\":{m.Groups[2].Value}}}]"); //{"op":"x","value":"Ashkan"} ==>> {"op":"x","value":[{"value":"Ashkan"}]}
context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));
await Next.Invoke(context);
}
}
然后将其添加到您创建的提供者中:
class myProvider:ProviderBase
{
....
private void OnServiceStartup(IAppBuilder appBuilder, HttpConfiguration configuration)
{
...
appBuilder.Use<PatchRequestUpdaterMiddleware>();
...
}