'"Access to this item is Restricted" user prompt when I have Implemented the above code and trying to read data from Keychain Access for that item
When I implement the below code Im facing an issue "Access to Item is Restricted" where I cannot read the Keychain item from Keychain Access when I have successfully performed write and read operations by allowing the keychain item with "Allow All Applications to access this item".

import Cocoa
import Foundation
import Security
import KeychainSwift
@main
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var mainview: NSView!
@IBOutlet var window: NSWindow!
@IBOutlet weak var password: NSSecureTextField!
@IBOutlet weak var username: NSTextField!
@IBOutlet weak var loginview: NSView!
@IBOutlet weak var success: NSView!
@IBOutlet weak var error: NSTextField!
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
mainview.addSubview(loginview)
}
func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}
func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
return true
}
@IBAction func login(_ sender: Any) {
// Write Data to Keychain...
var accessRef: SecAccess?
let accessCreateStatus = SecAccessCreateForAllApplications(
descriptor: "" as CFString, // Actually not necessary
accessRef: &accessRef
)
guard accessCreateStatus == errSecSuccess else { exit(EXIT_FAILURE) }
guard let access = accessRef else { exit(EXIT_FAILURE) }
let attributes: [CFString: Any] = [
kSecClass: kSecClassGenericPassword,
kSecAttrAccount: username.stringValue,
kSecValueData: password.stringValue.data(using: .utf8)!,
kSecAttrAccess: access
]
let itemAddStatus = SecItemAdd(attributes as CFDictionary, nil)
guard itemAddStatus == errSecSuccess else { exit(EXIT_FAILURE) }
// Read Data from Keychain...
var attributes1: [CFString: Any] = [
kSecClass: kSecClassGenericPassword,
kSecAttrAccount: username.stringValue,
kSecReturnData: kCFBooleanTrue as Any,
kSecMatchLimit: kSecMatchLimitOne,
kSecAttrAccessible : kSecAttrAccessibleAlways
]
var dataRef: AnyObject?
let status = SecItemCopyMatching(attributes1 as CFDictionary, &dataRef)
guard status == errSecSuccess else { exit(EXIT_FAILURE) }
guard let data = dataRef as? Data else { exit(EXIT_FAILURE) }
guard let string = String(data: data, encoding: .utf8) else { exit(EXIT_FAILURE) }
print("THE VALUE FOR THE KEY IS:", string) // => bar
//
mainview.replaceSubview(loginview, with: success)
}
func SecAccessCreateForAllApplications(
descriptor: CFString,
accessRef outerAccessRef: UnsafeMutablePointer<SecAccess?>
) -> OSStatus {
var accessRef: SecAccess?
// Create an access object with access granted to no application (2nd parameter).
// It comes configured with 3 default ACLs.
let accessCreateStatus = SecAccessCreate(
descriptor,
[] as CFArray, // No application has access
&accessRef
)
guard accessCreateStatus == errSecSuccess else { return accessCreateStatus }
guard let access = accessRef else { return accessCreateStatus }
// Extract the default ACLs from the created access object for the *decrypt* authorization tag.
guard let aclList = SecAccessCopyMatchingACLList(
access,
kSecACLAuthorizationDecrypt
) as? [SecACL] else { return errSecInvalidACL }
// There should be exactly one ACL for the *decrypt* authorization tag.
guard aclList.count == 1 else { return errSecInvalidACL }
guard let decryptACL = aclList.first else { return errSecInvalidACL }
// Extract all authorizations from the default ACL for the *decrypt* authorization tag.
let allAuthorizations = SecACLCopyAuthorizations(decryptACL)
// Remove the default ACL for the *decrypt* authorization tag from the access object.
let aclRemoveStatus = SecACLRemove(decryptACL)
guard aclRemoveStatus == errSecSuccess else { return aclRemoveStatus }
// Create a new ACL with access for all applications and add it to the access object.
var newDecryptACLRef: SecACL?
let aclCreateStatus = SecACLCreateWithSimpleContents(
access,
nil, // All applications have access
descriptor,
[], // Empty prompt selector
&newDecryptACLRef
)
guard aclCreateStatus == errSecSuccess else { return aclCreateStatus }
guard let newDecryptACL = newDecryptACLRef else { return aclCreateStatus }
// Set the authorizations extracted from the default ACL to the newly created ACL.
let aclUpdateAuthorizationStatus = SecACLUpdateAuthorizations(newDecryptACL, allAuthorizations)
guard aclUpdateAuthorizationStatus == errSecSuccess else { return aclUpdateAuthorizationStatus }
// Finally, write the access to the outer pointer.
outerAccessRef.initialize(to: access)
return errSecSuccess
}
}
Please Help me to solve this Issue!!!
The Above Code is refered from @Lukas Kubanek
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
