Azure Ad 无法使用 microsoft.systemForCrossDomainIdentityManagement nuget 包上的补丁更新用户

Azure Ad fails to update users using Patch on microsoft.systemForCrossDomainIdentityManagement nuget package

我们创建了一个 SCIM 集成,使用 microsoft.systemForCrossDomainIdentityManagement 此处描述的 nuget 包:

https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/use-scim-to-provision-users-and-groups

我们已经使用 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"}]}]

}}

我们应该如何解决这个问题?

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

...

}