Display Authorization plugin at screensaver unlock

I have an app which displays an NSWindow at the Login window using a non-privileged mechanism using authorization plugin.

I added the mechanism in system.login.console entry of authdb and it works fine on switch-user, reboot cases.

I want the app to be invoked at the screensaver unlock as well.

I tried adding the mechanism in the "authenticate" entry of authdb, but my app is not getting invoked in the screensaver unlock case.


If I modify the system.login.screensaver rule to use “authenticate-session-owner-or-admin” instead of “use-login-window-ui”, then the plugin is invoked but the login screen is displayed in older UI and touchid authentication doesn’t work with this screen.


Using SFAuthorizationPluginView also helps me display the UX and invoke my app, but that would require re-writing the complete loginwindow process.


Please suggest a way to invoke my app in screensaver scenario using the default loginwindow UI, which supports touchid authentication as well.

Replies

If I modify the

system.login.screensaver
rule to use
authenticate-session-owner-or-admin
instead of
use-login-window-ui
, then the plugin is invoked but the login screen is displayed in older UI and [Touch ID] authentication doesn’t work with this screen.

I believe that this is expected behaviour )-: The

use-login-window-ui
mechanism causes the system to run the fancy new code path with Touch ID and so on, one that’s not compatible with third-party authorisation plug-ins. If you remove that then you fall back to a legacy code path that is compatible with third-party authorisation plug-ins, but you lose all the nice new features.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

With the older code path of authenticate-session-owner-or-admin, where would be the custom evaluate-mechanisms mechanism insertion point in the authentication database?

The basic idea is to modify the screen saver right along the lines of the console login right. You can dump these using the following commands.

$ security authorizationdb read system.login.screensaver
$ security authorizationdb read system.login.console

I don’t have an exact recipe for this because it’s not something I support. I’m hoping that pradeepfromsymc will chime in here. If not, my recommendation is that you open a DTS tech support incident and talk to our Authorization Services expert.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

The evaluate mechanism insertion point is in the "authenticate" rights.


security authorizationdb read authenticate

I am looking for a solution to the same problem... the suggestion by pradeepfromsymc is a bit too cryptic for me so any suggestions would be appreciated.

Hi


Were you able to solve your problem somehow? Btw, how did you modify mechanisms in authenticate? My plugins are not being launched for some reason.


Sorry, they are launching alright, but the window is not presented for some reason.

We have written succesfully an authorization plugin called GMIAuthPlugin. This plugin works very well on the initial login. We allow for an out of band 2 factor authorization at the login screen. We even allow for passwordless login today. Our next goal is to display this auth plugin when waking from the screen saver or locking the machine. We have tried the following plist to system.login.screensaver. This gets us close but not all the way. In doing some reading it has been stated that we need to use the older login rule <string>authenticate-session-owner-or-admin</string> instead of the newer rule use-login-window-ui. I have not been able to configure both a mechanism and a login rule in the system.login.screensaver successfully. I am sure this is possible and maybe I am missing something obvious. Using the command Security authorizationdb write system.login.screensaver authenticate-session-owner-or-admin overwrites the whole plist file and does not keep the mechanism part we want.



I have read this:

https://forums.developer.apple.com/thread/86537


And this thread:

https://forums.developer.apple.com/thread/110667


Here is our current system.login.screensaver plist. This displays our auth plugin. Our end goal is to send an out of band mobile message to our platform which will then unlock and login without manually typing the user’s password which we save and present for authorization.




<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<plist version="1.0">

<dict>

<key>allow-root</key>

<false/>

<key>authenticate-user</key>

<true/>

<key>class</key>

<string>user</string>

<key>created</key>

<real>592759977.27845001</real>

<key>group</key>

<string>admin</string>

<key>mechanisms</key>

<array>

<string>GMIAuthPlugin:invoke</string>

<string>builtin:authenticate,privileged</string>

<string>builtin:auto-login,privileged</string>

<string>builtin:forward-login,privileged</string>

<string>PKINITMechanism:auth,privileged</string>

</array>

<key>modified</key>

<real>601410763.90900505</real>

<key>session-owner</key>

<true/>

<key>shared</key>

<false/>

<key>timeout</key>

<integer>2147483647</integer>

<key>tries</key>

<integer>10000</integer>

<key>version</key>

<integer>0</integer>

<key>class</key>

<string>rule</string>

<key>created</key>

<real>472414282.07143301</real>

<key>modified</key>

<real>498674468.80855602</real>

<key>version</key>

<integer>0</integer> </dict> </plist>

</dict>

</plist>

@ pradeepfromsymc

Using SFAuthorizationPluginView also helps me display the UX and invoke my app

I have written an authorization plugin using SFAuthorizationPluginView and it does get invoked at the lock screen but it doesn't display the UI at all. I get an alert box saying "You must enter your password to continue" with OK and Cancel buttons.
If I just set rule (method below) to "authenticate-session-owner-or-admin" in system.login.screensaver while not adding mechanism of my Authorization Plugin in 'authenticate' then I get editable username and password fields and I can login with native macOS credentials.

@eskimo

Code Block
use-login-window-ui

If you remove that then you fall back to a legacy code path that is compatible with third-party authorisation plug-ins
I've tried to invoke my Authorization Plugin at lock screen by doing this. But, it displays only a black screen if I write my mechanism in the "authenticate" entry of authdb. It displays username and password fields (NOT a feature of my auth plugin) if "authenticate" entry of authdb is not changed.
I've tried this:
Code Block
sudo security authorizationdb write system.login.screensaver < myfile.plist

The file is:
Code Block xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>allow-root</key>
<false/>
<key>authenticate-user</key>
<true/>
<key>class</key>
<string>rule</string>
<key>comment</key>
<string>The owner or any administrator can unlock the screensaver, set rule to "authenticate-session-owner-or-admin" to enable SecurityAgent.</string>
<key>created</key>
<real>619370235.93105304</real>
<key>modified</key>
<real>619370235.93105304</real>
<key>rule</key>
<array>
<string>authenticate-session-owner-or-admin</string>
</array>
<key>session-owner</key>
<true/>
<key>version</key>
<integer>1</integer>
</dict>
</plist>

I've used this file also:
Code Block xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>allow-root</key>
<false/>
<key>authenticate-user</key>
<true/>
<key>class</key>
<string>user</string>
<key>created</key>
<real>592759977.27845001</real>
<key>group</key>
<string>admin</string>
<key>mechanisms</key>
<array>
<string>CustomAuthorizationPlugin:invoke</string>
<string>builtin:authenticate,privileged</string>
<string>builtin:auto-login,privileged</string>
<string>builtin:forward-login,privileged</string>
<string>PKINITMechanism:auth,privileged</string>
</array>
<key>rule</key>
<array>
<string>authenticate-session-owner-or-admin</string>
</array>
<key>modified</key>
<real>601410763.90900505</real>
<key>session-owner</key>
<true/>
<key>shared</key>
<false/>
<key>timeout</key>
<integer>2147483647</integer>
<key>tries</key>
<integer>10000</integer>
<key>modified</key>
<real>498674468.80855602</real>
<key>version</key>
<integer>0</integer>
</dict>
</plist>

I've changed authenticate entry of authDB using:
Code Block shell
sudo security authorizationdb write authenticate < myfile.plist

My file for it is:
Code Block xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>allow-root</key>
<false/>
<key>authenticate-user</key>
<true/>
<key>class</key>
<string>user</string>
<key>created</key>
<real>619370235.93105304</real>
<key>group</key>
<string>admin</string>
<key>mechanisms</key>
<array>
<string>CustomAuthorizationPlugin:invoke</string>
<string>builtin:forward-login,privileged</string>
<string>builtin:auto-login,privileged</string>
<string>builtin:authenticate,privileged</string>
<string>PKINITMechanism:auth,privileged</string>
</array>
<key>modified</key>
<real>619370235.93105304</real>
<key>session-owner</key>
<true/>
<key>shared</key>
<false/>
<key>timeout</key>
<integer>2147483647</integer>
<key>tries</key>
<integer>10000</integer>
<key>version</key>
<integer>0</integer>
</dict>
</plist>

I've even tried this:
Code Block xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>allow-root</key>
<false/>
<key>authenticate-user</key>
<true/>
<key>class</key>
<string>user</string>
<key>created</key>
<real>619370235.93105304</real>
<key>group</key>
<string>admin</string>
<key>mechanisms</key>
<array>
<string>CustomAuthorizationPlugin:invoke</string>
</array>
<key>modified</key>
<real>619370235.93105304</real>
<key>session-owner</key>
<true/>
<key>shared</key>
<false/>
<key>timeout</key>
<integer>2147483647</integer>
<key>tries</key>
<integer>10000</integer>
<key>version</key>
<integer>0</integer>
</dict>
</plist>


__
Code Block swift
let domain = "hotmail.com"
let temp = "1_1"
let mail = "rehan\(temp)@\(domain)"


and this:
Code Block xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>class</key>
<string>evaluate-mechanisms</string>
<key>created</key>
<real>619370235.93105304</real>
<key>mechanisms</key>
<array>
<string>builtin:authenticate</string>
<string>CustomAuthorizationPlugin:invoke</string>
<string>builtin:reset-password,privileged</string>
<string>builtin:authenticate,privileged</string>
<string>PKINITMechanism:auth,privileged</string>
</array>
<key>modified</key>
<real>619370235.93105304</real>
<key>shared</key>
<true/>
<key>tries</key>
<integer>10000</integer>
<key>version</key>
<integer>0</integer>
</dict>
</plist>


I've tried multiple different file entries for both 'authenticate' and 'system.login.screensaver' entries of authDB but nothing worked.

Meanwhile I've figured out why authdb was reset for @mattklepp writing GMIAuthPlugin.

authenticate-session-owner-or-admin overwrites the whole plist file and does not keep the mechanism part we want.


There is some error in his plist file. My own file has almost same entries but am able to write them to authDB and they remain at there.

Also I heard that Knock to Unlock app uses login agent to control the lock screen. So, perhaps the only option I have is to develop a separate login agent to handle lock screen along with my existing Authorization Plugin for logout and reboot cases. Any way to get my existing plugin displayed at lockscreen also?

__
Code Block swift
let domain = "hotmail.com"
let temp = "1_1"
let mail = "rehan\(temp)@\(domain)"


If I modify the system.login.screensaver rule to use “authenticate-session-owner-or-admin” instead of “use-login-window-ui”, then the plugin is invoked but the login screen is displayed in older UI and touchid authentication doesn’t work with this screen.

Has there been any update to this in the past 2-years?
In other words, is the new code path that supports TouchID still not compatible with authentication plugins?
There are (at least) two issues in play here:
  • Modern systems prevent third-party code, including authorisation plug-ins, from showing UI on top of the lock screen. The only way to present UI in that context is to build an authorisation plug-in based on SFAuthorizationPluginView.

  • Authorisation plug-ins are not able to use Touch ID.

Neither of these is considered a bug.

I expect these two points cover the specific cases you care about (and by “cover” I mean “torpedo”)-: but post back if not.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"