Migrate authentication from 100.x to 200.x

Use the information in this topic to migrate authentication code and programming patterns implemented in your existing ArcGIS Runtime SDK for iOS (100.x) applications to the ArcGIS Maps SDK for Swift (200.x). There are two main approaches for handling authentication:

Default handling of authentication challenges

When you built an application with ArcGIS Runtime SDK for iOS (100.x) that accessed secured resources, the API used a default challenge handler that automatically displayed a login UI to the user. This UI presented information about the challenge as well as the appropriate options, such as username and password inputs. This default handler and UI are not available with the ArcGIS Maps SDK for Swift.

You have two options for handling authentication challenges in your ArcGIS Maps SDK for Swift application:

  1. Use the Authenticator component, provided by the ArcGIS Maps SDK for Swift toolkit, to handle authentication challenges, such as ArcGIS authentication (token and OAuth), Integrated Windows Authentication (IWA), and Client Certificate (PKI). The component provides a default UI for login prompts, certificate selection prompts, and server trust prompts. For more information about setting up the tool, persisting credential stores, revoking tokens and clearing credentials, see the Authentication tool section in the security and authentication topic. To see the Authenticator in action, check out out the Authentication Example application and refer to AuthenticationApp.swift in your project.

  2. Set up an ArcGISAuthenticationChallengeHandler and NetworkAuthenticationChallengeHandler to capture the authentication challenges. Write your own code to present a UI with login prompts, certificate selection prompts, or server trust prompts. Use the response to create an appropriate credential so that the application can continue with the challenge. For more information, see Handle authentication challenges in the security and authentication topic.

Authentication manager

Access to secured resources is managed using the authentication manager, which you can now obtain directly from the ArcGISEnvironment.

Use dark colors for code blocksCopy
                                                                                                                                                                                                   
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
ArcGISEnvironment.authenticationManager

Authentication challenge handlers

ArcGIS and network authentication challenges were previously handled using a single AGSAuthenticationManagerDelegate. With ArcGIS Maps SDK for Swift, you must create separate authentication challenge handlers that respond to any ArcGISAuthenticationChallenge or NetworkAuthenticationChallenge. Set the ArcGIS and network authentication challenge handlers on the AuthenticationManager.

Use dark colors for code blocksCopy
                                                                                                                                                                                                   
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
// Create an ArcGIS authentication challenge handler
final class MyArcGISChallengeHandler: ArcGISAuthenticationChallengeHandler {
    /// The OAuth configurations that this challenge handler can work with.
    let oAuthUserConfigurations: [OAuthUserConfiguration]

    public init(
        oAuthUserConfigurations: [OAuthUserConfiguration] = []
    ) {
        self.oAuthUserConfigurations = oAuthUserConfigurations
    }

    /// Handle the challenge to an ArcGIS secured resource that requires OAuth or ArcGIS Token authentication.
    func handleArcGISAuthenticationChallenge(
        _ challenge: ArcGISAuthenticationChallenge
    ) async throws -> ArcGISAuthenticationChallenge.Disposition {
        // If an OAuth user configuration is available for the challenge then create an `OAuthUserCredential`.
        if let configuration = oAuthUserConfigurations.first(where: { $0.canBeUsed(for: challenge.requestURL) }) {
            return .continueWithCredential(
                try await OAuthUserCredential.credential(for: configuration)
            )
        } else {
            // If not, prompt the user for a username and password to create a `TokenCredential`.
            ///...
            return .continueWithCredential(
                try await TokenCredential.credential(for: challenge, username: "username", password: "password")
            )
        }
    }
}

/// Create the challenge handler with desired OAuth user configurations and set it on the `AuthenticationManager`.
let myArcGISChallengeHandler = MyArcGISChallengeHandler(oAuthUserConfigurations: [<OAuthUserConfiguration>])
ArcGISEnvironment.authenticationManager.arcGISAuthenticationChallengeHandler = myArcGISChallengeHandler

// Create a Network authentication challenge handler
final class MyNetworkChallengeHandler: NetworkAuthenticationChallengeHandler {
    func handleNetworkAuthenticationChallenge(
        _ challenge: NetworkAuthenticationChallenge
    ) async -> NetworkAuthenticationChallenge.Disposition {
        switch challenge.kind {
        case .ntlm, .basic, .digest:
            // Prompt the user for a username and password to create a `NetworkCredential`.
            // ...
            return .continueWithCredential(.password(username: "username", password: "password"))
        case .clientCertificate:
            // Prompt the user for a client certificate to create a `NetworkCredential`.
            // ...
            return .continueWithCredential(.certificate(at: <certificate file url>, password: "password"))
        case .serverTrust:
            // Prompt user to ask if they want to trust an untrusted host.
            // ...
            return .continueWithCredential(.serverTrust)
        }
    }
}
// Create the challenge handler and set it on the `AuthenticationManager`.
let myNetworkChallengeHandler = MyNetworkChallengeHandler()
ArcGISEnvironment.authenticationManager.networkAuthenticationChallengeHandler = myNetworkChallengeHandler

Credentials

ArcGIS Runtime SDK for iOS handled a variety of credentials using the AGSCredential and AGSOAuthConfiguration classes. ArcGIS Maps SDK for Swift uses a range of specialized credential types to match the ArcGIS credentials (OAuthUserCredential, TokenCredential, and PregeneratedTokenCredential) and network credentials (CertificateCredential and PasswordCredential). You can write code in an authentication challenge handler to prompt the user for credential information, create a credential, and use it to continue with the challenge. This credential will be placed in the store and used by future requests coming from the same source.

You can also create ArcGIS credentials preemptively and store them in ArcGISCredentialStore.

OAuth

In your ArcGIS Maps SDK for Swift application, use OAuthUserCredential to handle OAuth authentication challenges for Portal. Previously, these challenges were handled by adding an OAuth configuration (AGSOAuthConfiguration) to the AGSAuthenticationManager.shared().oAuthConfigurations.

Use dark colors for code blocksCopy
                                                                                                                                                                                                   
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
// OAuth user credential
let configuration = OAuthUserConfiguration(portalURL: <portal URL>, clientID: "<client ID>", redirectURL: <redirect URL>)
let oauthUserCredential = try await OAuthUserCredential.credential(for: configuration)

Token

Use dark colors for code blocksCopy
                                                                                                                                                                                                   
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
// Token credential
let tokenCredential = try await TokenCredential.credential(for: <service URL>, username: "<username>", password: "<password>", tokenExpirationMinutes: <minutes>)
let tokenInfo = try await credential.tokenInfo

Pregenerated token

Use dark colors for code blocksCopy
                                                                                                                                                                                                   
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
// Pregenerated token credential
let tokenInfo = TokenInfo(accessToken: "<access token>", expirationDate: <expiration date>, isSSLRequired: true)
let pregeneratedTokenCredential = PregeneratedTokenCredential(url: <service URL>, tokenInfo: tokenInfo, referer: "<referer>")

Client-side certificate

Use dark colors for code blocksCopy
                                                                                                                                                                                                   
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
// Client certificate credential
let certificateCredential = NetworkCredential.certificate(at: <file url to .p12/.pfx>, password: "<password>")

Username and password

Use dark colors for code blocksCopy
                                                                                                                                                                                                   
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
// Password credential for HTTP Basic/Digest, Integrated Windows Authentication (IWA)
let passwordCredential = NetworkCredential.password(username: "<username>", password: "<password>")

Trust servers

Previously, you could avoid server trust challenges by preemptively adding the host to the AGSAuthenticationManager.shared().trustedHosts collection. The ArcGIS Maps SDK for Swift now uses the NetworkCredential.serverTrust to handle server trust challenges. If you handle a trust challenge with a credential, it will be placed in the store and used by future trust challenges.

Use dark colors for code blocksCopy
                                                                                                                                                                                                   
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
// Server trust credential for host with self-signed certificate
let credential = NetworkCredential.serverTrust

Store and persist credentials

ArcGIS and network credentials were previously held in a single AGSCredentialCache. With ArcGIS Maps SDK for Swift, the authentication manager has separate credential stores that exist for the lifetime of the application. These are ArcGISCredentialStore and NetworkCredentialStore.

Use dark colors for code blocksCopy
                                                                                                                                                                                                   
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
ArcGISEnvironment.authenticationManager.arcGISCredentialStore
ArcGISEnvironment.authenticationManager.networkCredentialStore

To make the credential stores persist in the keychain, set the store instances created using function makePersistent(access:synchronizesWithiCloud:) on the authentication manager.

Use dark colors for code blocksCopy
                                                                                                                                                                                                   
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
ArcGISEnvironment.authenticationManager.arcGISCredentialStore = try await .makePersistent(
    access: .afterFirstUnlockThisDeviceOnly,
    synchronizesWithiCloud: <true/false>
)
await ArcGISEnvironment.authenticationManager.setNetworkCredentialStore(
    try await .makePersistent(access: .afterFirstUnlockThisDeviceOnly, synchronizesWithiCloud: <true/false>)
)

Previously, you could create and set a credential preemptively on a specific object. With ArcGIS Maps SDK for Swift, you can add the credential to the store before any secure resources are loaded.

Use dark colors for code blocksCopy
                                                                                                                                                                                                   
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
let tokenCredential = try await TokenCredential.credential(
    for: URL(string: "https://www.arcgis.com")!,
    username: "<username>",
    password: "<password>"
)
ArcGISEnvironment.authenticationManager.arcGISCredentialStore.add(tokenCredential)

let portal = Portal.arcGISOnline(connection: .authenticated)
try await portal.load()

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