SwiftUI-MSALSample
I could not find a good walkthrough on how to implement MSAL with SwiftUI, everything is written for UIKit unfortunately and even then it wasn't clear IMO.
I started following the walkthrough Microsoft Authentication Library for iOS and macOS on github and then pieced together the rest using Stack Overflow.
There is still some work to be done. Please feel free to open a PR for any code improvements or adding features!
Getting Started the Short Version.
- Download the project.
- Follow the instructions listed on the AzureAD github to register your app within the Azure Portal.
- You will also want to follow the steps listed on adding MSAL to your project listed here.
- Updated
clientID
andredirectUri
inMSALLogin.swift
-MSALPublicClientApplicationConfig(clientId: clientID, redirectUri: redirectUri, authority: authority)
with the information you got from when you registered your app in the azure portal.
Getting Started:
Installation
- I followed the instructions listed on the AzureAD github to register your app within the Azure Portal.
- You will also want to follow the steps listed on adding MSAL to your project listed here.
After step 2 is a bit where I got lost so I'm hoping this sample project will help.
Using This Sample Project
- Majority of the code is
MSALLogin.swift
and the big chuck of the code below is how you will login with MSAL. - You'll want to replace
clientID
andredirectUri
inMSALPublicClientApplicationConfig(clientId: clientID, redirectUri: redirectUri, authority: authority)
with the information you got from when you registered your app in the azure portal. (Note: I have this info stored in a file that I did not upload.) - Depending on your project you'll may also need to update your
scopes
inlet interactiveParameters = MSALInteractiveTokenParameters(scopes: ["user.read"], webviewParameters: webViewParameters)
do {
let authority = try MSALB2CAuthority(url: URL(string: "https://login.microsoftonline.com/common")!)
let pcaConfig = MSALPublicClientApplicationConfig(clientId: clientID, redirectUri: redirectUri, authority: authority)
let application = try MSALPublicClientApplication(configuration: pcaConfig)
let webViewParameters = MSALWebviewParameters(authPresentationViewController: self)
let interactiveParameters = MSALInteractiveTokenParameters(scopes: ["user.read"], webviewParameters: webViewParameters)
application.acquireToken(with: interactiveParameters) { (result, error) in
guard let result = result else {
print("error \(error?.localizedDescription)")
return
}
if let account = result.account.username {
print("logging \(account)")
// accountName = account
msalModel.accountName = account
msalModel.scopes = result.scopes
print("logging \(result.account.description)")
UIApplication.shared.windows.first {
$0.isKeyWindow
}!.rootViewController = UIHostingController(rootView: ContentView())
}
}
} catch {
print("\(#function) logging error \(error)")
}
- The rest of the code within
MSALLogin.swift
are methods and classes so UIKit and SwiftUI can work together.
Getting this to work with SwiftUI
- In
ContentView.swift
I declated a@StateObject
linking back toMSALScreenViewModel()
that I created inMSALLogin.swift
. - Within
ContentView.swift
I created a button that callsmsalModel.loadMSALScreen()
and then added the UIKit viewMSALScreenView_UI(viewModel: msalModel)
. Just a heads up, but depending on how you implament this you will need to adjust the frame.
Challenges and Learning
- I'm not sure how I can dump
result.account.username
into the@Published var
to use in other views. This will be beneficial for tokens to make other calls within MSFT products. - I have not explored adding a sign out option.
- I'm unsure of how long the token would be for without having a silent refresh implemented.
- The biggest thing I learned is that Microsoft is not quite ready for SwiftUI and their documentation is lacking IMO for developers at least compared to Google Firebase. I do hope this changes in time.