├── .gitignore ├── AppCreationScripts └── apps.json ├── CODE_OF_CONDUCT.md ├── LICENSE ├── MSALMacOS.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── MSALMacOS.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── MSALMacOS ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── Base.lproj │ └── Main.storyboard ├── Info.plist ├── MSALMacOS.entitlements └── ViewController.swift ├── Podfile ├── Podfile.lock ├── README.md └── images └── iosintro-keychainShare.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | .DS_Store 10 | 11 | ## Various settings 12 | *.pbxuser 13 | !default.pbxuser 14 | *.mode1v3 15 | !default.mode1v3 16 | *.mode2v3 17 | !default.mode2v3 18 | *.perspectivev3 19 | !default.perspectivev3 20 | xcuserdata/ 21 | 22 | ## Other 23 | *.moved-aside 24 | *.xccheckout 25 | *.xcscmblueprint 26 | 27 | ## Obj-C/Swift specific 28 | *.hmap 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | # Packages/ 41 | # Package.pins 42 | # Package.resolved 43 | .build/ 44 | 45 | # CocoaPods 46 | # 47 | # We recommend against adding the Pods directory to your .gitignore. However 48 | # you should judge for yourself, the pros and cons are mentioned at: 49 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 50 | # 51 | Pods/ 52 | 53 | # Carthage 54 | # 55 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 56 | # Carthage/Checkouts 57 | 58 | Carthage/Build 59 | 60 | # fastlane 61 | # 62 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 63 | # screenshots whenever they are needed. 64 | # For more information about the recommended setup visit: 65 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 66 | 67 | fastlane/report.xml 68 | fastlane/Preview.html 69 | fastlane/screenshots/**/*.png 70 | fastlane/test_output 71 | -------------------------------------------------------------------------------- /AppCreationScripts/apps.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sample": { 3 | "Title": "Calling Microsoft Graph from a macOS app", 4 | "Level": 400, 5 | "Client": "macOS" 6 | }, 7 | "AppRegistrations": [{ 8 | "x-ms-id": "active-directory-macOS-swift", 9 | "x-ms-name": "macOS-swift", 10 | "x-ms-version": "2.0", 11 | "replyUrlsWithType": [{ 12 | "url": "msauth.://auth", 13 | "type": "InstalledClient" 14 | }], 15 | "requiredResourceAccess": [{ 16 | "x-ms-resourceAppName": "Microsoft Graph", 17 | "resourceAppId": "00000003-0000-0000-c000-000000000000", 18 | "resourceAccess": [{ 19 | "id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", 20 | "type": "Scope", 21 | "x-ms-name": "user.read" 22 | }] 23 | }], 24 | "codeConfigurations": [{ 25 | "settingFile": "/MSALMacOS/ViewController.swift", 26 | "replaceTokens": { 27 | "appId": "2a858956-70de-42b9-b5db-d566eb1fb820", 28 | "authorityEndpointHost": "https://login.microsoftonline.com/", 29 | "tenantId": "common", 30 | "msgraphEndpointHost": "https://graph.microsoft.com/", 31 | "redirectUri": "msauth.com.microsoft.identitysample.MSALMacOS://auth" 32 | } 33 | }, 34 | { 35 | "settingFile": "/MSALMacOS/Info.plist", 36 | "replaceTokens": { 37 | "bundleId": "com.microsoft.identitysample.MSALMacOS" 38 | } 39 | }, 40 | { 41 | "settingFile": "/MSALMacOS.xcodeproj/project.pbxproj", 42 | "replaceTokens": { 43 | "bundleId": "com.microsoft.identitysample.MSALMacOS" 44 | } 45 | } 46 | ] 47 | }] 48 | } 49 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /MSALMacOS.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 51; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 8BB991C88518EF3991A40197 /* Pods_MSALMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F823B6F5F9FD8ECE38A6EF5F /* Pods_MSALMacOS.framework */; }; 11 | DF7F84BD22EA772F0013BA63 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF7F84BC22EA772F0013BA63 /* AppDelegate.swift */; }; 12 | DF7F84BF22EA772F0013BA63 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF7F84BE22EA772F0013BA63 /* ViewController.swift */; }; 13 | DF7F84C122EA77300013BA63 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DF7F84C022EA77300013BA63 /* Assets.xcassets */; }; 14 | DF7F84C422EA77300013BA63 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DF7F84C222EA77300013BA63 /* Main.storyboard */; }; 15 | /* End PBXBuildFile section */ 16 | 17 | /* Begin PBXContainerItemProxy section */ 18 | DF7F84CC22EA77310013BA63 /* PBXContainerItemProxy */ = { 19 | isa = PBXContainerItemProxy; 20 | containerPortal = DF7F84B122EA772F0013BA63 /* Project object */; 21 | proxyType = 1; 22 | remoteGlobalIDString = DF7F84B822EA772F0013BA63; 23 | remoteInfo = MSALMacOS; 24 | }; 25 | DF7F84D722EA77310013BA63 /* PBXContainerItemProxy */ = { 26 | isa = PBXContainerItemProxy; 27 | containerPortal = DF7F84B122EA772F0013BA63 /* Project object */; 28 | proxyType = 1; 29 | remoteGlobalIDString = DF7F84B822EA772F0013BA63; 30 | remoteInfo = MSALMacOS; 31 | }; 32 | /* End PBXContainerItemProxy section */ 33 | 34 | /* Begin PBXFileReference section */ 35 | 0DB7DCF21505D715D6C44593 /* Pods-MSALMacOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MSALMacOS.release.xcconfig"; path = "Target Support Files/Pods-MSALMacOS/Pods-MSALMacOS.release.xcconfig"; sourceTree = ""; }; 36 | 2A8C162F9C6809D06DFFD7D9 /* Pods-MSALMacOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MSALMacOS.debug.xcconfig"; path = "Target Support Files/Pods-MSALMacOS/Pods-MSALMacOS.debug.xcconfig"; sourceTree = ""; }; 37 | DF7F84B922EA772F0013BA63 /* MSALMacOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MSALMacOS.app; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | DF7F84BC22EA772F0013BA63 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 39 | DF7F84BE22EA772F0013BA63 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 40 | DF7F84C022EA77300013BA63 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 41 | DF7F84C322EA77300013BA63 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 42 | DF7F84C522EA77300013BA63 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 43 | DF7F84C622EA77300013BA63 /* MSALMacOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MSALMacOS.entitlements; sourceTree = ""; }; 44 | DF7F84CB22EA77310013BA63 /* MSALMacOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MSALMacOSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | DF7F84D622EA77310013BA63 /* MSALMacOSUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MSALMacOSUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | F823B6F5F9FD8ECE38A6EF5F /* Pods_MSALMacOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MSALMacOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | /* End PBXFileReference section */ 48 | 49 | /* Begin PBXFrameworksBuildPhase section */ 50 | DF7F84B622EA772F0013BA63 /* Frameworks */ = { 51 | isa = PBXFrameworksBuildPhase; 52 | buildActionMask = 2147483647; 53 | files = ( 54 | 8BB991C88518EF3991A40197 /* Pods_MSALMacOS.framework in Frameworks */, 55 | ); 56 | runOnlyForDeploymentPostprocessing = 0; 57 | }; 58 | DF7F84C822EA77310013BA63 /* Frameworks */ = { 59 | isa = PBXFrameworksBuildPhase; 60 | buildActionMask = 2147483647; 61 | files = ( 62 | ); 63 | runOnlyForDeploymentPostprocessing = 0; 64 | }; 65 | DF7F84D322EA77310013BA63 /* Frameworks */ = { 66 | isa = PBXFrameworksBuildPhase; 67 | buildActionMask = 2147483647; 68 | files = ( 69 | ); 70 | runOnlyForDeploymentPostprocessing = 0; 71 | }; 72 | /* End PBXFrameworksBuildPhase section */ 73 | 74 | /* Begin PBXGroup section */ 75 | 1B35B523E78C9A12231B12B9 /* Pods */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | 2A8C162F9C6809D06DFFD7D9 /* Pods-MSALMacOS.debug.xcconfig */, 79 | 0DB7DCF21505D715D6C44593 /* Pods-MSALMacOS.release.xcconfig */, 80 | ); 81 | path = Pods; 82 | sourceTree = ""; 83 | }; 84 | C59A55362EC75B6788638529 /* Frameworks */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | F823B6F5F9FD8ECE38A6EF5F /* Pods_MSALMacOS.framework */, 88 | ); 89 | name = Frameworks; 90 | sourceTree = ""; 91 | }; 92 | DF7F84B022EA772F0013BA63 = { 93 | isa = PBXGroup; 94 | children = ( 95 | DF7F84BB22EA772F0013BA63 /* MSALMacOS */, 96 | DF7F84BA22EA772F0013BA63 /* Products */, 97 | 1B35B523E78C9A12231B12B9 /* Pods */, 98 | C59A55362EC75B6788638529 /* Frameworks */, 99 | ); 100 | sourceTree = ""; 101 | }; 102 | DF7F84BA22EA772F0013BA63 /* Products */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | DF7F84B922EA772F0013BA63 /* MSALMacOS.app */, 106 | DF7F84CB22EA77310013BA63 /* MSALMacOSTests.xctest */, 107 | DF7F84D622EA77310013BA63 /* MSALMacOSUITests.xctest */, 108 | ); 109 | name = Products; 110 | sourceTree = ""; 111 | }; 112 | DF7F84BB22EA772F0013BA63 /* MSALMacOS */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | DF7F84BC22EA772F0013BA63 /* AppDelegate.swift */, 116 | DF7F84BE22EA772F0013BA63 /* ViewController.swift */, 117 | DF7F84C022EA77300013BA63 /* Assets.xcassets */, 118 | DF7F84C222EA77300013BA63 /* Main.storyboard */, 119 | DF7F84C522EA77300013BA63 /* Info.plist */, 120 | DF7F84C622EA77300013BA63 /* MSALMacOS.entitlements */, 121 | ); 122 | path = MSALMacOS; 123 | sourceTree = ""; 124 | }; 125 | /* End PBXGroup section */ 126 | 127 | /* Begin PBXNativeTarget section */ 128 | DF7F84B822EA772F0013BA63 /* MSALMacOS */ = { 129 | isa = PBXNativeTarget; 130 | buildConfigurationList = DF7F84DF22EA77310013BA63 /* Build configuration list for PBXNativeTarget "MSALMacOS" */; 131 | buildPhases = ( 132 | C0EE9C2E9ECD705A0F921CFC /* [CP] Check Pods Manifest.lock */, 133 | DF7F84B522EA772F0013BA63 /* Sources */, 134 | DF7F84B622EA772F0013BA63 /* Frameworks */, 135 | DF7F84B722EA772F0013BA63 /* Resources */, 136 | 3EBDB9DDA938B8967A835FA2 /* [CP] Embed Pods Frameworks */, 137 | ); 138 | buildRules = ( 139 | ); 140 | dependencies = ( 141 | ); 142 | name = MSALMacOS; 143 | productName = MSALMacOS; 144 | productReference = DF7F84B922EA772F0013BA63 /* MSALMacOS.app */; 145 | productType = "com.apple.product-type.application"; 146 | }; 147 | DF7F84CA22EA77310013BA63 /* MSALMacOSTests */ = { 148 | isa = PBXNativeTarget; 149 | buildConfigurationList = DF7F84E222EA77310013BA63 /* Build configuration list for PBXNativeTarget "MSALMacOSTests" */; 150 | buildPhases = ( 151 | DF7F84C722EA77310013BA63 /* Sources */, 152 | DF7F84C822EA77310013BA63 /* Frameworks */, 153 | DF7F84C922EA77310013BA63 /* Resources */, 154 | ); 155 | buildRules = ( 156 | ); 157 | dependencies = ( 158 | DF7F84CD22EA77310013BA63 /* PBXTargetDependency */, 159 | ); 160 | name = MSALMacOSTests; 161 | productName = MSALMacOSTests; 162 | productReference = DF7F84CB22EA77310013BA63 /* MSALMacOSTests.xctest */; 163 | productType = "com.apple.product-type.bundle.unit-test"; 164 | }; 165 | DF7F84D522EA77310013BA63 /* MSALMacOSUITests */ = { 166 | isa = PBXNativeTarget; 167 | buildConfigurationList = DF7F84E522EA77310013BA63 /* Build configuration list for PBXNativeTarget "MSALMacOSUITests" */; 168 | buildPhases = ( 169 | DF7F84D222EA77310013BA63 /* Sources */, 170 | DF7F84D322EA77310013BA63 /* Frameworks */, 171 | DF7F84D422EA77310013BA63 /* Resources */, 172 | ); 173 | buildRules = ( 174 | ); 175 | dependencies = ( 176 | DF7F84D822EA77310013BA63 /* PBXTargetDependency */, 177 | ); 178 | name = MSALMacOSUITests; 179 | productName = MSALMacOSUITests; 180 | productReference = DF7F84D622EA77310013BA63 /* MSALMacOSUITests.xctest */; 181 | productType = "com.apple.product-type.bundle.ui-testing"; 182 | }; 183 | /* End PBXNativeTarget section */ 184 | 185 | /* Begin PBXProject section */ 186 | DF7F84B122EA772F0013BA63 /* Project object */ = { 187 | isa = PBXProject; 188 | attributes = { 189 | LastSwiftUpdateCheck = 1020; 190 | LastUpgradeCheck = 1020; 191 | ORGANIZATIONNAME = Microsoft; 192 | TargetAttributes = { 193 | DF7F84B822EA772F0013BA63 = { 194 | CreatedOnToolsVersion = 10.2.1; 195 | SystemCapabilities = { 196 | com.apple.Keychain = { 197 | enabled = 0; 198 | }; 199 | }; 200 | }; 201 | DF7F84CA22EA77310013BA63 = { 202 | CreatedOnToolsVersion = 10.2.1; 203 | TestTargetID = DF7F84B822EA772F0013BA63; 204 | }; 205 | DF7F84D522EA77310013BA63 = { 206 | CreatedOnToolsVersion = 10.2.1; 207 | TestTargetID = DF7F84B822EA772F0013BA63; 208 | }; 209 | }; 210 | }; 211 | buildConfigurationList = DF7F84B422EA772F0013BA63 /* Build configuration list for PBXProject "MSALMacOS" */; 212 | compatibilityVersion = "Xcode 9.3"; 213 | developmentRegion = en; 214 | hasScannedForEncodings = 0; 215 | knownRegions = ( 216 | en, 217 | Base, 218 | ); 219 | mainGroup = DF7F84B022EA772F0013BA63; 220 | productRefGroup = DF7F84BA22EA772F0013BA63 /* Products */; 221 | projectDirPath = ""; 222 | projectRoot = ""; 223 | targets = ( 224 | DF7F84B822EA772F0013BA63 /* MSALMacOS */, 225 | DF7F84CA22EA77310013BA63 /* MSALMacOSTests */, 226 | DF7F84D522EA77310013BA63 /* MSALMacOSUITests */, 227 | ); 228 | }; 229 | /* End PBXProject section */ 230 | 231 | /* Begin PBXResourcesBuildPhase section */ 232 | DF7F84B722EA772F0013BA63 /* Resources */ = { 233 | isa = PBXResourcesBuildPhase; 234 | buildActionMask = 2147483647; 235 | files = ( 236 | DF7F84C122EA77300013BA63 /* Assets.xcassets in Resources */, 237 | DF7F84C422EA77300013BA63 /* Main.storyboard in Resources */, 238 | ); 239 | runOnlyForDeploymentPostprocessing = 0; 240 | }; 241 | DF7F84C922EA77310013BA63 /* Resources */ = { 242 | isa = PBXResourcesBuildPhase; 243 | buildActionMask = 2147483647; 244 | files = ( 245 | ); 246 | runOnlyForDeploymentPostprocessing = 0; 247 | }; 248 | DF7F84D422EA77310013BA63 /* Resources */ = { 249 | isa = PBXResourcesBuildPhase; 250 | buildActionMask = 2147483647; 251 | files = ( 252 | ); 253 | runOnlyForDeploymentPostprocessing = 0; 254 | }; 255 | /* End PBXResourcesBuildPhase section */ 256 | 257 | /* Begin PBXShellScriptBuildPhase section */ 258 | 3EBDB9DDA938B8967A835FA2 /* [CP] Embed Pods Frameworks */ = { 259 | isa = PBXShellScriptBuildPhase; 260 | buildActionMask = 2147483647; 261 | files = ( 262 | ); 263 | inputFileListPaths = ( 264 | "${PODS_ROOT}/Target Support Files/Pods-MSALMacOS/Pods-MSALMacOS-frameworks-${CONFIGURATION}-input-files.xcfilelist", 265 | ); 266 | name = "[CP] Embed Pods Frameworks"; 267 | outputFileListPaths = ( 268 | "${PODS_ROOT}/Target Support Files/Pods-MSALMacOS/Pods-MSALMacOS-frameworks-${CONFIGURATION}-output-files.xcfilelist", 269 | ); 270 | runOnlyForDeploymentPostprocessing = 0; 271 | shellPath = /bin/sh; 272 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-MSALMacOS/Pods-MSALMacOS-frameworks.sh\"\n"; 273 | showEnvVarsInLog = 0; 274 | }; 275 | C0EE9C2E9ECD705A0F921CFC /* [CP] Check Pods Manifest.lock */ = { 276 | isa = PBXShellScriptBuildPhase; 277 | buildActionMask = 2147483647; 278 | files = ( 279 | ); 280 | inputFileListPaths = ( 281 | ); 282 | inputPaths = ( 283 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 284 | "${PODS_ROOT}/Manifest.lock", 285 | ); 286 | name = "[CP] Check Pods Manifest.lock"; 287 | outputFileListPaths = ( 288 | ); 289 | outputPaths = ( 290 | "$(DERIVED_FILE_DIR)/Pods-MSALMacOS-checkManifestLockResult.txt", 291 | ); 292 | runOnlyForDeploymentPostprocessing = 0; 293 | shellPath = /bin/sh; 294 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 295 | showEnvVarsInLog = 0; 296 | }; 297 | /* End PBXShellScriptBuildPhase section */ 298 | 299 | /* Begin PBXSourcesBuildPhase section */ 300 | DF7F84B522EA772F0013BA63 /* Sources */ = { 301 | isa = PBXSourcesBuildPhase; 302 | buildActionMask = 2147483647; 303 | files = ( 304 | DF7F84BF22EA772F0013BA63 /* ViewController.swift in Sources */, 305 | DF7F84BD22EA772F0013BA63 /* AppDelegate.swift in Sources */, 306 | ); 307 | runOnlyForDeploymentPostprocessing = 0; 308 | }; 309 | DF7F84C722EA77310013BA63 /* Sources */ = { 310 | isa = PBXSourcesBuildPhase; 311 | buildActionMask = 2147483647; 312 | files = ( 313 | ); 314 | runOnlyForDeploymentPostprocessing = 0; 315 | }; 316 | DF7F84D222EA77310013BA63 /* Sources */ = { 317 | isa = PBXSourcesBuildPhase; 318 | buildActionMask = 2147483647; 319 | files = ( 320 | ); 321 | runOnlyForDeploymentPostprocessing = 0; 322 | }; 323 | /* End PBXSourcesBuildPhase section */ 324 | 325 | /* Begin PBXTargetDependency section */ 326 | DF7F84CD22EA77310013BA63 /* PBXTargetDependency */ = { 327 | isa = PBXTargetDependency; 328 | target = DF7F84B822EA772F0013BA63 /* MSALMacOS */; 329 | targetProxy = DF7F84CC22EA77310013BA63 /* PBXContainerItemProxy */; 330 | }; 331 | DF7F84D822EA77310013BA63 /* PBXTargetDependency */ = { 332 | isa = PBXTargetDependency; 333 | target = DF7F84B822EA772F0013BA63 /* MSALMacOS */; 334 | targetProxy = DF7F84D722EA77310013BA63 /* PBXContainerItemProxy */; 335 | }; 336 | /* End PBXTargetDependency section */ 337 | 338 | /* Begin PBXVariantGroup section */ 339 | DF7F84C222EA77300013BA63 /* Main.storyboard */ = { 340 | isa = PBXVariantGroup; 341 | children = ( 342 | DF7F84C322EA77300013BA63 /* Base */, 343 | ); 344 | name = Main.storyboard; 345 | sourceTree = ""; 346 | }; 347 | /* End PBXVariantGroup section */ 348 | 349 | /* Begin XCBuildConfiguration section */ 350 | DF7F84DD22EA77310013BA63 /* Debug */ = { 351 | isa = XCBuildConfiguration; 352 | buildSettings = { 353 | ALWAYS_SEARCH_USER_PATHS = NO; 354 | CLANG_ANALYZER_NONNULL = YES; 355 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 356 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 357 | CLANG_CXX_LIBRARY = "libc++"; 358 | CLANG_ENABLE_MODULES = YES; 359 | CLANG_ENABLE_OBJC_ARC = YES; 360 | CLANG_ENABLE_OBJC_WEAK = YES; 361 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 362 | CLANG_WARN_BOOL_CONVERSION = YES; 363 | CLANG_WARN_COMMA = YES; 364 | CLANG_WARN_CONSTANT_CONVERSION = YES; 365 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 366 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 367 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 368 | CLANG_WARN_EMPTY_BODY = YES; 369 | CLANG_WARN_ENUM_CONVERSION = YES; 370 | CLANG_WARN_INFINITE_RECURSION = YES; 371 | CLANG_WARN_INT_CONVERSION = YES; 372 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 373 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 374 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 375 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 376 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 377 | CLANG_WARN_STRICT_PROTOTYPES = YES; 378 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 379 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 380 | CLANG_WARN_UNREACHABLE_CODE = YES; 381 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 382 | CODE_SIGN_IDENTITY = "Mac Developer"; 383 | COPY_PHASE_STRIP = NO; 384 | DEBUG_INFORMATION_FORMAT = dwarf; 385 | ENABLE_STRICT_OBJC_MSGSEND = YES; 386 | ENABLE_TESTABILITY = YES; 387 | GCC_C_LANGUAGE_STANDARD = gnu11; 388 | GCC_DYNAMIC_NO_PIC = NO; 389 | GCC_NO_COMMON_BLOCKS = YES; 390 | GCC_OPTIMIZATION_LEVEL = 0; 391 | GCC_PREPROCESSOR_DEFINITIONS = ( 392 | "DEBUG=1", 393 | "$(inherited)", 394 | ); 395 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 396 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 397 | GCC_WARN_UNDECLARED_SELECTOR = YES; 398 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 399 | GCC_WARN_UNUSED_FUNCTION = YES; 400 | GCC_WARN_UNUSED_VARIABLE = YES; 401 | MACOSX_DEPLOYMENT_TARGET = 10.14; 402 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 403 | MTL_FAST_MATH = YES; 404 | ONLY_ACTIVE_ARCH = YES; 405 | SDKROOT = macosx; 406 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 407 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 408 | }; 409 | name = Debug; 410 | }; 411 | DF7F84DE22EA77310013BA63 /* Release */ = { 412 | isa = XCBuildConfiguration; 413 | buildSettings = { 414 | ALWAYS_SEARCH_USER_PATHS = NO; 415 | CLANG_ANALYZER_NONNULL = YES; 416 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 417 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 418 | CLANG_CXX_LIBRARY = "libc++"; 419 | CLANG_ENABLE_MODULES = YES; 420 | CLANG_ENABLE_OBJC_ARC = YES; 421 | CLANG_ENABLE_OBJC_WEAK = YES; 422 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 423 | CLANG_WARN_BOOL_CONVERSION = YES; 424 | CLANG_WARN_COMMA = YES; 425 | CLANG_WARN_CONSTANT_CONVERSION = YES; 426 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 427 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 428 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 429 | CLANG_WARN_EMPTY_BODY = YES; 430 | CLANG_WARN_ENUM_CONVERSION = YES; 431 | CLANG_WARN_INFINITE_RECURSION = YES; 432 | CLANG_WARN_INT_CONVERSION = YES; 433 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 434 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 435 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 436 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 437 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 438 | CLANG_WARN_STRICT_PROTOTYPES = YES; 439 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 440 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 441 | CLANG_WARN_UNREACHABLE_CODE = YES; 442 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 443 | CODE_SIGN_IDENTITY = "Mac Developer"; 444 | COPY_PHASE_STRIP = NO; 445 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 446 | ENABLE_NS_ASSERTIONS = NO; 447 | ENABLE_STRICT_OBJC_MSGSEND = YES; 448 | GCC_C_LANGUAGE_STANDARD = gnu11; 449 | GCC_NO_COMMON_BLOCKS = YES; 450 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 451 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 452 | GCC_WARN_UNDECLARED_SELECTOR = YES; 453 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 454 | GCC_WARN_UNUSED_FUNCTION = YES; 455 | GCC_WARN_UNUSED_VARIABLE = YES; 456 | MACOSX_DEPLOYMENT_TARGET = 10.14; 457 | MTL_ENABLE_DEBUG_INFO = NO; 458 | MTL_FAST_MATH = YES; 459 | SDKROOT = macosx; 460 | SWIFT_COMPILATION_MODE = wholemodule; 461 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 462 | }; 463 | name = Release; 464 | }; 465 | DF7F84E022EA77310013BA63 /* Debug */ = { 466 | isa = XCBuildConfiguration; 467 | baseConfigurationReference = 2A8C162F9C6809D06DFFD7D9 /* Pods-MSALMacOS.debug.xcconfig */; 468 | buildSettings = { 469 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 470 | CODE_SIGN_ENTITLEMENTS = MSALMacOS/MSALMacOS.entitlements; 471 | CODE_SIGN_STYLE = Automatic; 472 | COMBINE_HIDPI_IMAGES = YES; 473 | DEVELOPMENT_TEAM = UBF8T346G9; 474 | INFOPLIST_FILE = MSALMacOS/Info.plist; 475 | LD_RUNPATH_SEARCH_PATHS = ( 476 | "$(inherited)", 477 | "@executable_path/../Frameworks", 478 | ); 479 | PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.identitysample.MSALMacOS; 480 | PRODUCT_NAME = "$(TARGET_NAME)"; 481 | SWIFT_VERSION = 5.0; 482 | }; 483 | name = Debug; 484 | }; 485 | DF7F84E122EA77310013BA63 /* Release */ = { 486 | isa = XCBuildConfiguration; 487 | baseConfigurationReference = 0DB7DCF21505D715D6C44593 /* Pods-MSALMacOS.release.xcconfig */; 488 | buildSettings = { 489 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 490 | CODE_SIGN_ENTITLEMENTS = MSALMacOS/MSALMacOS.entitlements; 491 | CODE_SIGN_STYLE = Automatic; 492 | COMBINE_HIDPI_IMAGES = YES; 493 | DEVELOPMENT_TEAM = UBF8T346G9; 494 | INFOPLIST_FILE = MSALMacOS/Info.plist; 495 | LD_RUNPATH_SEARCH_PATHS = ( 496 | "$(inherited)", 497 | "@executable_path/../Frameworks", 498 | ); 499 | PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.identitysample.MSALMacOS; 500 | PRODUCT_NAME = "$(TARGET_NAME)"; 501 | SWIFT_VERSION = 5.0; 502 | }; 503 | name = Release; 504 | }; 505 | DF7F84E322EA77310013BA63 /* Debug */ = { 506 | isa = XCBuildConfiguration; 507 | buildSettings = { 508 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 509 | BUNDLE_LOADER = "$(TEST_HOST)"; 510 | CODE_SIGN_STYLE = Automatic; 511 | COMBINE_HIDPI_IMAGES = YES; 512 | DEVELOPMENT_TEAM = N9S2V74MEY; 513 | INFOPLIST_FILE = MSALMacOSTests/Info.plist; 514 | LD_RUNPATH_SEARCH_PATHS = ( 515 | "$(inherited)", 516 | "@executable_path/../Frameworks", 517 | "@loader_path/../Frameworks", 518 | ); 519 | PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.identitysample.MSALMacOSTests; 520 | PRODUCT_NAME = "$(TARGET_NAME)"; 521 | SWIFT_VERSION = 5.0; 522 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MSALMacOS.app/Contents/MacOS/MSALMacOS"; 523 | }; 524 | name = Debug; 525 | }; 526 | DF7F84E422EA77310013BA63 /* Release */ = { 527 | isa = XCBuildConfiguration; 528 | buildSettings = { 529 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 530 | BUNDLE_LOADER = "$(TEST_HOST)"; 531 | CODE_SIGN_STYLE = Automatic; 532 | COMBINE_HIDPI_IMAGES = YES; 533 | DEVELOPMENT_TEAM = N9S2V74MEY; 534 | INFOPLIST_FILE = MSALMacOSTests/Info.plist; 535 | LD_RUNPATH_SEARCH_PATHS = ( 536 | "$(inherited)", 537 | "@executable_path/../Frameworks", 538 | "@loader_path/../Frameworks", 539 | ); 540 | PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.identitysample.MSALMacOSTests; 541 | PRODUCT_NAME = "$(TARGET_NAME)"; 542 | SWIFT_VERSION = 5.0; 543 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MSALMacOS.app/Contents/MacOS/MSALMacOS"; 544 | }; 545 | name = Release; 546 | }; 547 | DF7F84E622EA77310013BA63 /* Debug */ = { 548 | isa = XCBuildConfiguration; 549 | buildSettings = { 550 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 551 | CODE_SIGN_STYLE = Automatic; 552 | COMBINE_HIDPI_IMAGES = YES; 553 | DEVELOPMENT_TEAM = N9S2V74MEY; 554 | INFOPLIST_FILE = MSALMacOSUITests/Info.plist; 555 | LD_RUNPATH_SEARCH_PATHS = ( 556 | "$(inherited)", 557 | "@executable_path/../Frameworks", 558 | "@loader_path/../Frameworks", 559 | ); 560 | PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.identitysample.MSALMacOSUITests; 561 | PRODUCT_NAME = "$(TARGET_NAME)"; 562 | SWIFT_VERSION = 5.0; 563 | TEST_TARGET_NAME = MSALMacOS; 564 | }; 565 | name = Debug; 566 | }; 567 | DF7F84E722EA77310013BA63 /* Release */ = { 568 | isa = XCBuildConfiguration; 569 | buildSettings = { 570 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 571 | CODE_SIGN_STYLE = Automatic; 572 | COMBINE_HIDPI_IMAGES = YES; 573 | DEVELOPMENT_TEAM = N9S2V74MEY; 574 | INFOPLIST_FILE = MSALMacOSUITests/Info.plist; 575 | LD_RUNPATH_SEARCH_PATHS = ( 576 | "$(inherited)", 577 | "@executable_path/../Frameworks", 578 | "@loader_path/../Frameworks", 579 | ); 580 | PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.identitysample.MSALMacOSUITests; 581 | PRODUCT_NAME = "$(TARGET_NAME)"; 582 | SWIFT_VERSION = 5.0; 583 | TEST_TARGET_NAME = MSALMacOS; 584 | }; 585 | name = Release; 586 | }; 587 | /* End XCBuildConfiguration section */ 588 | 589 | /* Begin XCConfigurationList section */ 590 | DF7F84B422EA772F0013BA63 /* Build configuration list for PBXProject "MSALMacOS" */ = { 591 | isa = XCConfigurationList; 592 | buildConfigurations = ( 593 | DF7F84DD22EA77310013BA63 /* Debug */, 594 | DF7F84DE22EA77310013BA63 /* Release */, 595 | ); 596 | defaultConfigurationIsVisible = 0; 597 | defaultConfigurationName = Release; 598 | }; 599 | DF7F84DF22EA77310013BA63 /* Build configuration list for PBXNativeTarget "MSALMacOS" */ = { 600 | isa = XCConfigurationList; 601 | buildConfigurations = ( 602 | DF7F84E022EA77310013BA63 /* Debug */, 603 | DF7F84E122EA77310013BA63 /* Release */, 604 | ); 605 | defaultConfigurationIsVisible = 0; 606 | defaultConfigurationName = Release; 607 | }; 608 | DF7F84E222EA77310013BA63 /* Build configuration list for PBXNativeTarget "MSALMacOSTests" */ = { 609 | isa = XCConfigurationList; 610 | buildConfigurations = ( 611 | DF7F84E322EA77310013BA63 /* Debug */, 612 | DF7F84E422EA77310013BA63 /* Release */, 613 | ); 614 | defaultConfigurationIsVisible = 0; 615 | defaultConfigurationName = Release; 616 | }; 617 | DF7F84E522EA77310013BA63 /* Build configuration list for PBXNativeTarget "MSALMacOSUITests" */ = { 618 | isa = XCConfigurationList; 619 | buildConfigurations = ( 620 | DF7F84E622EA77310013BA63 /* Debug */, 621 | DF7F84E722EA77310013BA63 /* Release */, 622 | ); 623 | defaultConfigurationIsVisible = 0; 624 | defaultConfigurationName = Release; 625 | }; 626 | /* End XCConfigurationList section */ 627 | }; 628 | rootObject = DF7F84B122EA772F0013BA63 /* Project object */; 629 | } 630 | -------------------------------------------------------------------------------- /MSALMacOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MSALMacOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MSALMacOS.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MSALMacOS.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MSALMacOS/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Copyright (c) Microsoft Corporation. 4 | // All rights reserved. 5 | // 6 | // This code is licensed under the MIT License. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files(the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions : 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | // 26 | //------------------------------------------------------------------------------ 27 | 28 | import Cocoa 29 | import MSAL 30 | 31 | @NSApplicationMain 32 | class AppDelegate: NSObject, NSApplicationDelegate { 33 | 34 | func applicationDidFinishLaunching(_ aNotification: Notification) { 35 | 36 | // The MSAL Logger should be set as early as possible in the app launch sequence, before any MSAL 37 | // requests are made. 38 | 39 | MSALGlobalConfig.loggerConfig.setLogCallback { (logLevel, message, containsPII) in 40 | 41 | // If PiiLoggingEnabled is set YES, this block will potentially contain sensitive information (Personally Identifiable Information), but not all messages will contain it. 42 | // containsPII == YES indicates if a particular message contains PII. 43 | // You might want to capture PII only in debug builds, or only if you take necessary actions to handle PII properly according to legal requirements of the region 44 | if let displayableMessage = message { 45 | if (!containsPII) { 46 | #if DEBUG 47 | // NB! This sample uses print just for testing purposes 48 | // You should only ever log to NSLog in debug mode to prevent leaking potentially sensitive information 49 | print(displayableMessage) 50 | #endif 51 | } 52 | } 53 | } 54 | 55 | } 56 | 57 | func applicationWillTerminate(_ aNotification: Notification) { 58 | // Insert code here to tear down your application 59 | } 60 | 61 | 62 | } 63 | 64 | -------------------------------------------------------------------------------- /MSALMacOS/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /MSALMacOS/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /MSALMacOS/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 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 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | Default 530 | 531 | 532 | 533 | 534 | 535 | 536 | Left to Right 537 | 538 | 539 | 540 | 541 | 542 | 543 | Right to Left 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | Default 555 | 556 | 557 | 558 | 559 | 560 | 561 | Left to Right 562 | 563 | 564 | 565 | 566 | 567 | 568 | Right to Left 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | -------------------------------------------------------------------------------- /MSALMacOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | CFBundleURLTypes 24 | 25 | 26 | CFBundleURLSchemes 27 | 28 | msauth.com.microsoft.identitysample.MSALMacOS 29 | 30 | 31 | 32 | LSMinimumSystemVersion 33 | $(MACOSX_DEPLOYMENT_TARGET) 34 | NSHumanReadableCopyright 35 | Copyright © 2019 Microsoft. All rights reserved. 36 | NSMainStoryboardFile 37 | Main 38 | NSPrincipalClass 39 | NSApplication 40 | 41 | 42 | -------------------------------------------------------------------------------- /MSALMacOS/MSALMacOS.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | com.apple.security.network.client 10 | 11 | keychain-access-groups 12 | 13 | $(AppIdentifierPrefix)com.microsoft.identitysample.MSALMacOS 14 | $(AppIdentifierPrefix)com.microsoft.identity.universalstorage 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /MSALMacOS/ViewController.swift: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Copyright (c) Microsoft Corporation. 4 | // All rights reserved. 5 | // 6 | // This code is licensed under the MIT License. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files(the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions : 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | // 26 | //------------------------------------------------------------------------------ 27 | 28 | import Cocoa 29 | import MSAL 30 | 31 | class ViewController: NSViewController, NSTextFieldDelegate, URLSessionDelegate { 32 | 33 | // Update the below to your client ID you received in the portal. The below is for running the demo only 34 | let kClientID = "2a858956-70de-42b9-b5db-d566eb1fb820" 35 | let kGraphEndpoint = "https://graph.microsoft.com/" 36 | let kAuthority = "https://login.microsoftonline.com/common" 37 | let kRedirectUri = "msauth.com.microsoft.identitysample.MSALMacOS://auth" 38 | 39 | let kScopes: [String] = ["user.read"] 40 | 41 | var accessToken = String() 42 | var applicationContext : MSALPublicClientApplication? 43 | var webViewParamaters : MSALWebviewParameters? 44 | 45 | var callGraphButton: NSButton! 46 | var loggingText: NSTextView! 47 | var signOutButton: NSButton! 48 | 49 | var usernameLabel: NSTextField! 50 | 51 | var currentAccount: MSALAccount? 52 | 53 | /** 54 | Setup public client application in viewDidLoad 55 | */ 56 | 57 | override func viewDidLoad() { 58 | 59 | super.viewDidLoad() 60 | 61 | initUI() 62 | 63 | do { 64 | try self.initMSAL() 65 | } catch let error { 66 | self.updateLogging(text: "Unable to create Application Context \(error)") 67 | } 68 | 69 | self.loadCurrentAccount() 70 | self.platformViewDidLoadSetup() 71 | } 72 | 73 | func platformViewDidLoadSetup() {} 74 | 75 | override func viewWillAppear() { 76 | 77 | super.viewWillAppear() 78 | self.loadCurrentAccount() 79 | } 80 | } 81 | 82 | extension ViewController { 83 | 84 | /** 85 | 86 | Initialize a MSALPublicClientApplication with a given clientID and authority 87 | 88 | - clientId: The clientID of your application, you should get this from the app portal. 89 | - redirectUri: A redirect URI of your application, you should get this from the app portal. 90 | If nil, MSAL will create one by default. i.e./ msauth.://auth 91 | - authority: A URL indicating a directory that MSAL can use to obtain tokens. In Azure AD 92 | it is of the form https://, where is the 93 | directory host (e.g. https://login.microsoftonline.com) and is a 94 | identifier within the directory itself (e.g. a domain associated to the 95 | tenant, such as contoso.onmicrosoft.com, or the GUID representing the 96 | TenantID property of the directory) 97 | - error The error that occurred creating the application object, if any, if you're 98 | not interested in the specific error pass in nil. 99 | */ 100 | func initMSAL() throws { 101 | 102 | guard let authorityURL = URL(string: kAuthority) else { 103 | self.updateLogging(text: "Unable to create authority URL") 104 | return 105 | } 106 | 107 | let authority = try MSALAADAuthority(url: authorityURL) 108 | 109 | let msalConfiguration = MSALPublicClientApplicationConfig(clientId: kClientID, 110 | redirectUri: kRedirectUri, 111 | authority: authority) 112 | self.applicationContext = try MSALPublicClientApplication(configuration: msalConfiguration) 113 | self.initWebViewParams() 114 | } 115 | 116 | func initWebViewParams() { 117 | self.webViewParamaters = MSALWebviewParameters(authPresentationViewController: self) 118 | } 119 | } 120 | 121 | extension ViewController { 122 | 123 | @objc func callGraphAPI(_ sender: Any) { 124 | 125 | self.loadCurrentAccount { (account) in 126 | 127 | guard let currentAccount = account else { 128 | 129 | // We check to see if we have a current logged in account. 130 | // If we don't, then we need to sign someone in. 131 | self.acquireTokenInteractively() 132 | return 133 | } 134 | 135 | self.acquireTokenSilently(currentAccount) 136 | } 137 | } 138 | 139 | func acquireTokenInteractively() { 140 | 141 | guard let applicationContext = self.applicationContext else { return } 142 | guard let webViewParameters = self.webViewParamaters else { return } 143 | 144 | let parameters = MSALInteractiveTokenParameters(scopes: kScopes, webviewParameters: webViewParameters) 145 | parameters.promptType = .selectAccount 146 | 147 | applicationContext.acquireToken(with: parameters) { (result, error) in 148 | 149 | if let error = error { 150 | 151 | self.updateLogging(text: "Could not acquire token: \(error)") 152 | return 153 | } 154 | 155 | guard let result = result else { 156 | 157 | self.updateLogging(text: "Could not acquire token: No result returned") 158 | return 159 | } 160 | 161 | self.accessToken = result.accessToken 162 | self.updateLogging(text: "Access token is \(self.accessToken)") 163 | self.updateCurrentAccount(account: result.account) 164 | self.getContentWithToken() 165 | } 166 | } 167 | 168 | func acquireTokenSilently(_ account : MSALAccount!) { 169 | 170 | guard let applicationContext = self.applicationContext else { return } 171 | 172 | /** 173 | 174 | Acquire a token for an existing account silently 175 | 176 | - forScopes: Permissions you want included in the access token received 177 | in the result in the completionBlock. Not all scopes are 178 | guaranteed to be included in the access token returned. 179 | - account: An account object that we retrieved from the application object before that the 180 | authentication flow will be locked down to. 181 | - completionBlock: The completion block that will be called when the authentication 182 | flow completes, or encounters an error. 183 | */ 184 | 185 | let parameters = MSALSilentTokenParameters(scopes: kScopes, account: account) 186 | 187 | applicationContext.acquireTokenSilent(with: parameters) { (result, error) in 188 | 189 | if let error = error { 190 | 191 | let nsError = error as NSError 192 | 193 | // interactionRequired means we need to ask the user to sign-in. This usually happens 194 | // when the user's Refresh Token is expired or if the user has changed their password 195 | // among other possible reasons. 196 | 197 | if (nsError.domain == MSALErrorDomain) { 198 | 199 | if (nsError.code == MSALError.interactionRequired.rawValue) { 200 | 201 | DispatchQueue.main.async { 202 | self.acquireTokenInteractively() 203 | } 204 | return 205 | } 206 | } 207 | 208 | self.updateLogging(text: "Could not acquire token silently: \(error)") 209 | return 210 | } 211 | 212 | guard let result = result else { 213 | 214 | self.updateLogging(text: "Could not acquire token: No result returned") 215 | return 216 | } 217 | 218 | self.accessToken = result.accessToken 219 | self.updateLogging(text: "Refreshed Access token is \(self.accessToken)") 220 | self.updateSignOutButton(enabled: true) 221 | self.getContentWithToken() 222 | } 223 | } 224 | 225 | func getGraphEndpoint() -> String { 226 | return kGraphEndpoint.hasSuffix("/") ? (kGraphEndpoint + "v1.0/me/") : (kGraphEndpoint + "/v1.0/me/"); 227 | } 228 | 229 | /** 230 | This will invoke the call to the Microsoft Graph API. It uses the 231 | built in URLSession to create a connection. 232 | */ 233 | 234 | func getContentWithToken() { 235 | 236 | // Specify the Graph API endpoint 237 | let graphURI = getGraphEndpoint() 238 | let url = URL(string: graphURI) 239 | var request = URLRequest(url: url!) 240 | 241 | // Set the Authorization header for the request. We use Bearer tokens, so we specify Bearer + the token we got from the result 242 | request.setValue("Bearer \(self.accessToken)", forHTTPHeaderField: "Authorization") 243 | 244 | URLSession.shared.dataTask(with: request) { data, response, error in 245 | 246 | if let error = error { 247 | self.updateLogging(text: "Couldn't get graph result: \(error)") 248 | return 249 | } 250 | 251 | guard let result = try? JSONSerialization.jsonObject(with: data!, options: []) else { 252 | 253 | self.updateLogging(text: "Couldn't deserialize result JSON") 254 | return 255 | } 256 | 257 | self.updateLogging(text: "Result from Graph: \(result))") 258 | 259 | }.resume() 260 | } 261 | 262 | } 263 | 264 | extension ViewController { 265 | 266 | typealias AccountCompletion = (MSALAccount?) -> Void 267 | 268 | func loadCurrentAccount(completion: AccountCompletion? = nil) { 269 | 270 | guard let applicationContext = self.applicationContext else { return } 271 | 272 | let msalParameters = MSALParameters() 273 | msalParameters.completionBlockQueue = DispatchQueue.main 274 | 275 | // Note that this sample showcases an app that signs in a single account at a time 276 | // If you're building a more complex app that signs in multiple accounts at the same time, you'll need to use a different account retrieval API that specifies account identifier 277 | // For example, see "accountsFromDeviceForParameters:completionBlock:" - https://azuread.github.io/microsoft-authentication-library-for-objc/Classes/MSALPublicClientApplication.html#/c:objc(cs)MSALPublicClientApplication(im)accountsFromDeviceForParameters:completionBlock: 278 | applicationContext.getCurrentAccount(with: msalParameters, completionBlock: { (currentAccount, previousAccount, error) in 279 | 280 | if let error = error { 281 | self.updateLogging(text: "Couldn't query current account with error: \(error)") 282 | return 283 | } 284 | 285 | if let currentAccount = currentAccount { 286 | 287 | self.updateLogging(text: "Found a signed in account \(String(describing: currentAccount.username)). Updating data for that account...") 288 | 289 | self.updateCurrentAccount(account: currentAccount) 290 | 291 | if let completion = completion { 292 | completion(self.currentAccount) 293 | } 294 | 295 | return 296 | } 297 | 298 | self.updateLogging(text: "Account signed out. Updating UX") 299 | self.accessToken = "" 300 | self.updateCurrentAccount(account: nil) 301 | 302 | if let completion = completion { 303 | completion(nil) 304 | } 305 | }) 306 | } 307 | 308 | @objc func signOut(_ sender: Any) { 309 | 310 | guard let applicationContext = self.applicationContext else { return } 311 | 312 | guard let account = self.currentAccount else { return } 313 | 314 | do { 315 | 316 | /** 317 | Removes all tokens from the cache for this application for the provided account 318 | 319 | - account: The account to remove from the cache 320 | */ 321 | 322 | let signoutParameters = MSALSignoutParameters(webviewParameters: self.webViewParamaters!) 323 | signoutParameters.signoutFromBrowser = true 324 | 325 | applicationContext.signout(with: account, signoutParameters: signoutParameters, completionBlock: {(success, error) in 326 | 327 | if let error = error { 328 | self.updateLogging(text: "Couldn't sign out account with error: \(error)") 329 | return 330 | } 331 | 332 | self.updateLogging(text: "Sign out completed successfully") 333 | self.accessToken = "" 334 | self.updateCurrentAccount(account: nil) 335 | }) 336 | 337 | } 338 | } 339 | } 340 | 341 | extension ViewController { 342 | 343 | func initUI() { 344 | 345 | usernameLabel = NSTextField() 346 | usernameLabel.translatesAutoresizingMaskIntoConstraints = false 347 | usernameLabel.stringValue = "" 348 | usernameLabel.isEditable = false 349 | usernameLabel.isBezeled = false 350 | self.view.addSubview(usernameLabel) 351 | 352 | usernameLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 30.0).isActive = true 353 | usernameLabel.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -10.0).isActive = true 354 | 355 | // Add call Graph button 356 | callGraphButton = NSButton() 357 | callGraphButton.translatesAutoresizingMaskIntoConstraints = false 358 | callGraphButton.title = "Call Microsoft Graph API" 359 | callGraphButton.target = self 360 | callGraphButton.action = #selector(callGraphAPI(_:)) 361 | callGraphButton.bezelStyle = .rounded 362 | self.view.addSubview(callGraphButton) 363 | 364 | callGraphButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true 365 | callGraphButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 50.0).isActive = true 366 | callGraphButton.heightAnchor.constraint(equalToConstant: 34.0).isActive = true 367 | 368 | // Add sign out button 369 | signOutButton = NSButton() 370 | signOutButton.translatesAutoresizingMaskIntoConstraints = false 371 | signOutButton.title = "Sign Out" 372 | signOutButton.target = self 373 | signOutButton.action = #selector(signOut(_:)) 374 | signOutButton.bezelStyle = .texturedRounded 375 | self.view.addSubview(signOutButton) 376 | 377 | signOutButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true 378 | signOutButton.topAnchor.constraint(equalTo: callGraphButton.bottomAnchor, constant: 10.0).isActive = true 379 | signOutButton.heightAnchor.constraint(equalToConstant: 34.0).isActive = true 380 | signOutButton.isEnabled = false 381 | 382 | // Add logging textfield 383 | loggingText = NSTextView() 384 | loggingText.translatesAutoresizingMaskIntoConstraints = false 385 | 386 | self.view.addSubview(loggingText) 387 | 388 | loggingText.topAnchor.constraint(equalTo: signOutButton.bottomAnchor, constant: 10.0).isActive = true 389 | loggingText.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 10.0).isActive = true 390 | loggingText.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: -10.0).isActive = true 391 | loggingText.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -10.0).isActive = true 392 | loggingText.widthAnchor.constraint(equalToConstant: 500.0).isActive = true 393 | loggingText.heightAnchor.constraint(equalToConstant: 300.0).isActive = true 394 | } 395 | 396 | func updateLogging(text : String) { 397 | 398 | if Thread.isMainThread { 399 | self.loggingText.string = text 400 | } else { 401 | DispatchQueue.main.async { 402 | self.loggingText.string = text 403 | } 404 | } 405 | } 406 | 407 | func updateSignOutButton(enabled : Bool) { 408 | if Thread.isMainThread { 409 | self.signOutButton.isEnabled = enabled 410 | } else { 411 | DispatchQueue.main.async { 412 | self.signOutButton.isEnabled = enabled 413 | } 414 | } 415 | } 416 | 417 | func updateAccountLabel() { 418 | 419 | guard let currentAccount = self.currentAccount else { 420 | self.usernameLabel.stringValue = "Signed out" 421 | return 422 | } 423 | 424 | self.usernameLabel.stringValue = currentAccount.username ?? "" 425 | self.usernameLabel.sizeToFit() 426 | } 427 | 428 | func updateCurrentAccount(account: MSALAccount?) { 429 | self.currentAccount = account 430 | self.updateAccountLabel() 431 | self.updateSignOutButton(enabled: account != nil) 432 | } 433 | } 434 | 435 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | 3 | platform :macos, '10.13' 4 | 5 | target 'MSALMacOS' do 6 | pod 'MSAL' 7 | end 8 | 9 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - MSAL (1.2.6): 3 | - MSAL/app-lib (= 1.2.6) 4 | - MSAL/app-lib (1.2.6) 5 | 6 | DEPENDENCIES: 7 | - MSAL (~> 1.2) 8 | 9 | SPEC REPOS: 10 | trunk: 11 | - MSAL 12 | 13 | SPEC CHECKSUMS: 14 | MSAL: bd4b040f859205c39b01859eb177974a7ec20704 15 | 16 | PODFILE CHECKSUM: de3de1ccdc09c7067ab7384c9106a9bdd495e1a0 17 | 18 | COCOAPODS: 1.11.2 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_type: sample 3 | languages: 4 | - swift 5 | client: 6 | - macOS Desktop App 7 | service: Microsoft Graph 8 | --- 9 | 10 | # MSAL macOS Swift Microsoft Graph API Sample 11 | 12 | ![Build Badge](https://identitydivision.visualstudio.com/_apis/public/build/definitions/a7934fdd-dcde-4492-a406-7fad6ac00e17/523/badge) 13 | 14 | | [Library](https://github.com/AzureAD/microsoft-authentication-library-for-objc) | [API Reference](https://azuread.github.io/docs/objc/) | [Support](README.md#feedback-community-help-and-support) 15 | | --- | --- | --- | 16 | 17 | The MSAL for macOS library gives your app the ability to begin using the [Microsoft identity platform](https://aka.ms/aaddev) by supporting [Microsoft Entra ID](https://azure.microsoft.com/services/active-directory/) and [Microsoft Accounts](https://account.microsoft.com/) in a converged experience using industry standard OAuth2 and OpenID Connect. This sample demonstrates all the normal lifecycle your application should experience, including: 18 | 19 | - How to get a token 20 | - How to refresh a token 21 | - How to call the Microsoft Graph API 22 | - How to sign a user out of your application 23 | 24 | ## Scenario 25 | 26 | This app is a multi-tenant app, meaning it can be used within any Microsoft Entra tenant and also supports Microsoft Account. It demonstrates how a developer can build apps to connect with enterprise users and access their Azure + O365 data via the Microsoft Graph. During the auth flow, end users will be required to sign in and consent to the permissions of the application, and in some cases may require an admin to consent to the app. The majority of the logic in this sample shows how to auth an end user and make a basic call to the Microsoft Graph. 27 | 28 | ## Prerequisites 29 | 30 | To run this sample, you'll need: 31 | 32 | * Xcode 33 | * An internet connection 34 | 35 | ## Setup 36 | 37 | Follow the steps below to setup the project and run the sample. 38 | 39 | ## Step 1 40 | 41 | ## 1A: Clone or download this repository 42 | 43 | From Terminal: 44 | 45 | ```terminal 46 | git clone https://github.com/Azure-Samples/ms-identity-macOS-swift-objc.git 47 | ``` 48 | or download and extract the repository.zip file, and navigate to 'MSALmacOS.xcworkspace' from the ms-identity-macOS-swift-objc folder 49 | 50 | ## 1B: Installation 51 | 52 | Load the podfile using cocoapods. This will create a new XCode Workspace you will load. 53 | 54 | From terminal navigate to the directory where the podfile is located 55 | 56 | ``` 57 | $ pod install 58 | ... 59 | $ open MSALmacOS.xcworkspace 60 | ``` 61 | 62 | ## 1C: Configure sample 63 | 64 | In the `ViewControler.swift` file, update the `kClientID` variable with `2a858956-70de-42b9-b5db-d566eb1fb820`. This is the default value for the sample. You can skip this step if you follow instructions in the step 2. 65 | 66 | ```swift 67 | let kClientID = "2a858956-70de-42b9-b5db-d566eb1fb820" 68 | ``` 69 | 70 | ## Step 2: (Optional) 71 | 72 | ## 2A: Register your App 73 | 74 | This app comes pre-configured for testing. If you would like to register your own app, please follow the steps below. 75 | 76 | To Register an app: 77 | 1. Sign in to the [Microsoft Entra admin center](https://entra.microsoft.com) using either a work or school account. 78 | 2. In the left-hand navigation pane, select the **Microsoft Entra ID** blade, and then select **App registrations**. 79 | 3. Click on the **New registration** button at the top left of the page. 80 | 4. On the app registration page, 81 | - Name your app 82 | - Under **Supported account types**, select **Accounts in any organizational directory (Any Microsoft Entra ID directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)** 83 | - Click **Register** to finish. 84 | 5. After the app is created, you'll land on your app management page. Take note of the **Application (client) ID** as this would be needed for the step 1B below. 85 | 6. Click **Authentication**, and add new Redirect URI with type **Public client (mobile & desktop)**. Enter redirect URI in format: `msauth.://auth`. Replace with the **Bundle Identifier** for your application. 86 | 7. Hit the **Save** button in the top left, to save these updates. 87 | 8. Click **Make this change for me** and then download the code sample for macOS 88 | 89 | ## Step 3: Run the sample 90 | 91 | 1. Click the Run Button in the top menu or go to Product from the menu tab and click Run. 92 | 2. Once the sample app launches, click on the 'Call Microsoft Graph API' button to go through the sign in flow and see the results from Microsoft Graph. 93 | 94 | ## How to add MSAL library into your existing Xcode project 95 | 96 | ## Step 1: Configure your application Info.plist 97 | 98 | Add URI scheme in the `Info.plist`. Redirect URI scheme follows the format `msauth.[app_bundle_id]`. Make sure to substitute [app_bundle_id] with the **Bundle Identifier** for your application. 99 | 100 | ```xml 101 | CFBundleURLTypes 102 | 103 | 104 | CFBundleURLSchemes 105 | 106 | msauth.[app_bundle_id] 107 | 108 | 109 | 110 | ``` 111 | 112 | ## Step 2: Configure your application defaults 113 | 114 | In your app, add the `kClientID` variable with your Application (client) ID. 115 | 116 | ```swift 117 | // For example, you can declare a client id in this way. Below ID is just a sample. 118 | 119 | let kClientID = "66855f8a-60cd-445e-a9bb-8cd8eadbd3fa" 120 | ``` 121 | 122 | Add variables with your Microsoft Entra authority and Microsoft Graph endpoint for your national cloud. 123 | 124 | ```swift 125 | let kGraphEndpoint = "https://graph.microsoft.com/" 126 | let kAuthority = "https://login.microsoftonline.com/common" 127 | ``` 128 | 129 | Other endpoints are documented [here](https://docs.microsoft.com/en-us/graph/deployments#app-registration-and-token-service-root-endpoints). For example, to run the sample with Azure Germany, use following: 130 | 131 | ```swift 132 | let kGraphEndpoint = "https://graph.microsoft.de/" 133 | let kAuthority = "https://login.microsoftonline.de/common" 134 | ``` 135 | 136 | ## Step 3: Configure Xcode project settings 137 | 138 | Add a new keychain group to your project **Signing & Capabilities**. The keychain group should be `com.microsoft.identity.universalstorage` on macOS. 139 | 140 | ![Xcode UI displaying how the the keychain group should be set up](./images/iosintro-keychainShare.png) 141 | 142 | ## Feedback, Community Help, and Support 143 | 144 | We use [Stack Overflow](http://stackoverflow.com/questions/tagged/msal) with the community to provide support. We highly recommend you ask your questions on Stack Overflow first and browse existing issues to see if someone has asked your question before. 145 | 146 | If you find a bug or have a feature request, please raise the issue on [GitHub Issues](../../issues). 147 | 148 | To provide a recommendation, visit our [User Voice page](https://feedback.azure.com/forums/169401-azure-active-directory). 149 | 150 | # Contribute 151 | 152 | We enthusiastically welcome contributions and feedback. You can clone the repo and start contributing now. 153 | 154 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 155 | 156 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 157 | 158 | 159 | ## Security Library 160 | 161 | This library controls how users sign-in and access services. We recommend you always take the latest version of our library in your app when possible. We use [semantic versioning](http://semver.org) so you can control the risk associated with updating your app. As an example, always downloading the latest minor version number (e.g. x.*y*.x) ensures you get the latest security and feature enhancements but our API surface remains the same. You can always see the latest version and release notes under the Releases tab of GitHub. 162 | 163 | ## Security Reporting 164 | 165 | If you find a security issue with our libraries or services please report it to [secure@microsoft.com](mailto:secure@microsoft.com) with as much detail as possible. Your submission may be eligible for a bounty through the [Microsoft Bounty](http://aka.ms/bugbounty) 166 | program. Please do not post security issues to GitHub Issues or any other public site. We will contact you shortly upon receiving the information. We encourage you to get notifications of when security incidents occur by visiting [this page](https://technet.microsoft.com/en-us/security/dd252948) and subscribing to Security Advisory Alerts. 167 | 168 | Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License (the "License"); 169 | -------------------------------------------------------------------------------- /images/iosintro-keychainShare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-macOS-swift-objc/f116da98eb7b7571244d43ced71be3202bcf3a94/images/iosintro-keychainShare.png --------------------------------------------------------------------------------