Skip to content

Commit 10f8733

Browse files
authored
Native auth: add backward compatibility feature (capabilities) (#2645)
* Native auth: backward compatibility, add new capabilities parameter (#2635) * add new capabilities ns option, add new config class for native auth * add public comments, add new init and deprecated old methods * Rename internal config class, call one single init method in application class * fix issue on super init method * Add capabilities to internal configuration * send capabilities to first call of each flows * call new init application method * use correct comment * fix unit tests * fix integration and unit tests * add new tests for request parameters and capabilities * add new tests * fix indentation, rename test variables * remove unused method * rewording public capabilities comment * removed otp challenge type because not required * Native auth: add redirect reason to all native auth HTTP response (#2642) * add new capabilities ns option, add new config class for native auth * add public comments, add new init and deprecated old methods * Rename internal config class, call one single init method in application class * fix issue on super init method * Add capabilities to internal configuration * send capabilities to first call of each flows * call new init application method * use correct comment * fix unit tests * fix integration and unit tests * add new tests for request parameters and capabilities * add new tests * parse new field redirect reason and send browser required when needed * parse token response when redirect response is received * add new test for native auth CIAM token response * add browser required to all SDK public error responses * add new test for redirect * create generic native auth error to remove repeated code * add new tests for redirect in controllers * add new test for duplicate capabilities * add new tests for redirect * update changelog * New integration tests for redirect * fix bugs for SSPR responses, all fields should be optional * add new test, remove todo comment * address PR comments
1 parent 0f60c64 commit 10f8733

File tree

169 files changed

+1773
-733
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

169 files changed

+1773
-733
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## TBD
2+
* Make native auth MFA feature more backward compatible (#2645)
3+
14
## [2.1.0]
25
* Integrate Broker XPC service into Mac Sample app
36
* Update minimum supported version to iOS 16.0 and macOS 11.0 (#2623)

MSAL/MSAL.xcodeproj/project.pbxproj

Lines changed: 84 additions & 6 deletions
Large diffs are not rendered by default.

MSAL/src/native_auth/client_application_wrapper/silent_token/MSALNativeAuthSilentTokenProvider.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,9 @@ class MSALNativeAuthSilentTokenProvider: MSALNativeAuthSilentTokenProviding {
2727

2828
private let application: MSALNativeAuthPublicClientApplication?
2929

30-
init(
31-
configuration config: MSALPublicClientApplicationConfig,
32-
challengeTypes: MSALNativeAuthChallengeTypes) throws {
33-
self.application = try? MSALNativeAuthPublicClientApplication(configuration: config, challengeTypes: challengeTypes)
34-
}
30+
init(configuration: MSALNativeAuthPublicClientApplicationConfig) throws {
31+
self.application = try? MSALNativeAuthPublicClientApplication(nativeAuthConfiguration: configuration)
32+
}
3533

3634
func acquireTokenSilent(parameters: MSALSilentTokenParameters,
3735
completionBlock: @escaping MSALNativeAuthSilentTokenResponse) {

MSAL/src/native_auth/client_application_wrapper/silent_token/factory/MSALNativeAuthSilentTokenProviderBuildable.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,5 @@
2323
// THE SOFTWARE.
2424

2525
protocol MSALNativeAuthSilentTokenProviderBuildable {
26-
func makeSilentTokenProvider(configuration: MSALPublicClientApplicationConfig,
27-
challengeTypes: MSALNativeAuthChallengeTypes) throws -> MSALNativeAuthSilentTokenProviding?
26+
func makeSilentTokenProvider(configuration: MSALNativeAuthPublicClientApplicationConfig) throws -> MSALNativeAuthSilentTokenProviding?
2827
}

MSAL/src/native_auth/client_application_wrapper/silent_token/factory/MSALNativeAuthSilentTokenProviderFactory.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@
2323
// THE SOFTWARE.
2424

2525
class MSALNativeAuthSilentTokenProviderFactory: MSALNativeAuthSilentTokenProviderBuildable {
26-
func makeSilentTokenProvider(configuration: MSALPublicClientApplicationConfig,
27-
challengeTypes: MSALNativeAuthChallengeTypes) throws -> MSALNativeAuthSilentTokenProviding? {
28-
return try? MSALNativeAuthSilentTokenProvider(configuration: configuration, challengeTypes: challengeTypes)
26+
func makeSilentTokenProvider(configuration: MSALNativeAuthPublicClientApplicationConfig) throws -> MSALNativeAuthSilentTokenProviding? {
27+
return try? MSALNativeAuthSilentTokenProvider(configuration: configuration)
2928
}
3029
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
//
2+
// Copyright (c) Microsoft Corporation.
3+
// All rights reserved.
4+
//
5+
// This code is licensed under the MIT License.
6+
//
7+
// Permission is hereby granted, free of charge, to any person obtaining a copy
8+
// of this software and associated documentation files(the "Software"), to deal
9+
// in the Software without restriction, including without limitation the rights
10+
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
11+
// copies of the Software, and to permit persons to whom the Software is
12+
// furnished to do so, subject to the following conditions :
13+
//
14+
// The above copyright notice and this permission notice shall be included in
15+
// all copies or substantial portions of the Software.
16+
//
17+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
20+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
// THE SOFTWARE.
24+
25+
@_implementationOnly import MSAL_Private
26+
27+
struct MSALNativeAuthInternalConfiguration {
28+
var challengeTypesString: String {
29+
return challengeTypes.map { $0.rawValue }.joined(separator: " ")
30+
}
31+
32+
var capabilitiesString: String? {
33+
return capabilities?.map { $0.rawValue }.joined(separator: " ")
34+
}
35+
36+
let clientId: String
37+
let authority: MSIDCIAMAuthority
38+
let challengeTypes: [MSALNativeAuthInternalChallengeType]
39+
let capabilities: [MSALNativeAuthInternalCapability]?
40+
let redirectUri: String?
41+
var sliceConfig: MSALSliceConfig?
42+
43+
init(
44+
clientId: String,
45+
authority: MSALCIAMAuthority,
46+
challengeTypes: MSALNativeAuthChallengeTypes,
47+
capabilities: MSALNativeAuthCapabilities?,
48+
redirectUri: String?) throws {
49+
self.clientId = clientId
50+
self.authority = try MSIDCIAMAuthority(
51+
url: authority.url,
52+
validateFormat: false,
53+
context: MSALNativeAuthRequestContext()
54+
)
55+
self.challengeTypes = MSALNativeAuthInternalConfiguration.getInternalChallengeTypes(challengeTypes)
56+
self.capabilities = MSALNativeAuthInternalConfiguration.getInternalCapabilities(capabilities)
57+
self.redirectUri = redirectUri
58+
}
59+
60+
private static func getInternalChallengeTypes(
61+
_ challengeTypes: MSALNativeAuthChallengeTypes
62+
) -> [MSALNativeAuthInternalChallengeType] {
63+
var internalChallengeTypes = [MSALNativeAuthInternalChallengeType]()
64+
65+
if challengeTypes.contains(.OOB) {
66+
internalChallengeTypes.append(.oob)
67+
}
68+
69+
if challengeTypes.contains(.password) {
70+
internalChallengeTypes.append(.password)
71+
}
72+
73+
internalChallengeTypes.append(.redirect)
74+
return internalChallengeTypes
75+
}
76+
77+
private static func getInternalCapabilities(
78+
_ capabilities: MSALNativeAuthCapabilities?
79+
) -> [MSALNativeAuthInternalCapability]? {
80+
guard let capabilities else { return nil }
81+
var internalCapabilities: [MSALNativeAuthInternalCapability] = []
82+
83+
if capabilities.contains(.mfaRequired) {
84+
internalCapabilities.append(.mfaRequired)
85+
}
86+
87+
if capabilities.contains(.registrationRequired) {
88+
internalCapabilities.append(.registrationRequired)
89+
}
90+
return internalCapabilities
91+
}
92+
}

MSAL/src/native_auth/controllers/MSALNativeAuthTokenController.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class MSALNativeAuthTokenController: MSALNativeAuthBaseController {
5454
func performAndValidateTokenRequest(
5555
_ request: MSIDHttpRequest,
5656
context: MSALNativeAuthRequestContext) async -> MSALNativeAuthTokenValidatedResponse {
57-
let ciamTokenResponse: Result<MSIDCIAMTokenResponse, Error> = await performTokenRequest(request, context: context)
57+
let ciamTokenResponse: Result<MSALNativeAuthCIAMTokenResponse, Error> = await performTokenRequest(request, context: context)
5858
return responseValidator.validate(
5959
context: context,
6060
result: ciamTokenResponse
@@ -206,7 +206,10 @@ extension MSALNativeAuthTokenController {
206206
}
207207
}
208208

209-
private func performTokenRequest(_ request: MSIDHttpRequest, context: MSIDRequestContext) async -> Result<MSIDCIAMTokenResponse, Error> {
209+
private func performTokenRequest(
210+
_ request: MSIDHttpRequest,
211+
context: MSIDRequestContext
212+
) async -> Result<MSALNativeAuthCIAMTokenResponse, Error> {
210213
return await withCheckedContinuation { continuation in
211214
request.send { response, error in
212215
if let error = error {
@@ -218,8 +221,9 @@ extension MSALNativeAuthTokenController {
218221
return
219222
}
220223
do {
221-
let tokenResponse = try MSIDCIAMTokenResponse(jsonDictionary: responseDict)
222-
tokenResponse.correlationId = request.context?.correlationId().uuidString
224+
let tokenResponse = try MSALNativeAuthCIAMTokenResponse(jsonDictionary: responseDict)
225+
// use request correlation id if server doesn't return one
226+
tokenResponse.correlationId = tokenResponse.correlationId ?? request.context?.correlationId().uuidString
223227
continuation.resume(returning: .success(tokenResponse))
224228
} catch {
225229
MSALNativeAuthLogger.log(level: .error, context: context, format: "Error token request - Both result and error are nil")

MSAL/src/native_auth/controllers/credentials/MSALNativeAuthCredentialsController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ final class MSALNativeAuthCredentialsController: MSALNativeAuthTokenController,
5050
)
5151
}
5252

53-
convenience init(config: MSALNativeAuthConfiguration, cacheAccessor: MSALNativeAuthCacheInterface) {
53+
convenience init(config: MSALNativeAuthInternalConfiguration, cacheAccessor: MSALNativeAuthCacheInterface) {
5454
let factory = MSALNativeAuthResultFactory(config: config, cacheAccessor: cacheAccessor)
5555
self.init(
5656
clientId: config.clientId,

MSAL/src/native_auth/controllers/factories/MSALNativeAuthControllerFactory.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ protocol MSALNativeAuthControllerBuildable {
3131
}
3232

3333
final class MSALNativeAuthControllerFactory: MSALNativeAuthControllerBuildable {
34-
private let config: MSALNativeAuthConfiguration
34+
private let config: MSALNativeAuthInternalConfiguration
3535

36-
init(config: MSALNativeAuthConfiguration) {
36+
init(config: MSALNativeAuthInternalConfiguration) {
3737
self.config = config
3838
}
3939

MSAL/src/native_auth/controllers/factories/MSALNativeAuthResultFactory.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
protocol MSALNativeAuthResultBuildable {
2828

29-
var config: MSALNativeAuthConfiguration {get}
29+
var config: MSALNativeAuthInternalConfiguration {get}
3030

3131
func makeAccount(tokenResult: MSIDTokenResult, context: MSIDRequestContext) -> MSALAccount
3232

@@ -39,10 +39,10 @@ protocol MSALNativeAuthResultBuildable {
3939

4040
final class MSALNativeAuthResultFactory: MSALNativeAuthResultBuildable {
4141

42-
let config: MSALNativeAuthConfiguration
42+
let config: MSALNativeAuthInternalConfiguration
4343
let cacheAccessor: MSALNativeAuthCacheInterface
4444

45-
init(config: MSALNativeAuthConfiguration, cacheAccessor: MSALNativeAuthCacheInterface) {
45+
init(config: MSALNativeAuthInternalConfiguration, cacheAccessor: MSALNativeAuthCacheInterface) {
4646
self.config = config
4747
self.cacheAccessor = cacheAccessor
4848
}

0 commit comments

Comments
 (0)