I’m working on an application where when a user selects a menu item they are brought to a webpage. The webpage requires authentication, and to make things simpler for the user I would like to pass along their authentication information to Safari/Firefox/Chrome that is stored in my application.
I’ve tried creating generic and internet keychain items, which show up beautifully in Keychain Access, but no web browsers pick up on them.
I’ve noticed that the keychain items being stored for the browsers have the type “Web Form Password”.
When I try to create a keychain item with the type ‘kSecAuthenticationTypeHTMLForm’ it shows in Keychain Access as ‘internet password’. I’ve modified some code from the EMKeychain class:
+ (EMInternetKeychainItem *)addInternetKeychainItemForServer:(NSString *)server
withUsername:(NSString *)username
password:(NSString *)password
path:(NSString *)path
port:(NSInteger)port
protocol:(SecProtocolType)protocol
{
if (!username || !server || !password)
return nil;
const char *serverCString = [server UTF8String];
const char *usernameCString = [username UTF8String];
const char *passwordCString = [password UTF8String];
const char *pathCString = [path UTF8String];
if (!path || [path length] == 0)
pathCString = "";
SecKeychainItemRef item = nil;
OSStatus returnStatus = SecKeychainAddInternetPassword(NULL, strlen(serverCString), serverCString, 0, NULL, strlen(usernameCString), usernameCString, strlen(pathCString), pathCString, port, protocol, kSecAuthenticationTypeHTMLForm, strlen(passwordCString), (void *)passwordCString, &item);
if (returnStatus != noErr || !item)
{
if (_logsErrors)
NSLog(@"Error (%@) - %s", NSStringFromSelector(_cmd), GetMacOSStatusErrorString(returnStatus));
return nil;
}
return [EMInternetKeychainItem _internetKeychainItemWithCoreKeychainItem:item forServer:server username:username password:password path:path port:port protocol:protocol];
}
The most likely problem is that the keychain entry is created with an ACL that does not give access to its contents to Safari. (I think Chrome and Firefox use their own proprietary password databases instead of the keychain, so modifying the keychain won’t affect those browsers.)
Try using
SecKeychainItemSetAccessto permit access to all applications. I use the following code to create such a permissive SecAccess object: