Select to view content in your preferred language

OAuthLoginManager

2246
16
05-10-2019 01:15 PM
by Anonymous User
Not applicable

I am trying to update our application to 100.5 from 10.2.9.  I am trying to authenticate the application and have an application setup for the application in our AGOL Organization with a client id and redirect uri.  Am running into issues using OAuthLoginManager when I run oAuthLoginManager.launchOAuthBrowserPage(context); I get the message...

Please copy this code, switch to your application and paste it there.  Struggling to find a good example that describes this.  Also strange that it opens up Chrome rather than opening within the app as it did with 10.2.9.  Any guidance in the right direction greatly appreciated.  

private OAuthManagement() {

final int OAUTH_EXPIRATION_NEVER = -1;
oAuthLoginManager = new OAuthLoginManager("https://arcgis.com", "YOUR_CLIENT_ID", "urn:ietf:wg:oauth:2.0:oob", OAUTH_EXPIRATION_NEVER);
}

public void LaunchLogin(Context context) {
oAuthLoginManager.launchOAuthBrowserPage(context);
}

public void handleTokenCredential(Intent intent) {
portal = new Portal("https://www.arcgis.com", true);
ListenableFuture<OAuthTokenCredential> futureToken = oAuthLoginManager.fetchOAuthTokenCredentialAsync(intent);

try {
OAuthTokenCredential oAuthTokenCredential = futureToken.get();
portal.setCredential(oAuthTokenCredential);
portal.loadAsync();
portal.addDoneLoadingListener(new Runnable() {
@Override
public void run() {
if(portal.getLoadStatus() == LoadStatus.LOADED) {
ArcGISRuntimeEnvironment.setLicense(portal.getPortalInfo().getLicenseInfo());
}
}
});

} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}

0 Kudos
16 Replies
XuemingWu
Esri Contributor

Aaron,

You should use a custom redirect_uri instead of the known uri "urn:ietf:wg:oauth:2.0:oob" in your Android app. In order to allow the browser to redirect the user back to your app after they authorize your app you need to setup a custom redirect_uri. An example of a custom redirect_uri is "my-arcgis-app://auth". The following changes are needed. Before making these changes, you need to add the custom redirect_uri to your application on ArcGIS Online or your on-premise portal. More info about configuring a redirect URI can be found at this guide doc

1. Modify the intent-filter in the AndroidManifest.xml: 

change

<data android:scheme="urn:ietf:wg:oauth:2.0:oob"/>

to 

<data android:host=“auth” android:scheme=“my-arcgis-app”/>

2. Modify the redirectUri parameter passed to the OAuthConfiguration:

change

OAuthConfiguration oAC = new OAuthConfiguration(urlLogin, Client_ID2, "urn:ietf:wg:oauth:2.0:oob", OAUTH_EXPIRATION_NEVER);

to 

OAuthConfiguration oAC = new OAuthConfiguration(urlLogin, Client_ID2, "my-arcgis-app://auth", OAUTH_EXPIRATION_NEVER);

thanks,

Xueming

0 Kudos
by Anonymous User
Not applicable

Thanks Xueming!  That worked.

A follow up question.  So a question after login is successful and back in portal listener...

portal.getCredential() returns a regular Credential

Is there anyway to pull an OAuthTokenCredential from the AuthenticationManager after login?  
Cannot seem to find a good example of this.

The reason we need an OAuthTokenCredential is that in the app we have the ability to download TPK files and in order to download I follow this pattern using the token to do a stock Android download...

String token = mOauthToken.getAccessToken();
requestUrl = portal.getUri() + "/sharing/rest/content/items/" + itemID + "/data?token=" + token;
URL url = new URL(requestUrl);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

Seems like something like this might work alternatively....but am struggling to figure out how to create an authorizationCode

OAuthTokenCredentialRequest request = new OAuthTokenCredentialRequest(finalURLLogin, null, Client_ID2, "my-arcgis-app://auth", authorizationCode);
0 Kudos
XuemingWu
Esri Contributor

Aaron,

You are very welcome. 

You don't need to pull the credential from AuthenticationManager. When you access a portal with OAuth, the credential comes back should be an instance of OAuthTokenCredential, meaning you can cast it to an OAuthTokenCredential like the following:

OAuthTokenCredential credential = ((OAuthTokenCredential) portal.getCredential());

As for downloading TPK files from a portal, our SDK provides another option which is a class called ArcGISDownloadRequest. This class extends Android's DownloadManager.Request and works with token-based and OAuth authentication. You can create a Request by calling:

ArcGISDownloadRequest.createInstance(portal.getUri() + "/sharing/rest/content/items/" + itemID + "/data");

As you already use the DefaultAuthenticationChallengeHandler to deal with authentication in your app, it is unnecessary to use OAuthTokenCredentialRequest to obtain credential. Though the DefaultAuthenticationChallengeHandler also calls OAuthTokenCredentialRequest, there are a few more steps to get the authorization code, launch the sign in page in a browser and then obtain the credential. The DefaultAuthenticationChallengeHandler takes case all the details and is the recommended approach for our users.

Cheers,

Xueming

0 Kudos
by Anonymous User
Not applicable

Xueming, Thank you for that quick tip.  Should have thought about casting the credential.  For everyone else's benefit below is a summary of how to get your app authenticated and create a credential for further use in your application.

1.  In you application in AGOL add in a new redirect uri as follows...

"my-arcgis-app://auth"

2.  In you Android Manifest add in the following...

<activity
    android:name="com.esri.arcgisruntime.security.DefaultOAuthIntentReceiver"
    android:launchMode="singleTask"
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
    android:label="YourLabel">
    <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:scheme="my-arcgis-app"/>
    </intent-filter>
</activity>

3.  In onCreate of your Activity...Note that client id also is known from you application in AGOL

String urlLogin = "https://www.arcgis.com";
try {
   int OAUTH_EXPIRATION_NEVER = -1;
final AuthenticationChallengeHandler handler = new DefaultAuthenticationChallengeHandler(this);
final OAuthConfiguration oAC = new OAuthConfiguration(urlLogin, Client_ID, "my-arcgis-app://auth", OAUTH_EXPIRATION_NEVER);
AuthenticationManager.addOAuthConfiguration(oAC);
AuthenticationManager.setAuthenticationChallengeHandler(handler);
} catch (MalformedURLException e) {
//String x = e.getMessage();
throw new AssertionError(e);
}

// create a portal to ArcGIS Online
portal = new Portal(urlLogin, true);

portal.addDoneLoadingListener(new Runnable() {
@Override
public void run() {
try {
if (portal.getLoadStatus() == LoadStatus.LOADED) {
// loaded
// get the authorization code by sending user to the authorization screen
OAuthTokenCredential mValidLoginCredentials = (OAuthTokenCredential) portal.getCredential();
         }
} catch (Exception e) {
e.printStackTrace();
}
}
});

0 Kudos
by Anonymous User
Not applicable

Argh forgot an important detail...portal.loadAsync(); is what initiates portal and request for creds...

// create a portal to ArcGIS Online
portal = new Portal(urlLogin, true);

portal.addDoneLoadingListener(new Runnable() {
 @Override
 public void run() {
 try {
 if (portal.getLoadStatus() == LoadStatus.LOADED) {
 // loaded
 // get the authorization code by sending user to the authorization screen
 OAuthTokenCredential mValidLoginCredentials = (OAuthTokenCredential) portal.getCredential();
         }
 } catch (Exception e) {
 e.printStackTrace();
 }
 }
});

portal.loadAsync();

0 Kudos
by Anonymous User
Not applicable

OK one other comment on this method for login.  When using this method the default browser is used for login.  The unfortunate consequence is that each time you login a new tab is opened in your internet browser on your device (in my case Chrome).  When I later access Chrome Browser I see a tab for each time I logged in with credentials still in there.  Is there a built in way to close the browser tab after done?  I can see this being a problem in the production environment.

0 Kudos
GuntherHeppner
Esri Contributor

Hi Aaron,

This is a bug we are aware of and currently trying to fix. We are not aware of any workaround.

Gunther

0 Kudos