Microsoft Android application is not matching the signature hash with the application reply URI

Viewed 2059

Goal: Use the MS Identity application that was created by Microsoft and try to tailor the application according to our needs.

Issue The android application is not matching the signature hash with the Applications' Reply URI.

Configuration Values

Signature Hash: ga0RGNYHvNM5d0SLGQfpQWAPGJ8=
Redirect URI: msauth://com.azuresamples.msalandroidapp/ga0RGNYHvNM5d0SLGQfpQWAPGJ8%3D
Android:host: com.azuresamples.msalandroidapp
Android Scheme: msauth

Logs and Screenshots

Logs show: The redirect URI in the configuration file doesn't match with the one generated with package name and signature hash. Screenshot of the error in the Android Emulator

Methods Tried

  1. Tried to fix this by changing the android:path value to /ga0RGNYHvNM5d0SLGQfpQWAPGJ8%3D however got this message from the UI: Screenshot of the update android:path value

  2. Tried to change the Reply URI directly from Azure Portal, but was not able to

  3. Tried changing the Redirect URI in the android code to msauth://com.azuresamples.msalandroidapp/ga0RGNYHvNM5d0SLGQfpQWAPGJ8%3D but that gave the same error

  4. The default library in the code was 1.2, changed it to 1.5+ in gradle and still it didnt work.

Configuration Files

auth_config_single_account.json


  "client_id" : "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "authorization_user_agent" : "DEFAULT",
  "redirect_uri" : "msauth://com.azuresamples.msalandroidapp/ga0RGNYHvNM5d0SLGQfpQWAPGJ8%3D",
  "account_mode" : "SINGLE",
  "broker_redirect_uri_registered": true,
  "authorities" : [
    {
      "type": "AAD",
      "authority_url": "https://login.microsoftonline.com/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
    }
  ]
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.azuresamples.msalandroidapp">
    ...
            <intent-filter>
                ... 
                <data
                    android:host="com.azuresamples.msalandroidapp"
                    android:path="/ga0RGNYHvNM5d0SLGQfpQWAPGJ8="
                    android:scheme="msauth" />
            </intent-filter>
       ...

</manifest>

Build-Gradle:app

...
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "androidx.appcompat:appcompat:$rootProject.ext.appCompatVersion"
    implementation "com.google.android.material:material:$rootProject.ext.materialVersion"
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'

    implementation 'com.android.volley:volley:1.1.1'

    if (findProject(':msal') != null) {
        // For developer team only.
        localImplementation project(':msal')
        externalImplementation 'com.microsoft.identity.client:msal:1.5.+'
    }
    else {
        // Downloads and Builds MSAL from maven central.
        implementation 'com.microsoft.identity.client:msal:1.5.+'
    }

}

Update

Was trying to avoid this but I have updated my keystore using the debug.keystore that microsoft provides and it works, however this is not solution for production environments. What are the steps I need to take for this to work in the production environment.

3 Answers

Not sure if it will be a relevant answer, but will share my experience. At some point I run into the same issue, dig into the library and figured out how hash is calculated there. It was something like this (I have translated it into kotlin):

try {
        val info = packageManager.getPackageInfo(
            packageName,
            PackageManager.GET_SIGNATURES
        )
        for (signature in info.signatures) {
            val md = MessageDigest.getInstance("SHA")
            md.update(signature.toByteArray())
            val hash = Base64.encodeToString(
                md.digest(),
                Base64.DEFAULT
            )
            Log.d("KeyHash", "KeyHash:$hash")
        }
    } catch (e: PackageManager.NameNotFoundException) {
        Log.d("KeyHash", e.toString())
    } catch (e: NoSuchAlgorithmException) {
    }

The value calculated this way didn't match the value from running this command:

keytool -exportcert -alias androiddebugkey -keystore %HOMEPATH%\.android\debug.keystore | openssl sha1 -binary | openssl base64

But it was the one that msal library expects to get. Same happened on release signature. I haven't yet investigated the reason (maybe I did something wrong), but for now I'm using signature hash got from the first method, and it works fine.

This is Dome from the MSAL Android team.

If you want to use your own keystore, you will have to register your own application.

com.azuresamples.msalandroidapp was only registered with the signature hash of the provided debug.keystore.

Please let me know if you have any other question. You can also leave a question in our GitHub repository as well (we're constantly monitoring that one).

I tried with cmd and keytool but not get success. Please Try this code to generate key hash programmatically in you code.

String packageName = getApplicationContext().getPackageName();
    try {
        PackageInfo info = getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
        for (Signature signature : info.signatures) {
            MessageDigest md;
            md = MessageDigest.getInstance("SHA");
            md.update(signature.toByteArray());
            sha1Singature = new String(Base64.encode(md.digest(), 0));
            //String something = new String(Base64.encodeBytes(md.digest()));
            Log.e(AppConstants.TAG, sha1Singature);
        }
    } 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());
    }

and then you set this Signature hash to Azure portal.

Related