Access services with OAuth credentials

Learn how to implement user authentication to access a secure ArcGIS service with OAuth credentials.

access services with oauth 2

You can use different types of authentication to access secured ArcGIS services. To implement OAuth credentials for user authentication, you can use your ArcGIS account to register an app with your portal and get a Client ID, and then configure your app to redirect users to login with their credentials when the service or content is accessed. This is known as user authentication. If the app uses premium ArcGIS Online services that consume credits, for example, the app user's account will be charged.

In this tutorial, you will build an app that implements user authentication using OAuth credentials so users can sign in and be authenticated through ArcGIS Online to access the ArcGIS World Traffic service.

Prerequisites

Before starting this tutorial:

  1. You need an ArcGIS Location Platform or ArcGIS Online account.

  2. Confirm that your system meets the system requirements.

  3. An IDE for Android development in Kotlin.

Steps

Create OAuth credentials for user authentication

OAuth credentials are required to implement user authentication. These credentials are created as an Application item in your organization's portal.

  1. Go to the Create OAuth credentials for user authentication tutorial and create OAuth credentials using your ArcGIS Location Platform or ArcGIS Online account.

  2. Copy the Client ID and Redirect URL as you will use them to implement user authentication in the next step. The Client ID is found on the Application item's Overview page, while the Redirect URL is found on the Settings page.

You'll use the Client ID and Redirect URL when implementing OAuth in your app's code. The Client ID is found on the Application item's Overview page, while the Redirect URL is found on the Settings page.

Open an Android Studio project with Gradle

  1. To start this tutorial, complete the Display a map tutorial. Or download and unzip the Display a map solution in a new folder.

  2. Modify the old project for use in this new tutorial. Expand More info for instructions.

  3. Delete the code that sets your API Key. Since your app will be using OAuth, you will not need to set an API Key.

    MainActivity.kt
    Expand
    Use dark colors for code blocks
    40 41 42 43 44 45 46 47 48 49
    Remove line
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            setContentView(activityMainBinding.root)
    
            setApiKeyForApp()
    
            setupMap()
    
        }
    
    Expand
    MainActivity.kt
    Expand
    Use dark colors for code blocks
    61 62 63 64 65 66 67 68 69 70
    Remove lineRemove lineRemove lineRemove lineRemove line
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
        override fun onDestroy() {
            mapView.dispose()
            super.onDestroy()
        }
    
        private fun setApiKeyForApp(){
    
            ArcGISRuntimeEnvironment.setApiKey("YOUR_ACCESS_TOKEN")
    
        }
    
    Expand

Prepare files before coding the app

Modify the files from the Display a map tutorial so they can be used in this tutorial: you will add imports, modify the view point's scale, define strings for OAuth Client ID and Redirect URL, and add an Android activity for the default OAuth intent receiver.

  1. In the Project tool window, make sure that the Android view is displayed. Open app/java/com.example.app, and click MainActivity.kt. Add the following imports, replacing those from the Display a map tutorial.

    MainActivity.kt
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    package com.example.app
    
    import android.os.Bundle
    import android.util.Log
    import android.widget.Toast
    import androidx.appcompat.app.AppCompatActivity
    
    import com.esri.arcgisruntime.layers.ArcGISMapImageLayer
    import com.esri.arcgisruntime.mapping.ArcGISMap
    import com.esri.arcgisruntime.mapping.BasemapStyle
    import com.esri.arcgisruntime.mapping.Viewpoint
    import com.esri.arcgisruntime.mapping.view.MapView
    import com.esri.arcgisruntime.security.AuthenticationManager
    import com.esri.arcgisruntime.security.DefaultAuthenticationChallengeHandler
    import com.esri.arcgisruntime.security.OAuthConfiguration
    import com.example.app.databinding.ActivityMainBinding
    
    import java.net.MalformedURLException
    
    
    class MainActivity : AppCompatActivity() {
    
  2. Change the scale of the map's initial viewpoint to 72000.0. This scale will make the secured layer visible without zooming in.

    MainActivity.kt
    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
          val map = ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC)
    
          mapView.map = map
    
          mapView.setViewpoint(Viewpoint(34.02700, -118.80543, 72000.0))
    
    Expand
  3. Open app/res/values and click strings.xml. Enter certain values that you specified while creating your OAuth credentials in Create OAuth credentials above.

    In string.xml define strings for the OAuth Client ID, redirect host and uri. Replace the placeholder strings with values from your actual OAuth credentials. The replacement values are not quoted.

    • "YOUR_CLIENT_ID": Replace with the Client ID for your app.

    • "YOUR_REDIRECT_HOST": Replace with the host name portion of your Redirect URL that follows ://. Above, we suggested using auth.

    • "YOUR_REDIRECT_URI": Replace with the protocol identifier of your Redirect URL that precedes ://. This must be my-app.

    strings.xml
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <resources>
    
        <string name="app_name">Access services with OAuth 2.0</string>
    
        <string name="oauth_client_id">YOUR_CLIENT_ID</string>
        <string name="oauth_redirect_host">YOUR_REDIRECT_HOST</string>
        <string name="oauth_redirect_uri">YOUR_REDIRECT_URI</string>
    
    </resources>
  4. Open app/manifests and click AndroidManifest.xml. Add an activity for the default OAuth intent receiver.

    AndroidManifest.xml
    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
            <!-- You must declare this activity, an intent receiver, to display the OAuth sign in -->
            <activity
                android:exported="true"
                android:name="com.esri.arcgisruntime.security.DefaultOAuthIntentReceiver"
                android:launchMode="singleTask">
                <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:host="@string/oauth_redirect_host"
                        android:scheme="authenticate-with-oauth" />
                </intent-filter>
            </activity>
    
        </application>
    
    Expand

Implement user authentication using OAuth credentials

ArcGIS Runtime provides an API that abstracts some of the details for user authentication using OAuth 2.0 in your app. You can use classes like AuthenticationManager to request, store, and manage credentials for secure resources.

Add code to set up the AuthenticationManager . This launches a browser window that challenges the user for sign in credentials.

  1. In the setupMap() function, after the line that calls mapView.setViewpoint(), create an OAuthConfiguration .

    MainActivity.kt
    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
          mapView.setViewpoint(Viewpoint(34.02700, -118.80543, 72000.0))
    
          // set up an OAuth config with URL to portal, a Client ID and a Redirect URL
          val oAuthConfiguration = OAuthConfiguration(
            null, getString(R.string.oauth_client_id),
            getString(R.string.oauth_redirect_uri) + "://" + getString(R.string.oauth_redirect_host)
          )
    
    
    Expand
  2. Create a DefaultAuthenticationChallengeHandler and set it on the AuthenticationManager . Then add the oAuthConfiguration to the AuthenticationManager.

    MainActivity.kt
    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
          mapView.setViewpoint(Viewpoint(34.02700, -118.80543, 72000.0))
    
          // set up an OAuth config with URL to portal, a Client ID and a Redirect URL
          val oAuthConfiguration = OAuthConfiguration(
            null, getString(R.string.oauth_client_id),
            getString(R.string.oauth_redirect_uri) + "://" + getString(R.string.oauth_redirect_host)
          )
    
          // setup AuthenticationManager to handle auth challenges
          val defaultAuthenticationChallengeHandler = DefaultAuthenticationChallengeHandler(this)
    
          // use the DefaultChallengeHandler to handle authentication challenges
          AuthenticationManager.setAuthenticationChallengeHandler(
            defaultAuthenticationChallengeHandler
          )
    
          // add an OAuth configuration
          // NOTE: you must add the DefaultOAuthIntentReceiver Activity to the app's manifest to handle starting a browser
          AuthenticationManager.addOAuthConfiguration(oAuthConfiguration)
    
    Expand

Add a traffic layer

You will add a layer to display the ArcGIS World Traffic service, a dynamic map service that presents historical and near real-time traffic information for different regions in the world. This service requires an ArcGIS Online organizational subscription.

Finally, you will add error code that catches a malformed URL and displays a Toast with the error message.

  1. Create an ArcGISMapImageLayer to display the traffic service. Then add the layer to the map's collection of data layers (operational layers).

    MainActivity.kt
    Expand
    Use dark colors for code blocks
    98 99 100 101 102 103
    Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
          // add an OAuth configuration
          // NOTE: you must add the DefaultOAuthIntentReceiver Activity to the app's manifest to handle starting a browser
          AuthenticationManager.addOAuthConfiguration(oAuthConfiguration)
    
          val trafficLayer = ArcGISMapImageLayer("https://traffic.arcgis.com/arcgis/rest/services/World/Traffic/MapServer")
          map.operationalLayers.add(trafficLayer)
    
    Expand
  2. Enclose the code of setupMap() using a try clause. Follow the try with a catch clause that takes a MalformedURLException and calls logError().

    MainActivity.kt
    Expand
    Use dark colors for code blocks
    76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
    Add line.Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
      private fun setupMap() {
    
        try {
    
          val map = ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC)
    
          mapView.map = map
    
          mapView.setViewpoint(Viewpoint(34.02700, -118.80543, 72000.0))
    
          // set up an OAuth config with URL to portal, a Client ID and a Redirect URL
          val oAuthConfiguration = OAuthConfiguration(
            null, getString(R.string.oauth_client_id),
            getString(R.string.oauth_redirect_uri) + "://" + getString(R.string.oauth_redirect_host)
          )
    
          // setup AuthenticationManager to handle auth challenges
          val defaultAuthenticationChallengeHandler = DefaultAuthenticationChallengeHandler(this)
    
          // use the DefaultChallengeHandler to handle authentication challenges
          AuthenticationManager.setAuthenticationChallengeHandler(
            defaultAuthenticationChallengeHandler
          )
    
          // add an OAuth configuration
          // NOTE: you must add the DefaultOAuthIntentReceiver Activity to the app's manifest to handle starting a browser
          AuthenticationManager.addOAuthConfiguration(oAuthConfiguration)
    
          val trafficLayer = ArcGISMapImageLayer("https://traffic.arcgis.com/arcgis/rest/services/World/Traffic/MapServer")
          map.operationalLayers.add(trafficLayer)
    
        }
    
        catch (e: MalformedURLException) {
          logError("Error in OAuthConfiguration URL: " + e.message)
        }
    
      }
    
    Expand
  3. Within the MainActivity class, create the logError() function that takes a String parameter and displays a Toast containing the message.

    MainActivity.kt
    Expand
    Use dark colors for code blocks
    115 116 117 118 119 120 121 122 123 124
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
      /**
       * Log an error to logcat and to the screen via Toast.
       * @param message the text to log.
       */
      private fun logError(message: String?) {
        message?.let {
          Log.e(TAG, message)
          Toast.makeText(this, message, Toast.LENGTH_LONG).show()
        }
      }
    
    Expand
  4. Click Run > Run > app to run the app.

You should see the map with the topographic basemap layer centered on the Santa Monica Mountains in California. You will also see the traffic layer, with its symbology of green, yellow, orange, and red roads to indicate current traffic flow. This is a secured layer, which is visible in your app because the user has entered valid ArcGIS Online username and password.

ArcGIS World Traffic service layer

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.