Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to create SingleAccountPublicClientApplication for Azure AD on android

As per instructions at https://learn.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-android I generated development signature hash using KeyTool and registered my application in Azure portal.

The portal generated MSAL configuration that I then pasted into res.raw.auth_config.json in the project (my-app-client-id and my-app's package name are just place holders in the sample below; actual values were auto-generated by 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"
      }
    }
  ]
}

I then added the following to 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>

In my activity's onCreate() I attempt to create a single account client application as follows:

    @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);
                }
            });
}

Unfortunatelly PublicClientApplication.createSingleAccountPublicClientApplication() call crashes the app with the following error:

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.

I can't figure out why this is happening because the config file's content was generated by Azure portal and package name, signature hash, and redirect URI match whatever is shown in the portal.

I'd appreciate any suggestions.

like image 434
gordieb Avatar asked Nov 07 '19 22:11

gordieb


People also ask

Can Android device join Azure AD?

The Android Work Account will register the device with the Azure AD Device Registration Service. Using devices registered with this service, you can configure conditional access policies to on-premises resources now.

How do I authenticate an app using Azure AD?

Enable Azure Active Directory in your App Service app. Sign in to the Azure portal and navigate to your app. Select Authentication in the menu on the left. Click Add identity provider.

What is App ID URI in Azure AD?

The sign-on URL is the URL that clients will use to access the application. The application ID URI is a URI that uniquely identifies the application in your Azure Active Directory. The URI can be anything you want as long as it is unique to your directory and a valid URI.


2 Answers

I too faced the same issue. To get the Signature hash that works, follow the below steps.

STEP 1: Run the below method in the onCreate method of LAUNCHER 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());
}

STEP 2: You should get the HashKey in the Android Studio Logcat. Use this HasKey to register in Azure AD

like image 71
Roshan Varghese Avatar answered Oct 16 '22 07:10

Roshan Varghese


In short: this is likely a problem with your debug keystore. I was having this same problem recently, it ended up being a problem when I was creating the hash on the command line with their instructions. What solved it for me was re-doing the app registration process on the azure portal, and when you create the hash on the command line, make sure to use the password for your android keystore (default is 'android'). The first time I did it I used the default password for the jdk keystore and it still created a hash for me but it resulted in the error you described. I'm not entirely sure how the whole process works and would love for another person to clarify, but what I described above solved the issue for me.

like image 25
nicktm Avatar answered Oct 16 '22 06:10

nicktm