无法在 android 上为 Azure AD 创建 SingleAccountPublicClientApplication

Unable to create SingleAccountPublicClientApplication for Azure AD on android

按照 https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-android 上的说明,我使用 KeyTool 生成了开发签名哈希并在 Azure 门户中注册了我的应用程序。

门户生成了 MSAL 配置,然后我将其粘贴到项目的 res.raw.auth_config.json 中(my-app-client-id 和 my-app 的程序包名称只是下面示例中的占位符;实际值为 auto -由 Azure 生成):

{
  "client_id" : "<my-app-client-id>",
  "authorization_user_agent" : "DEFAULT",
  "redirect_uri" : "msauth://<my-app's package name>/npYKnQBHywGAasZflTy2xmdpEiU%3D",
  "authorities" : [
    {
      "type": "AAD",
      "audience": {
        "type": "AzureADMultipleOrgs",
        "tenant_id": "organizations"
      }
    }
  ]
}

然后我将以下内容添加到 AndroidManifest.xml:

<application>
[..]
        <!--Intent filter to catch Microsoft's callback after Sign In-->
        <activity
            android:name="com.microsoft.identity.client.BrowserTabActivity">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE"/>

                <!--
                    Add in your scheme/host from registered redirect URI
                    note that the leading "/" is required for android:path
                -->
                <data
                    android:scheme="msauth"
                    android:host=""
                    android:path="/<signature-generated-by-keytool>" />
            </intent-filter>
        </activity>
[...]
</application>

在我的 activity 的 onCreate() 中,我尝试创建一个单一帐户客户端应用程序,如下所示:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_single_account_model);
        initializeUI();

        PublicClientApplication.createSingleAccountPublicClientApplication(this,
            R.raw.auth_config,
            new IPublicClientApplication.ISingleAccountApplicationCreatedListener() {
                @Override
                public void onCreated(ISingleAccountPublicClientApplication application) {
                    mSingleAccountApp = application;
                    loadAccount();
                }

                @Override
                public void onError(MsalException exception) {
                    displayError(exception);
                }
            });
}

不幸的是 PublicClientApplication.createSingleAccountPublicClientApplication() 调用使应用程序崩溃并出现以下错误:

java.lang.IllegalStateException: The redirect URI in the configuration file doesn't match with the one generated with package name and signature hash. Please verify the uri in the config file and your app registration in Azure portal.

我不明白为什么会这样,因为配置文件的内容是由 Azure 门户生成的,包名称、签名哈希和重定向 URI 与门户中显示的任何内容都匹配。

如果有任何建议,我将不胜感激。

简而言之:这可能是您的调试密钥库有问题。我最近遇到了同样的问题,当我按照他们的说明在命令行上创建哈希时,它最终成为一个问题。为我解决的是在 Azure 门户上重新执行应用程序注册过程,当您在命令行上创建哈希时,请确保使用 android 密钥库的密码(默认为 'android').我第一次这样做时,我使用了 jdk 密钥库的默认密码,它仍然为我创建了一个散列,但它导致了你描述的错误。我不完全确定整个过程是如何进行的,希望其他人能够澄清,但我上面描述的内容为我解决了这个问题。

我也遇到了同样的问题。要获得有效的签名哈希,请按照以下步骤操作。

STEP 1: 运行 LAUNCHER的onCreate方法中的以下方法activity.

Kotlin

@RequiresApi(Build.VERSION_CODES.P)
private fun getSignatureHash() {
   try {
      val info = packageManager.getPackageInfo(
         "<com.package.name>",
         PackageManager.GET_SIGNING_CERTIFICATES
      )
      for (signature in info.signingInfo.apkContentsSigners) {
         val md = MessageDigest.getInstance("SHA")
         md.update(signature.toByteArray())
         Log.d(
           "KeyHash", "KeyHash:" + Base64.encodeToString(
              md.digest(),
              Base64.DEFAULT
           )
         )
      }
   } catch (e: PackageManager.NameNotFoundException) {
   } catch (e: NoSuchAlgorithmException) {
   }
}

Java
https://github.com/AzureAD/microsoft-authentication-library-for-android/issues/914#issuecomment-582259223

try {
   PackageInfo info = getPackageManager().getPackageInfo(
      "<com.package.name>",
      PackageManager.GET_SIGNATURES
   );
   for (Signature signature : info.signatures) {
      MessageDigest md;
      md = MessageDigest.getInstance("SHA");
      md.update(signature.toByteArray());
      String something = new String(Base64.encode(md.digest(), 0));
      //String something = new String(Base64.encodeBytes(md.digest()));
      Log.e("KeyHash", something);
   }
} catch (PackageManager.NameNotFoundException e1) {
   Log.e("name not found", e1.toString());
} catch (NoSuchAlgorithmException e) {
   Log.e("no such an algorithm", e.toString());
} catch (Exception e) {
   Log.e("exception", e.toString());
}

第 2 步: 您应该在 Android Studio Logcat 中获取 HashKey。使用此 HasKey 在 Azure AD 中注册

对我来说,问题原来是 MS 门户要求我们使用默认安装的 debug.keystore 以及 Android studio %HOMEPATH%\.android\debug.keystore.

但是,ms-identity-android-java 示例在项目文件夹中有一个单独的 debug.keystore 文件; \ms-identity-android-java-master\gradle\debug.keystore.

使用此文件创建哈希,您就完成了:)