Repository: Esri/arcgis-maps-sdk-swift-samples
Pull request #611: [New] Authenticate with integrated windows authentication
Author: login: rolson
Created: 2025-05-13T18:31:32Z | Merged: 2025-05-14T16:05:35Z

## Description

This PR implements `AuthenticateWithIntegratedWindowsAuthentication` in `Cloud and Portal` category.
URL to README: 

## Linked Issue(s)

- `swift/issues/6857`

## How To Test

- Run the sample
- enter a URL to an IWA secured portal.
- Select a webmap

If your portal has a self-signed certificate, then add:

```
		<key>NSAllowsArbitraryLoads</key>
		<true/>
```

To iOS/Info.plist under the key:

```
<key>NSAppTransportSecurity</key>
```

## Screenshots
![authenticate-with-integrated-windows-authentication-1](https://github.com/user-attachments/assets/d655ad88-de7e-45b5-b7a3-a9a096f9860a)
![authenticate-with-integrated-windows-authentication-2](https://github.com/user-attachments/assets/12de8e36-aaac-4ae7-a9fc-f2368f30e5c5)
![authenticate-with-integrated-windows-authentication-3](https://github.com/user-attachments/assets/6b22cdb1-0970-42b8-a32a-efa84e40ebdf)




Diff:
diff --git a/Samples.xcodeproj/project.pbxproj b/Samples.xcodeproj/project.pbxproj
index 0fdd9d362..b29027d8b 100644
--- a/Samples.xcodeproj/project.pbxproj
+++ b/Samples.xcodeproj/project.pbxproj
@@ -246,6 +246,8 @@
 		88FB70392DCC207B00EB76E3 /* ApplySymbologyToShapefileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88FB70382DCC207B00EB76E3 /* ApplySymbologyToShapefileView.swift */; };
 		88FB703C2DCC22E900EB76E3 /* ApplySymbologyToShapefileView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = 88FB70382DCC207B00EB76E3 /* ApplySymbologyToShapefileView.swift */; };
 		88FB70D12DCC248400EB76E3 /* Aurora_CO_shp in Resources */ = {isa = PBXBuildFile; fileRef = 88FB70D02DCC247B00EB76E3 /* Aurora_CO_shp */; settings = {ASSET_TAGS = (ApplySymbologyToShapefile, ); }; };
+		88FB70D42DCD10B600EB76E3 /* AuthenticateWithIntegratedWindowsAuthenticationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88FB70D32DCD10B600EB76E3 /* AuthenticateWithIntegratedWindowsAuthenticationView.swift */; };
+		88FB70D52DD3C2E000EB76E3 /* AuthenticateWithIntegratedWindowsAuthenticationView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = 88FB70D32DCD10B600EB76E3 /* AuthenticateWithIntegratedWindowsAuthenticationView.swift */; };
 		9503056E2C46ECB70091B32D /* ShowDeviceLocationUsingIndoorPositioningView.Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9503056D2C46ECB70091B32D /* ShowDeviceLocationUsingIndoorPositioningView.Model.swift */; };
 		9529D1942C01676200B5C1A3 /* SelectFeaturesInSceneLayerView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = 954AEDED2C01332600265114 /* SelectFeaturesInSceneLayerView.swift */; };
 		9537AFD72C220EF0000923C5 /* ExchangeSetwithoutUpdates in Resources */ = {isa = PBXBuildFile; fileRef = 9537AFD62C220EF0000923C5 /* ExchangeSetwithoutUpdates */; settings = {ASSET_TAGS = (ConfigureElectronicNavigationalCharts, ); }; };
@@ -653,6 +655,7 @@
 			dstPath = "";
 			dstSubfolderSpec = 7;
 			files = (
+				88FB70D52DD3C2E000EB76E3 /* AuthenticateWithIntegratedWindowsAuthenticationView.swift in Copy Source Code Files */,
 				88FB703C2DCC22E900EB76E3 /* ApplySymbologyToShapefileView.swift in Copy Source Code Files */,
 				88C5E0EC2DCBC3F30091D271 /* ApplyScenePropertyExpressionsView.swift in Copy Source Code Files */,
 				00FA4E8D2DCD7536008A34CF /* ApplySimpleRendererToGraphicsOverlayView.swift in Copy Source Code Files */,
@@ -1047,6 +1050,7 @@
 		88F93CC029C3D59C0006B28E /* CreateAndEditGeometriesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateAndEditGeometriesView.swift; sourceTree = "<group>"; };
 		88FB70382DCC207B00EB76E3 /* ApplySymbologyToShapefileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplySymbologyToShapefileView.swift; sourceTree = "<group>"; };
 		88FB70D02DCC247B00EB76E3 /* Aurora_CO_shp */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Aurora_CO_shp; sourceTree = "<group>"; };
+		88FB70D32DCD10B600EB76E3 /* AuthenticateWithIntegratedWindowsAuthenticationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticateWithIntegratedWindowsAuthenticationView.swift; sourceTree = "<group>"; };
 		9503056D2C46ECB70091B32D /* ShowDeviceLocationUsingIndoorPositioningView.Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowDeviceLocationUsingIndoorPositioningView.Model.swift; sourceTree = "<group>"; };
 		9537AFD62C220EF0000923C5 /* ExchangeSetwithoutUpdates */ = {isa = PBXFileReference; lastKnownFileType = folder; path = ExchangeSetwithoutUpdates; sourceTree = "<group>"; };
 		9547085B2C3C719800CA8579 /* EditFeatureAttachmentsView.Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditFeatureAttachmentsView.Model.swift; sourceTree = "<group>"; };
@@ -1467,6 +1471,7 @@
 				1C2538472BABAC7B00337307 /* Augment reality to navigate route */,
 				D7A737DF2BABB9FE00B7C7FC /* Augment reality to show hidden infrastructure */,
 				D72F27292ADA1E4400F906DA /* Augment reality to show tabletop scene */,
+				88FB70D22DCD10A500EB76E3 /* Authenticate with Integrated Windows Authentication */,
 				218F35B229C28F4A00502022 /* Authenticate with OAuth */,
 				E0FE32E528747762002C6ACA /* Browse building floors */,
 				95E980732C26185000CB8912 /* Browse OGC API feature service */,
@@ -2279,6 +2284,14 @@
 			path = d98b3e5293834c5f852f13c569930caa;
 			sourceTree = "<group>";
 		};
+		88FB70D22DCD10A500EB76E3 /* Authenticate with Integrated Windows Authentication */ = {
+			isa = PBXGroup;
+			children = (
+				88FB70D32DCD10B600EB76E3 /* AuthenticateWithIntegratedWindowsAuthenticationView.swift */,
+			);
+			path = "Authenticate with Integrated Windows Authentication";
+			sourceTree = "<group>";
+		};
 		9537AFC82C220ECB000923C5 /* 9d2987a825c646468b3ce7512fb76e2d */ = {
 			isa = PBXGroup;
 			children = (
@@ -4054,6 +4067,7 @@
 				D7114A0D2BDC6A3300FA68CA /* EditWithBranchVersioningView.Model.swift in Sources */,
 				00B04FB5283EEBA80026C882 /* DisplayOverviewMapView.swift in Sources */,
 				D718A1E72B570F7500447087 /* OrbitCameraAroundObjectView.Model.swift in Sources */,
+				88FB70D42DCD10B600EB76E3 /* AuthenticateWithIntegratedWindowsAuthenticationView.swift in Sources */,
 				88E52E812DCA703B00F48409 /* ApplyHillshadeRendererToRasterView.SettingsView.swift in Sources */,
 				D71C5F642AAA7A88006599FD /* CreateSymbolStylesFromWebStylesView.swift in Sources */,
 				D7CC33FF2A31475C00198EDF /* ShowLineOfSightBetweenPointsView.swift in Sources */,
diff --git a/Scripts/CI/common.py b/Scripts/CI/common.py
index 5f6ac6cb7..e3ec91db2 100644
--- a/Scripts/CI/common.py
+++ b/Scripts/CI/common.py
@@ -26,6 +26,7 @@
     'Arcade',
     'ArcGIS Online',
     'ArcGIS Pro',
+    'Authenticate with Integrated Windows Authentication',
     'GeoPackage',
     'OAuth',
     'OpenStreetMap',
diff --git a/Shared/Samples/Authenticate with Integrated Windows Authentication/AuthenticateWithIntegratedWindowsAuthenticationView.swift b/Shared/Samples/Authenticate with Integrated Windows Authentication/AuthenticateWithIntegratedWindowsAuthenticationView.swift
new file mode 100644
index 000000000..37578a712
--- /dev/null
+++ b/Shared/Samples/Authenticate with Integrated Windows Authentication/AuthenticateWithIntegratedWindowsAuthenticationView.swift	
@@ -0,0 +1,189 @@
+// Copyright 2025 Esri
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//   https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import ArcGIS
+import ArcGISToolkit
+import SwiftUI
+
+struct AuthenticateWithIntegratedWindowsAuthenticationView: View {
+    /// The model that backs this view.
+    @StateObject private var model = Model()
+    
+    var body: some View {
+        Form {
+            switch model.portalContent {
+            case .success(let success):
+                ForEach(success.results, id: \.id?.rawValue) { item in
+                    Button(item.title) {
+                        model.selectedItem = .init(portalItem: item)
+                    }
+                    .buttonStyle(.plain)
+                }
+            case .failure:
+                urlEntryView
+                ContentUnavailableView(
+                    "Error",
+                    systemImage: "exclamationmark.triangle",
+                    description: Text("Error searching specified portal.")
+                )
+            case nil:
+                if model.isConnecting {
+                    ProgressView()
+                        .frame(maxWidth: .infinity)
+                } else {
+                    urlEntryView
+                }
+            }
+        }
+        .onDisappear {
+            Task {
+                // Reset the challenge handlers and clear credentials
+                // when the view disappears so that user is prompted to enter
+                // credentials every time the sample is run, and to clean
+                // the environment for other samples.
+                await model.teardownAuthenticator()
+            }
+        }
+        .sheet(item: $model.selectedItem) { selectedItem in
+            NavigationStack {
+                MapView(map: Map(item: selectedItem.portalItem))
+                    .navigationTitle(selectedItem.portalItem.title)
+                    .navigationBarTitleDisplayMode(.inline)
+                    .toolbar {
+                        ToolbarItem(placement: .topBarTrailing) {
+                            Button("Done") {
+                                model.selectedItem = nil
+                            }
+                        }
+                    }
+            }
+            .interactiveDismissDisabled()
+            .highPriorityGesture(DragGesture())
+            .pagePresentation()
+        }
+        .animation(.default, value: model.isConnecting)
+        .authenticator(model.authenticator)
+    }
+    
+    @ViewBuilder private var urlEntryView: some View {
+        Section {
+            HStack {
+                TextField("IWA Secured Portal URL", text: $model.portalURLString)
+                    .onSubmit { Task { await model.connectToPortal() } }
+                    .autocapitalization(.none)
+                    .keyboardType(.URL)
+                Button("Connect") {
+                    Task { await model.connectToPortal() }
+                }
+                .disabled(model.portalURL == nil)
+            }
+        }
+    }
+}
+
+/// A value that represents an item selected by the user.
+private struct SelectedItem: Identifiable {
+    /// The portal item that was selected.
+    let portalItem: PortalItem
+    
+    var id: ObjectIdentifier {
+        ObjectIdentifier(portalItem)
+    }
+}
+
+extension AuthenticateWithIntegratedWindowsAuthenticationView {
+    @MainActor
+    class Model: ObservableObject {
+        /// The authenticator to handle authentication challenges.
+        let authenticator = Authenticator()
+        
+        /// The URL string entered by the user.
+        @Published var portalURLString = ""
+        
+        /// The fetched portal content.
+        @Published var portalContent: Result<PortalQueryResultSet<PortalItem>, Error>?
+        
+        /// A Boolean value indicating if a portal connection is in progress.
+        @Published var isConnecting = false
+        
+        /// The selected item.
+        @Published fileprivate var selectedItem: SelectedItem?
+        
+        /// The URL of the portal.
+        var portalURL: URL? { URL(string: portalURLString) }
+        
+        init() {
+            setupAuthenticator()
+        }
+        
+        /// Connects to the portal and finds a batch of webmaps.
+        func connectToPortal() async {
+            precondition(portalURL != nil)
+            
+            isConnecting = true
+            defer { isConnecting = false }
+            
+            do {
+                let portal = Portal(url: portalURL!)
+                try await portal.load()
+                let results = try await portal.findItems(queryParameters: .items(ofKinds: [.webMap]))
+                portalContent = .success(results)
+            } catch {
+                portalContent = .failure(error)
+            }
+        }
+        
+        /// Sets up the authenticator to handle challenges.
+        private func setupAuthenticator() {
+            // Setting the challenge handlers here when the model is created so user is prompted to enter
+            // credentials every time trying the sample. In real world applications, set challenge
+            // handlers at the start of the application.
+            
+            // Sets authenticator as ArcGIS and Network challenge handlers to handle authentication
+            // challenges.
+            ArcGISEnvironment.authenticationManager.handleChallenges(using: authenticator)
+            
+            // In your application you may want to uncomment this code to persist
+            // credentials in the keychain.
+            // setupPersistentCredentialStorage()
+        }
+        
+        /// Stops the authenticator from handling the challenges and clears credentials.
+        nonisolated func teardownAuthenticator() async {
+            // Resets challenge handlers.
+            ArcGISEnvironment.authenticationManager.handleChallenges(using: nil)
+            
+            // In your application, code may need to run at a different
+            // point in time based on the workflow desired. For example, it
+            // might make sense to remove credentials when the user taps
+            // a "sign out" button.
+            await ArcGISEnvironment.authenticationManager.revokeOAuthTokens()
+            await ArcGISEnvironment.authenticationManager.clearCredentialStores()
+        }
+        
+        /// Sets up new ArcGIS and Network credential stores that will be persisted in the keychain.
+        private func setupPersistentCredentialStorage() {
+            Task {
+                try await ArcGISEnvironment.authenticationManager.setupPersistentCredentialStorage(
+                    access: .whenUnlockedThisDeviceOnly,
+                    synchronizesWithiCloud: false
+                )
+            }
+        }
+    }
+}
+
+#Preview {
+    AuthenticateWithIntegratedWindowsAuthenticationView()
+}
diff --git a/Shared/Samples/Authenticate with Integrated Windows Authentication/README.md b/Shared/Samples/Authenticate with Integrated Windows Authentication/README.md
new file mode 100644
index 000000000..4ef2a3fa1
--- /dev/null
+++ b/Shared/Samples/Authenticate with Integrated Windows Authentication/README.md	
@@ -0,0 +1,48 @@
+# Authenticate with Integrated Windows Authentication
+
+Connect to an IWA secured Portal and search for maps.
+
+![Image of authenticate with integrated windows authentication](authenticate-with-integrated-windows-authentication-1.png)
+
+## Use case
+
+Your organization might use Integrated Windows Authentication (IWA) to secure ArcGIS Enterprise. This can be useful because the same credentials used to log into your work computer and network can be used to authenticate with ArcGIS. IWA is built into Microsoft Internet Information Server (IIS) and works well for intranet applications but isn't always practical for internet apps.
+
+## How to use the sample
+
+1. Enter the URL to your IWA-secured portal.
+2. Click the connect button to search for web maps stored on the portal.
+3. You will be prompted for a user name, and password.
+4. If you authenticate successfully, portal item results will display in the list.
+5. Select a web map item to display it in the map view.
+
+## How it works
+
+1. The `AuthenticationManager` object is configured with a challenge handler that will prompt for a Windows login (username and password) if a secure resource is encountered.
+2. When a search for portal items is performed against an IWA-secured portal, the `Authenticator` creates a `NetworkCredential` from the information entered by the user.
+3. If the user authenticates, the search returns a list of web maps (`PortalItem`) and the user can select one to display as a `Map`.
+
+## Relevant API
+
+* ArcGISEnvironment
+* AuthenticationManager
+* Authenticator
+* Portal
+
+## About the data
+
+This sample searches for web map portal items on a secure portal. To successfully run the sample, you need:
+
+* Access to a portal secured with Integrated Windows Authentication that contains one or more web map items.
+* A login that grants you access to the portal.
+
+## Additional information
+
+More information about IWA and its use with ArcGIS can be found at the following links:
+
+* [IWA - Wikipedia](https://en.wikipedia.org/wiki/Integrated_Windows_Authentication)
+* [Use Integrated Windows Authentication with your portal](http://enterprise.arcgis.com/en/portal/latest/administer/windows/use-integrated-windows-authentication-with-your-portal.htm)
+
+## Tags
+
+authentication, security, Windows
diff --git a/Shared/Samples/Authenticate with Integrated Windows Authentication/README.metadata.json b/Shared/Samples/Authenticate with Integrated Windows Authentication/README.metadata.json
new file mode 100644
index 000000000..df4072de0
--- /dev/null
+++ b/Shared/Samples/Authenticate with Integrated Windows Authentication/README.metadata.json	
@@ -0,0 +1,30 @@
+{
+    "category": "Cloud and Portal",
+    "description": "Connect to an IWA secured Portal and search for maps.",
+    "ignore": false,
+    "images": [
+        "authenticate-with-integrated-windows-authentication-1.png",
+        "authenticate-with-integrated-windows-authentication-2.png",
+        "authenticate-with-integrated-windows-authentication-3.png"
+    ],
+    "keywords": [
+        "Windows",
+        "authentication",
+        "security",
+        "ArcGISEnvironment",
+        "AuthenticationManager",
+        "Authenticator",
+        "Portal"
+    ],
+    "redirect_from": [],
+    "relevant_apis": [
+        "ArcGISEnvironment",
+        "AuthenticationManager",
+        "Authenticator",
+        "Portal"
+    ],
+    "snippets": [
+        "AuthenticateWithIntegratedWindowsAuthenticationView.swift"
+    ],
+    "title": "Authenticate with Integrated Windows Authentication"
+}
diff --git a/Shared/Samples/Authenticate with Integrated Windows Authentication/authenticate-with-integrated-windows-authentication-1.png b/Shared/Samples/Authenticate with Integrated Windows Authentication/authenticate-with-integrated-windows-authentication-1.png
new file mode 100644
index 000000000..d597c5b78
Binary files /dev/null and b/Shared/Samples/Authenticate with Integrated Windows Authentication/authenticate-with-integrated-windows-authentication-1.png differ
diff --git a/Shared/Samples/Authenticate with Integrated Windows Authentication/authenticate-with-integrated-windows-authentication-2.png b/Shared/Samples/Authenticate with Integrated Windows Authentication/authenticate-with-integrated-windows-authentication-2.png
new file mode 100644
index 000000000..1290442be
Binary files /dev/null and b/Shared/Samples/Authenticate with Integrated Windows Authentication/authenticate-with-integrated-windows-authentication-2.png differ
diff --git a/Shared/Samples/Authenticate with Integrated Windows Authentication/authenticate-with-integrated-windows-authentication-3.png b/Shared/Samples/Authenticate with Integrated Windows Authentication/authenticate-with-integrated-windows-authentication-3.png
new file mode 100644
index 000000000..e8a4acbbc
Binary files /dev/null and b/Shared/Samples/Authenticate with Integrated Windows Authentication/authenticate-with-integrated-windows-authentication-3.png differ


Reviews:
user: login: yo1995
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-13T19:17:23Z
user: login: yo1995
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-13T19:20:56Z
user: login: rolson
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-13T19:21:25Z
user: login: yo1995
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-13T20:20:13Z
user: login: pgruenler
state: DISMISSED
author_association: COLLABORATOR
submitted_at: 2025-05-13T22:59:28Z
user: login: njarecha
body: Couple of suggestions 
state: CHANGES_REQUESTED
author_association: COLLABORATOR
submitted_at: 2025-05-13T23:56:50Z
user: login: njarecha
body: Looks good
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-14T15:24:43Z
user: login: pgruenler
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-14T15:27:20Z

Review comments:
path: Shared/Samples/Authenticate with Integrated Windows Authentication/README.metadata.json
user: login: yo1995
body: To pass the status checker, feel free to use `python Scripts/create-metadata-from-README.py -c "Shared/Samples/Authenticate with Integrated Windows Authentication/README.metadata.json"` to generate a template JSON, then fill in the category. The metadata needs to follow a specific format request by the docs team, so the generated json is easier to begin with.
created_at: 2025-05-13T19:17:23Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,48 @@
+# Authenticate with Integrated Windows Authentication
path: Shared/Samples/Authenticate with Integrated Windows Authentication/README.md
user: login: yo1995
body: Add "Authenticate with Integrated Windows Authentication" to this list: https://github.com/Esri/arcgis-maps-sdk-swift-samples/blob/beab5d441fac2da56d2cad29fd849226aa0f14be/Scripts/CI/common.py#L25 so the title is in the exception.
created_at: 2025-05-13T19:20:56Z
author_association: COLLABORATOR
path: Shared/Samples/Authenticate with Integrated Windows Authentication/README.metadata.json
user: login: rolson
body: Ok... But how is "Windows" the right order?

![Uploading image.png…]()

created_at: 2025-05-13T19:21:25Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,48 @@
+# Authenticate with Integrated Windows Authentication
+
+Connect to an IWA secured Portal and search for maps.
+
+![Image of authenticate with integrated windows authentication](authenticate-with-integrated-windows-authentication-1.png)
+
+## Use case
+
+Your organization might use Integrated Windows Authentication (IWA) to secure ArcGIS Enterprise. This can be useful because the same credentials used to log into your work computer and network can be used to authenticate with ArcGIS. IWA is built into Microsoft Internet Information Server (IIS) and works well for intranet applications but isn't always practical for internet apps.
+
+## How to use the sample
+
+1. Enter the URL to your IWA-secured portal.
+2. Click the connect button to search for web maps stored on the portal.
+3. You will be prompted for a user name, and password.
+4. If you authenticate successfully, portal item results will display in the list.
+5. Select a web map item to display it in the map view.
+
+## How it works
+
+1. The `AuthenticationManager` object is configured with a challenge handler that will prompt for a Windows login (username, password, and domain) if a secure resource is encountered.
+2. When a search for portal items is performed against an IWA-secured portal, the `Authenticator` creates a `NetworkCredential` from the information entered by the user.
+3. If the user authenticates, the search returns a list of web maps (`PortalItem`) and the user can select one to display as a `Map`.
+
+## Relevant API
+
+* ArcGISEnvironment
+* AuthenticationManager
+* Authenticator
+* Portal
+
+## About the data
+
+This sample searches for web map portal items on a secure portal. To successfully run the sample, you need:
+
+* Access to a portal secured with Integrated Windows Authentication that contains one or more web map items.
+* A login that grants you access to the portal.
+
+## Additional information
+
+More information about IWA and its use with ArcGIS can be found at the following links:
+
+* [IWA - Wikipedia](https://en.wikipedia.org/wiki/Integrated_Windows_Authentication)
+* [Use Integrated Windows Authentication with your portal](http://enterprise.arcgis.com/en/portal/latest/administer/windows/use-integrated-windows-authentication-with-your-portal.htm)
+
+## Tags
+
+authentication, Portal, security, Windows
path: Shared/Samples/Authenticate with Integrated Windows Authentication/README.md
user: login: yo1995
body: ```suggestion
authentication, security, Windows
```
This should pass the status check
created_at: 2025-05-13T20:19:26Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,189 @@
+// Copyright 2025 Esri
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//   https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import ArcGIS
+import ArcGISToolkit
+import SwiftUI
+
+struct AuthenticateWithIntegratedWindowsAuthenticationView: View {
+    /// The model that backs this view.
+    @StateObject private var model = Model()
+    
+    var body: some View {
+        Form {
+            switch model.portalContent {
+            case .success(let success):
+                ForEach(success.results, id: \.id?.rawValue) { item in
+                    Button(item.title) {
+                        model.selectedItem = .init(portalItem: item)
+                    }
+                    .buttonStyle(.plain)
+                }
+            case .failure:
+                urlEntryView
+                ContentUnavailableView(
+                    "Error",
+                    systemImage: "exclamationmark.triangle",
+                    description: Text("Error searching specified portal.")
+                )
+            case nil:
+                if model.isConnecting {
+                    ProgressView()
+                        .frame(maxWidth: .infinity)
+                } else {
+                    urlEntryView
+                }
+            }
+        }
+        .onDisappear {
+            Task {
+                // Reset the challenge handlers and clear credentials
+                // when the view disappears so that user is prompted to enter
+                // credentials every time the sample is run, and to clean
+                // the environment for other samples.
+                await model.teardownAuthenticator()
+            }
+        }
+        .sheet(item: $model.selectedItem) { selectedItem in
+            NavigationStack {
+                MapView(map: Map(item: selectedItem.portalItem))
+                    .navigationTitle(selectedItem.portalItem.title)
+                    .navigationBarTitleDisplayMode(.inline)
+                    .toolbar {
+                        ToolbarItem(placement: .topBarTrailing) {
+                            Button("Done") {
+                                model.selectedItem = nil
+                            }
+                        }
+                    }
+            }
+            .interactiveDismissDisabled()
+            .highPriorityGesture(DragGesture())
+            .pagePresentation()
+        }
+        .animation(.default, value: model.isConnecting)
+        .authenticator(model.authenticator)
+    }
+    
+    @ViewBuilder private var urlEntryView: some View {
+        Section {
+            HStack {
+                TextField("IWA Secured Portal URL", text: $model.portalURLString)
+                    .onSubmit { Task { await model.connectToPortal() } }
+                    .autocapitalization(.none)
+                    .keyboardType(.URL)
+                Button("Connect") {
+                    Task { await model.connectToPortal() }
+                }
+                .disabled(model.portalURL == nil)
+            }
+        }
+    }
+}
+
+/// A value that represents an item selected by the user.
+private struct SelectedItem: Identifiable {
+    /// The portal item that was selected.
+    let portalItem: PortalItem
+    
+    var id: ObjectIdentifier {
+        ObjectIdentifier(portalItem)
+    }
+}
+
+extension AuthenticateWithIntegratedWindowsAuthenticationView {
+    @MainActor
+    class Model: ObservableObject {
+        /// The authenticator to handle authentication challenges.
+        let authenticator = Authenticator(promptForUntrustedHosts: true)
path: Shared/Samples/Authenticate with Integrated Windows Authentication/AuthenticateWithIntegratedWindowsAuthenticationView.swift
user: login: njarecha
body: The `promptForUntrustedHosts` should not be in the final sample. The project does have `NSAllowsArbitraryLoads: true` so untrusted prompt will not reach anyways.
```suggestion
        let authenticator = Authenticator()
```
created_at: 2025-05-13T23:22:38Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,189 @@
+// Copyright 2025 Esri
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//   https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import ArcGIS
+import ArcGISToolkit
+import SwiftUI
+
+struct AuthenticateWithIntegratedWindowsAuthenticationView: View {
+    /// The model that backs this view.
+    @StateObject private var model = Model()
+    
+    var body: some View {
+        Form {
+            switch model.portalContent {
+            case .success(let success):
+                ForEach(success.results, id: \.id?.rawValue) { item in
+                    Button(item.title) {
+                        model.selectedItem = .init(portalItem: item)
+                    }
+                    .buttonStyle(.plain)
+                }
+            case .failure:
+                urlEntryView
+                ContentUnavailableView(
+                    "Error",
+                    systemImage: "exclamationmark.triangle",
+                    description: Text("Error searching specified portal.")
+                )
+            case nil:
+                if model.isConnecting {
+                    ProgressView()
+                        .frame(maxWidth: .infinity)
+                } else {
+                    urlEntryView
+                }
+            }
+        }
+        .onDisappear {
+            Task {
+                // Reset the challenge handlers and clear credentials
+                // when the view disappears so that user is prompted to enter
+                // credentials every time the sample is run, and to clean
+                // the environment for other samples.
+                await model.teardownAuthenticator()
+            }
+        }
+        .sheet(item: $model.selectedItem) { selectedItem in
+            NavigationStack {
+                MapView(map: Map(item: selectedItem.portalItem))
+                    .navigationTitle(selectedItem.portalItem.title)
+                    .navigationBarTitleDisplayMode(.inline)
+                    .toolbar {
+                        ToolbarItem(placement: .topBarTrailing) {
+                            Button("Done") {
+                                model.selectedItem = nil
+                            }
+                        }
+                    }
+            }
+            .interactiveDismissDisabled()
+            .highPriorityGesture(DragGesture())
+            .pagePresentation()
+        }
+        .animation(.default, value: model.isConnecting)
+        .authenticator(model.authenticator)
+    }
+    
+    @ViewBuilder private var urlEntryView: some View {
+        Section {
+            HStack {
+                TextField("IWA Secured Portal URL", text: $model.portalURLString)
+                    .onSubmit { Task { await model.connectToPortal() } }
+                    .autocapitalization(.none)
+                    .keyboardType(.URL)
+                Button("Connect") {
+                    Task { await model.connectToPortal() }
+                }
+                .disabled(model.portalURL == nil)
+            }
+        }
+    }
+}
+
+/// A value that represents an item selected by the user.
+private struct SelectedItem: Identifiable {
+    /// The portal item that was selected.
+    let portalItem: PortalItem
+    
+    var id: ObjectIdentifier {
+        ObjectIdentifier(portalItem)
+    }
+}
+
+extension AuthenticateWithIntegratedWindowsAuthenticationView {
+    @MainActor
+    class Model: ObservableObject {
+        /// The authenticator to handle authentication challenges.
+        let authenticator = Authenticator(promptForUntrustedHosts: true)
+        
+        /// The URL string entered by the user.
+        @Published var portalURLString = ""
+        
+        /// The fetched portal content.
+        @Published var portalContent: Result<PortalQueryResultSet<PortalItem>, Error>?
+        
+        /// A Boolean value indicating if a portal connection is in progress.
+        @Published var isConnecting = false
+        
+        /// The selected item.
+        @Published fileprivate var selectedItem: SelectedItem?
+        
+        /// The URL to the portal.
path: Shared/Samples/Authenticate with Integrated Windows Authentication/AuthenticateWithIntegratedWindowsAuthenticationView.swift
user: login: njarecha
body: Should the be `of` the portal?
```suggestion
        /// The URL of the portal.
```
created_at: 2025-05-13T23:26:41Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,48 @@
+# Authenticate with Integrated Windows Authentication
+
+Connect to an IWA secured Portal and search for maps.
+
+![Image of authenticate with integrated windows authentication](authenticate-with-integrated-windows-authentication-1.png)
+
+## Use case
+
+Your organization might use Integrated Windows Authentication (IWA) to secure ArcGIS Enterprise. This can be useful because the same credentials used to log into your work computer and network can be used to authenticate with ArcGIS. IWA is built into Microsoft Internet Information Server (IIS) and works well for intranet applications but isn't always practical for internet apps.
+
+## How to use the sample
+
+1. Enter the URL to your IWA-secured portal.
+2. Click the connect button to search for web maps stored on the portal.
+3. You will be prompted for a user name, and password.
+4. If you authenticate successfully, portal item results will display in the list.
+5. Select a web map item to display it in the map view.
+
+## How it works
+
+1. The `AuthenticationManager` object is configured with a challenge handler that will prompt for a Windows login (username, password, and domain) if a secure resource is encountered.
path: Shared/Samples/Authenticate with Integrated Windows Authentication/README.md
user: login: njarecha
body: It does not give separate option to provide the `domain`. If they have to provide the domain then it should be part of the username`domain\\username`
```suggestion
1. The `AuthenticationManager` object is configured with a challenge handler that will prompt for a Windows login (username and password) if a secure resource is encountered.
```
created_at: 2025-05-13T23:43:25Z
author_association: COLLABORATOR

PR comments:
user: login: rolson
created_at: 2025-05-13T19:25:03Z
body: Anybody know what this is...

> 1. Shared/Samples/Authenticate with Integrated Windows Authentication - Error checking extra tags due to previous error - Error tags - API should not be in tags
author_association: COLLABORATOR
user: login: rolson
created_at: 2025-05-13T22:22:31Z
body: PR checks passing now. Please review.
author_association: COLLABORATOR