azure-activedirectory-library-for-objc
azure-activedirectory-library-for-objc copied to clipboard
Problem with NSURLRequest caching and ADURLProtocol on macOS
I am using the ADAL v2.5.1 release from Swift developing with the macOS 10.12 SDK and running on macOS 10.12.6. When I use it like so (no other code related to caching anywhere):
let authContext = ADAuthenticationContext(authority: authorityURL, error: error)
authContext.acquireToken(withResource: AZURE_RESOURCE_ID,
clientId: clientId,
redirectUri: URL(string: AZURE_REDIRECT_URL_STRING),
userId: nil,
extraQueryParameters: queryParams,
completionBlock: { (result) in
// use result here
})
I get the following errors logged:
ERROR: createEncodedCachedResponseAndRequestForXPCTransmission - Invalid protocol-property list - CFURLRequestRef. protoProps=<CFBasicHash 0x7fd6dc71d050 [0x7fffa1a9cda0]>{type = mutable dict, count = 1,
entries =>
0 : <CFString 0x105b12210 [0x7fffa1a9cda0]>{contents = "context"} = <ADWebAuthRequest: 0x7fd6dc7180d0>
}
ADD: failed to create cache dictionary at path=/Users/<mylocalacct>/Library/Caches/<mybundleid>. key=0x7fd6dc71a590
This appears to be a problem with NSURLRequest caching and the ADURLProtocol putting the context as a property into NSURLProtocol in the +addContext:toRequest: method in ADURLProtocol.m line 106: [NSURLProtocol setProperty:context forKey:@"context" inRequest:request]. This value is retrieved at line 42: [NSURLProtocol propertyForKey:@"context" inRequest:request].
Some StackOverflow posts seem to indicate that objects given to NSURLProtocol's setProperty:forKey:inRequest: should be property list serializable, although that's not explicitly stated in Apple's documentation. Can the caching be disabled somehow, or the property data be encoded/decoded for use in the context property?
@unpluggedk Can you take a look at this, when you have time?
@macblazer Can you give me some more detail? I've tried to repro this, and was not successful on macOS 10.12.6 with ADAL v2.5.1 on Swift.
- Does it always happen and when does it happen? (i.e./ Do you need to run it multiple times or happens at the first go)
- What is in the extraQueryParameters?
Any other information for me to reproduce this would be very helpful.
Thanks
It happens every time I call that authContext.acquireToken function when it has to pop open a window.
I am using the ADTokenCacheDelegate protocol to save tokens between launches. If it has the cached token, then no window is shown and the warning doesn't appear. If the cache is empty or expired, the window to login opens up and the warning message is shown.
I use this little function to come up with the String for extraQueryParameters.
func extraQueryParameters(forDomain tenantDomain: String) -> String {
let claims = "{\"access_token\":{\"deviceid\":{\"essential\":true}}}"
let encodedClaims = claims.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
let encodedDomain = tenantDomain.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
return "claims=\(encodedClaims!)&domain_hint=\(encodedDomain!)"
}
@macblazer, @unpluggedk, is there any development on this issue? I'm experiencing the very same issue on ADAL 2.5.3 while developing an iOS App (Swift 4/ Xcode 9.2).
Here's how I get the token from AAD (as seen in Microsoft's Guides):
func getToken(clearCache: Bool, parent: UIViewController, completion: @escaping (_ userInfo: ADUserInformation?, _ error: NSError?) -> Void)
{
let error: AutoreleasingUnsafeMutablePointer<ADAuthenticationError?>? = nil
var authenticationContext: ADAuthenticationContext
authenticationContext = ADAuthenticationContext(authority: config.authority!, error: error)
authenticationContext.parentController = parent
authenticationContext.acquireToken(
withResource: config.resource!,
clientId: config.clientId,
redirectUri: URL(string: config.redirectUri!),
promptBehavior: AD_PROMPT_AUTO,
userId: nil,
extraQueryParameters: "nux=1" ) { [weak self] optResult in
if let result = optResult {
if result.status != AD_SUCCEEDED {
print("Error: \(result.error.errorDetails)")
completion(nil, (result.error)!)
} else {
self?.token = result.accessToken
self?.username = (result.tokenCacheItem.userInformation?.userId)!
completion(result.tokenCacheItem.userInformation, nil)
}
} else {
print("Error: no result from token call")
}
}
}
Since it works more like a warning, I've been ignoring this error for now, but I'd like to know if there's something I could do to fix it
2.5.4 as well on iOS App (Swift 4/ Xcode 9.2).
It actually appears to not even be popping up the window to put in a password but I'm unsure if this is in relation to another issue in my code.
This is my code:
func getToken(username: String, completionBlock: @escaping (String) -> Void){
let error: AutoreleasingUnsafeMutablePointer<ADAuthenticationError?>? = nil
let authContext = ADAuthenticationContext(authority: "https://login.microsoftonline.com/common", error: error)
authContext?.acquireToken(withResource: "https://graph.windows.net", clientId: clientID, redirectUri: redirectURI, userId: username, completionBlock: { (result: ADAuthenticationResult!) in
if (AD_SUCCEEDED != result.status){
let loginFail = UIAlertController(title: "Login Failed", message: result.error.errorDetails, preferredStyle: .alert)
let retry = UIAlertAction(title: "Retry", style: .cancel, handler: { (UIAlertAction) in self.getToken(username: username, completionBlock: completionBlock)})
loginFail.addAction(retry)
if self.window?.rootViewController is LoginViewController{
self.window?.rootViewController?.present(loginFail, animated: true, completion: nil)
}
else{
(self.window?.rootViewController as! UINavigationController).topViewController?.present(loginFail, animated: true, completion: nil)
}
}
else{
completionBlock(result.accessToken);
}
})
}
This seems to be happening because of carrying the whole request context in ADURLProtocol:
[NSURLProtocol setProperty:context forKey:@"context" inRequest:request];
This can be fixed by either making sure request context is compatible with NSURLProtocol or saving only correlationId for logging purposes. This has to be done on ADAL side.
Hi,
I am using ADAL 2.7.7 and IntuneMAM SDK for IOS application.
Intune policy works for the first time after which when uninstalled and installed the app it does not work
It give below error:
ERROR: createEncodedCachedResponseAndRequestForXPCTransmission - Invalid protocol-property list - CFURLRequestRef. protoProps=<CFBasicHash 0x7fd6dc71d050 [0x7fffa1a9cda0]>{type = mutable dict, count = 1,
I used the Intune wrapping tool which has ADAL version 2.6.3 it gives different error ADAL 2.6.3 iOS 12.1.4 [2019-02-19 17:57:59] INFO: Found 2 token(s) for query