【问题标题】:Deleting a user from Azure Active Directory B2C Android/Java从 Azure Active Directory B2C Android/Java 中删除用户
【发布时间】:2020-06-04 06:21:37
【问题描述】:

我有一个 Android 应用程序,我在其中使用 Azure AD B2C 对用户进行身份验证。用户根据需要登录和注销应用程序。我想为用户提供删除自己帐户的选项。

我了解我需要使用 Azure AD Graph API 来删除用户。这是我目前所拥有的:

根据this link,似乎无法从个人帐户(这是 B2C 用户正在使用的帐户)中删除用户。对吗?

这是我用于 Graph API 调用的代码 sn-p。如果我偏离了轨道,请随意忽略它,并且有更好的方法来解决这个问题。

我认为我需要一个单独的访问令牌,而不是我的应用当前拥有的访问令牌(因为图形 API 需要其他 API 同意)。所以,我得到的访问令牌如下:

AcquireTokenParameters parameters = new AcquireTokenParameters.Builder()
      .startAuthorizationFromActivity(getActivity())
      .fromAuthority(B2CConfiguration.getAuthorityFromPolicyName(B2CConfiguration.Policies.get("SignUpSignIn")))
      .withScopes(B2CConfiguration.getGraphAPIScopes())
      .withPrompt(Prompt.CONSENT)
      .withCallback(getGraphAPIAuthCallback())
      .build();

taxApp.acquireToken(parameters);

getGraphAPIAuthCallback() 方法中,我使用单独的线程(在后台)调用 Graph API:

boolean resp = new DeleteUser().execute(authenticationResult.getAccessToken()).get();

最后,在我的DeleterUser() AsyncTask 中,我正在执行以下操作:

@Override
    protected Boolean doInBackground(String... aToken) {

        final String asToken = aToken[0];
        //this method will be running on background thread so don't update UI from here
        //do your long running http tasks here,you dont want to pass argument and u can access the parent class' variable url over here
        IAuthenticationProvider mAuthenticationProvider = new IAuthenticationProvider() {
            @Override
            public void authenticateRequest(final IHttpRequest request) {
                request.addHeader("Authorization",
                        "Bearer " + asToken);
            }
        };

        final IClientConfig mClientConfig = DefaultClientConfig
                .createWithAuthenticationProvider(mAuthenticationProvider);

        final IGraphServiceClient graphClient = new GraphServiceClient.Builder()
                .fromConfig(mClientConfig)
                .buildClient();

        try {
            graphClient.getMe().buildRequest().delete();
        } catch (Exception e) {
            Log.d(AccountSettingFragment.class.toString(), "Error deleting user. Error Details: " + e.getStackTrace());
        }

        return true;
    }

目前,我的应用程序在尝试获取带有空指针异常的访问令牌时失败:

com.microsoft.identity.client.exception.MsalClientException: Attempt to invoke virtual method 'long java.lang.Long.longValue()' on a null object reference

知道我需要做什么来为用户提供删除自己帐户的选项吗?谢谢!

【问题讨论】:

    标签: android azure-active-directory azure-ad-b2c azure-ad-graph-api


    【解决方案1】:

    感谢@allen-wu 的帮助。由于他的帮助,this azure feedback requestthis azure doc,我能够弄清楚如何静默获取和删除用户(无需干预)。

    正如@allen-wu 所说,您不能让用户自行删除。因此,我决定让移动应用程序在用户单击“删除帐户”按钮时调用我的服务器端 NodeJS API(因为我不想将客户端密码存储在 android 应用程序中)并让 NodeJS API 调用 Azure AD 端点以静默方式删除用户。需要注意的是,第一次尝试进行身份验证时需要管理员同意。另外,我只为 Graph API 测试过这个。我不能 100% 确定它是否也适用于其他 API。

    步骤如下:

    1. 在 AAD B2C 租户中创建应用程序。创建一个客户端密码并为其提供以下 API 权限:Directory.ReadWrite.AllAuditLog.Read.All(我不能 100% 确定我们是否需要 AuditLog 权限。没有它我还没有测试过)。

    2. 在浏览器中,粘贴以下链接:

    GET https://login.microsoftonline.com/{tenant}/adminconsent?
    client_id=6731de76-14a6-49ae-97bc-6eba6914391e
    &state=12345
    &redirect_uri=http://localhost/myapp/permissions
    
    1. 使用现有管理员帐户登录并同意应用。
    2. 获得管理员同意后,您无需再次重复步骤 1-3。接下来,进行以下调用以获取访问令牌:
    POST https://login.microsoftonline.com/{B2c_tenant_name}.onmicrosoft.com/oauth2/v2.0/token
    

    在正文中,包括您的client_idclient_secretgrant_type(其值应为client_credentials)和scope(值应为'https://graph.microsoft.com/.default')

    1. 最后,您可以调用 Graph API 来管理您的用户,包括删除他们:
    DELETE https://graph.microsoft.com/v1.0/users/{upn}
    

    不要忘记在标头中包含访问令牌。我注意到在 Postman 中,如果我在 Authorization 标头的开头包含单词“Bearer”,则图形 api 有一个错误并返回错误。尝试不使用它,它可以工作。我还没有在我的 NodeJS API 中尝试过,所以目前无法评论它。

    @allen-wu 还建议使用ROPC flow,我还没有尝试过,所以无法比较这两种方法。

    我希望这会有所帮助!

    【讨论】:

      【解决方案2】:

      有一行代码:graphClient.getUsers("").buildRequest().delete();

      好像你没有把用户对象id放进去。

      但是,我们可以忽略这个问题,因为 Microsoft Graph 不允许用户自行删除。

      这是我尝试这样做时的错误。

      {
          "error": {
              "code": "Request_BadRequest",
              "message": "The principal performing this request cannot delete itself.",
              "innerError": {
                  "request-id": "8f44118f-0e49-431f-a0a0-80bdd954a7f0",
                  "date": "2020-06-04T06:41:14"
              }
          }
      }
      

      【讨论】:

      • 谢谢艾伦。我更新了我的代码。它应该是getMe()。我正在测试getUsers(),但是,我的代码甚至没有到达那里。有趣的是,Graph 不会让您自行删除。知道在这种情况下推荐的方法是什么吗?如何以安全的方式删除用户?
      • @DataGeekd 我们应该使用管理员帐户通过门户或 Microsoft Graph 删除用户(而不是自己)。 AD 资源的维护应由管理员完成。如果我的回答对你有帮助,你可以接受它作为答案。谢谢。
      • 谢谢你的回答,@allen-wu。您的回答确实对我有所帮助,尽管您的评论对我的帮助大于您的实际答案。如果您可以发布/编辑您的答案以包含有关让用户自行删除的步骤的信息,那将非常有帮助!我的 Android 应用程序调用了 nodejs api,因此,我可以在 nodejs API 中设置删除。但是,我担心如果有人持有访问令牌,他们可能会冒充用户并向 API 发送删除请求。想法?再次感谢您的帮助!
      • @DataGeek 用户不能删除自己。如果您想知道如何使用管理员帐户删除用户,请参考docs.microsoft.com/en-us/graph/api/…。您可以使用应用程序角色:docs.microsoft.com/en-us/azure/active-directory/develop/…。让只有管理员可以删除用户。
      • 谢谢。我不太确定我是否遵循流程。你能帮忙解释一下吗?我在这里迷失了第 4 步。我的流程正确吗? 1. B2C 用户使用真实帐户登录 Android 应用程序 2. 登录后,用户单击按钮删除他们的帐户 3. 这会向我的 NodeJS API 发送 DELETE API 请求 4. 在我的 NodeJS API 中,我验证身份验证令牌从android客户端收到。验证后,我从 Azure AD 获得一个身份验证令牌,用于使用“client_credentials”注册管理应用程序 5. 我使用新收到的身份验证令牌连接到图形 API 并删除用户
      猜你喜欢
      • 2016-04-17
      • 2016-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-24
      • 1970-01-01
      • 1970-01-01
      • 2023-02-10
      相关资源
      最近更新 更多