Training
Learning path
Use advance techniques in canvas apps to perform custom updates and optimization - Training
Use advance techniques in canvas apps to perform custom updates and optimization
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
A Windows Hello companion device is a device that can act in conjunction with your Windows 10 desktop to enhance the user authentication experience. Using the Windows Hello companion device framework, a companion device can provide a rich experience for Windows Hello even when biometrics are not available (for example, if the Windows 10 desktop lacks a camera for face authentication or fingerprint reader device, for example).
Note
The API for the Windows Hello companion device framework is deprecated in Windows 10, version 2004.
For code samples, see the Windows Hello companion device framework Github repository.
There are numerous ways one can use the Windows Hello companion device framework to build a great Windows unlock experience with a companion device. For example, users could:
If the companion device supports biometrics, in some cases the Windows Biometric framework may be a better solution than the Windows Hello companion device framework.
The diagram below depicts the components of the solution and who is responsible for building them.
The Windows Hello companion device framework is implemented as a service running on Windows (called the Companion Authentication Service in this article). This service is responsible for generating an unlock token which needs to be protected by an HMAC key stored on the Windows Hello companion device. This guarantees that access to the unlock token requires Windows Hello companion device presence. Per each (PC, Windows user) tuple, there will be a unique unlock token.
Integration with the Windows Hello Companion Device Framework requires:
In addition to the above requirements, the Windows Hello companion device app is responsible for:
Normally, companion devices ship with an app for initial setup, like setting up a fitness band for the first time. The functionality described in this document can be part of that app and a separate app should not be required.
Each Windows Hello companion device should be combined with an app that supports three user signals. These signals can be in form of an action or gesture.
Any number of these user signals can be combined into one. User presence and intent signals must be required on each use.
Before a Windows Hello companion device can be plugged into the Windows Hello companion device framework, it needs to be registered with the framework. The experience for registration is completely owned by the Windows Hello companion device app.
The relationship between the Windows Hello companion device and the Windows 10 desktop device can be one to many (i.e., one companion device can be used for many Windows 10 desktop devices). However, each Windows Hello companion device can only be used for one user on each Windows 10 desktop device.
Before a Windows Hello companion device can communicate with a PC, they need to agree on a transport to use. Such choice is left to the Windows Hello companion device app; the Windows Hello companion device framework does not impose any limitations on transport type (USB, NFC, WiFi, BT, BLE, etc) or protocol being used between the Windows Hello companion device and the Windows Hello companion device app on the Windows 10 desktop device side. It does, however, suggest certain security considerations for the transport layer as outlined in the "Security Requirements" section of this document. It is the device provider’s responsibility to provide those requirements. The framework does not provide them for you.
A typical user workflow is as follows:
Notes:
The following diagram illustrates how the Windows Hello companion device interacts with Companion Authentication Service during registration.
There are two keys used in our protocol:
The device key and authentication keys are exchanged at registration time between the Windows Hello companion device app and Windows Hello companion device. As a result, the Windows Hello companion device app and Windows Hello companion device must use a secure transport to protect keys.
Also, note that while the diagram above displays two HMAC keys generating on the Windows Hello companion device, it is also possible for the app to generate them and send them to the Windows Hello companion device for storage.
There are two ways for the user to start the signing in flow to Windows 10 desktop using Windows Hello companion device framework (i.e., provide intent signal):
It is the Windows Hello companion device's choice to select which one is the starting point. The Windows Hello companion device framework will inform companion device app when option one happens. For option two, the Windows Hello companion device app should query the companion device to see if that event has been captured. This ensures the Windows Hello companion device collects the intent signal before the unlock succeeds.
There is a new credential provider in Windows 10 that handles all Windows Hello companion devices.
The Windows Hello companion device credential provider is responsible for launching the companion device background task via activating a trigger. The trigger is set the first time when the PC awakens and a lock screen is displayed. The second time is when the PC is entering logon UI and the Windows Hello companion device credential provider is the selected tile.
The helper library for the Windows Hello companion device app will listen to the lock screen status change and send the event corresponding to the Windows Hello companion device background task.
If there are multiple Windows Hello companion device background tasks, the first background task that has finished the authentication process will unlock the PC. The companion device authentication service will ignore any remaining authentication calls.
The experience on the Windows Hello companion device side is owned and managed by the Windows Hello companion device app. The Windows Hello companion device framework has no control over this part of the user experience. More specifically, the companion authentication provider informs the Windows Hello companion device app (via its background app) about state changes in logon UI (for example, lock screen just came down, or the user just dispelled lock screen by hitting spacebar), and it is the responsibility of the Windows Hello companion device app to build an experience around that (for example, upon user hitting spacebar and dispelling unlock screen, start looking for the device over USB).
The Windows Hello companion device Framework will provide a stock of (localized) text and error messages for the Windows Hello companion device app to choose from. These will be displayed on top of lock screen (or in logon UI). See the Dealing with Messages and Errors section for more details.
Once the background task associated with a Windows Hello companion device app is trigger started, it is responsible for asking the Windows Hello companion device to validate an HMAC value computed by the Companion Authentication Service and help calculate two HMAC values:
The second computed value is used by the service to authenticate the device and also prevent replay attack in transport channel.
Without a backend server, users must register their Windows Hello companion device with each Windows 10 desktop device separately.
A companion device vendor or OEM can implement a web service to roam the registration state across user Windows 10 desktops or mobile devices. For more details, see the Roaming, Revocation, and Filter Service section.
Before a companion device can be used, a PIN needs to be set up on Windows 10 desktop device. This ensures the user has a backup in case their Windows Hello companion device is not working. The PIN is something that Windows manages and that apps never see. To change it, the user navigates to Settings > Accounts > Sign-in options.
Users can remove a Windows Hello companion device from a Windows 10 desktops by running the Windows Hello companion device app on that desktop device.
Enterprises have two options for controlling the Windows Hello companion device framework:
The Windows Hello companion device framework does not support any centralized way to keep inventory of available companion devices, or a method to further filter which instances of a Windows Hello companion device type is allowed (for example, only a companion device with a serial number between X and Y are allowed). Apps developers can, however, build a service to provide such functionality. For more details, see the Roaming, Revocation, and Filter Service section.
The Windows Hello companion device framework does not support removing a companion device from a specific Windows 10 desktop device remotely. Instead, users can remove the Windows Hello companion device via the Windows Hello companion device app running on that Windows 10 desktop.
Companion device vendors, however, can build a service to provide remote revocation functionality. For more details, see Roaming, Revocation, and Filter Service section.
Companion device vendors can implement a web service that can be used for the following scenarios:
Implementing these features requires the Windows Hello companion device app to check with the web service at registration and usage time. The Windows Hello companion device app can optimize for cached logon scenarios like requiring checking with web service only once a day (at the cost of extending the revocation time to up to one day).
A Windows Hello companion device app should contain two components: a foreground app with UI responsible for registering and unregistering the device, and a background task that handles authentication.
The overall API flow is as follows:
Registration requires two API calls to the Companion Authentication Service: RequestStartRegisteringDeviceAsync and FinishRegisteringDeviceAsync.
Before any of these calls are made, the Windows Hello companion device app must make sure that the Windows Hello companion device is available. If the Windows Hello companion device is responsible for generating HMAC keys (authentication and device keys), then the Windows Hello companion device app should also ask the companion device to generate them before making any of the above two calls. If the Windows Hello companion device app is responsible for generating HMAC keys, then it should do so before calling the above two calls.
Additionally, as part of first API call (RequestStartRegisteringDeviceAsync), the Windows Hello companion device app must decide on device capability and be prepared to pass it as part of the API call; for example, whether the Windows Hello companion device supports secure storage for HMAC keys. If the same Windows Hello companion device app is used to manage multiple versions of the same companion device and those capabilities change (and requires a device query to decide), we recommend this queries occurs before first API call is made.
The first API (RequestStartRegisteringDeviceAsync) will return a handle used by the second API (FinishRegisteringDeviceAsync). The first call for registration will launch the PIN prompt to make sure user is present. If no PIN is set up, this call will fail. The Windows Hello companion device app can query whether PIN is set up or not via KeyCredentialManager.IsSupportedAsync call as well. RequestStartRegisteringDeviceAsync call can also fail if policy has disabled the usage of the Windows Hello companion device.
The result of first call is returned via SecondaryAuthenticationFactorRegistrationStatus enum:
{
Failed = 0, // Something went wrong in the underlying components
Started, // First call succeeded
CanceledByUser, // User cancelled PIN prompt
PinSetupRequired, // PIN is not set up
DisabledByPolicy, // Companion device framework or this app is disabled
}
The second call (FinishRegisteringDeviceAsync) finishes the registration. As part of registration process, the Windows Hello companion device app can store companion device configuration data with Companion Authentication Service. There is a 4K size limit for this data. This data will be available to the Windows Hello companion device app at authentication time. This data can be used, as an example, to connect to the Windows Hello companion device like a MAC address, or if the Windows Hello companion device does not have storage and companion device wants to use PC for storage, then configuration data can be used. Note that any sensitive data stored as part of configuration data must be encrypted with a key that only the Windows Hello companion device knows. Also, given that configuration data is stored by a Windows service, it is available to the Windows Hello companion device app across user profiles.
The Windows Hello companion device app can call AbortRegisteringDeviceAsync to cancel the registration and pass in an error code. The Companion Authentication Service will log the error in the telemetry data. A good example for this call would be when something went wrong with the Windows Hello companion device and it could not finish registration (for example, it cannot store HMAC keys or BT connection was lost).
The Windows Hello companion device app must provide an option for the user to de-register their Windows Hello companion device from their Windows 10 desktop (for example, if they lost their companion device or bought a newer version). When the user selects that option, then the Windows Hello companion device app must call UnregisterDeviceAsync. This call by the Windows Hello companion device app will trigger the companion device authentication service to delete all data (including HMAC keys) corresponding to the specific device Id and AppId of the caller app from PC side. This API call does not attempt to delete HMAC keys from either the Windows Hello companion device app or companion device side. That is left for the Windows Hello companion device app to implement.
The Windows Hello companion device app is responsible for showing any error messages that happen in registration and de-registration phase.
using System;
using Windows.Security.Authentication.Identity.Provider;
using Windows.Storage.Streams;
using Windows.Security.Cryptography;
using Windows.UI.Popups;
namespace SecondaryAuthFactorSample
{
public class DeviceRegistration
{
public void async OnRegisterButtonClick()
{
//
// Pseudo function, the deviceId should be retrieved by the application from the device
//
string deviceId = await ReadSerialNumberFromDevice();
IBuffer deviceKey = CryptographicBuffer.GenerateRandom(256/8);
IBuffer mutualAuthenticationKey = CryptographicBuffer.GenerateRandom(256/8);
SecondaryAuthenticationFactorRegistration registrationResult =
await SecondaryAuthenticationFactorRegistration.RequestStartRegisteringDeviceAsync(
deviceId, // deviceId: max 40 wide characters. For example, serial number of the device
SecondaryAuthenticationFactorDeviceCapabilities.SecureStorage |
SecondaryAuthenticationFactorDeviceCapabilities.HMacSha256 |
SecondaryAuthenticationFactorDeviceCapabilities.StoreKeys,
"My test device 1", // deviceFriendlyName: max 64 wide characters. For example: John's card
"SAMPLE-001", // deviceModelNumber: max 32 wide characters. The app should read the model number from device.
deviceKey,
mutualAuthenticationKey);
switch(registerResult.Status)
{
case SecondaryAuthenticationFactorRegistrationStatus.Started:
//
// Pseudo function:
// The app needs to retrieve the value from device and set into opaqueBlob
//
IBuffer deviceConfigData = ReadConfigurationDataFromDevice();
if (deviceConfigData != null)
{
await registrationResult.Registration.FinishRegisteringDeviceAsync(deviceConfigData); //config data limited to 4096 bytes
MessageDialog dialog = new MessageDialog("The device is registered correctly.");
await dialog.ShowAsync();
}
else
{
await registrationResult.Registration.AbortRegisteringDeviceAsync("Failed to connect to the device");
MessageDialog dialog = new MessageDialog("Failed to connect to the device.");
await dialog.ShowAsync();
}
break;
case SecondaryAuthenticationFactorRegistrationStatus.CanceledByUser:
MessageDialog dialog = new MessageDialog("You didn't enter your PIN.");
await dialog.ShowAsync();
break;
case SecondaryAuthenticationFactorRegistrationStatus.PinSetupRequired:
MessageDialog dialog = new MessageDialog("Please setup PIN in settings.");
await dialog.ShowAsync();
break;
case SecondaryAuthenticationFactorRegistrationStatus.DisabledByPolicy:
MessageDialog dialog = new MessageDialog("Your enterprise prevents using this device to sign in.");
await dialog.ShowAsync();
break;
}
}
public void async UpdateDeviceList()
{
IReadOnlyList<SecondaryAuthenticationFactorInfo> deviceInfoList =
await SecondaryAuthenticationFactorRegistration.FindAllRegisteredDeviceInfoAsync(
SecondaryAuthenticationFactorDeviceFindScope.User);
if (deviceInfoList.Count > 0)
{
foreach (SecondaryAuthenticationFactorInfo deviceInfo in deviceInfoList)
{
//
// Add deviceInfo.FriendlyName and deviceInfo.DeviceId into a combo box
//
}
}
}
public void async OnUnregisterButtonClick()
{
string deviceId;
//
// Read the deviceId from the selected item in the combo box
//
await SecondaryAuthenticationFactorRegistration.UnregisterDeviceAsync(deviceId);
}
}
}
Authentication requires two API calls to the Companion Authentication Service: StartAuthenticationAsync and FinishAuthencationAsync.
The first initiation API will return a handle used by the second API. The first call returns, among other things, a nonce that – once concatenated with other things - needs to be HMAC'ed with the device key stored on the Windows Hello companion device. The second call returns the results of HMAC with device key and can potentially end in successful authentication (i.e., the user will see their desktop).
The first initiation API (StartAuthenticationAsync) can fail if policy has disabled that Windows Hello companion device after initial registration. It can also fail if the API call was made outside WaitingForUserConfirmation or CollectingCredential states (more on this later in this section). It can also fail if an unregistered companion device app calls it. SecondaryAuthenticationFactorAuthenticationStatus Enum summarizes the possible outcomes:
{
Failed = 0, // Something went wrong in the underlying components
Started,
UnknownDevice, // Companion device app is not registered with framework
DisabledByPolicy, // Policy disabled this device after registration
InvalidAuthenticationStage, // Companion device framework is not currently accepting
// incoming authentication requests
}
The second API call (FinishAuthencationAsync) can fail if the nonce that was provided in the first call is expired (20 seconds). SecondaryAuthenticationFactorFinishAuthenticationStatus enum captures possible outcomes.
{
Failed = 0, // Something went wrong in the underlying components
Completed, // Success
NonceExpired, // Nonce is expired
}
The timing of two API calls (StartAuthenticationAsync and FinishAuthencationAsync) needs to align with how the Windows Hello companion device collects intent, user presence, and disambiguation signals (see User Signals for more details). For example, the second call must not be submitted until intent signal is available. In other words, the PC should not unlock if the user has not expressed intent for it. To make this more clear, assume that Bluetooth proximity is used for PC unlock, then an explicit intent signal must be collected, otherwise, as soon as user walks by his PC on the way to kitchen, the PC will unlock. Also, the nonce returned from the first call is time bound (20 seconds) and will expire after certain period. As a result, the first call only should be made when the Windows Hello companion device app has good indication of companion device presence, for example, the companion device is inserted into USB port, or tapped on NFC reader. With Bluetooth, care must be taken to avoid affecting battery on PC side or affecting other Bluetooth activities going on at that point when checking for Windows Hello companion device presence. Also, if a user presence signal needs to be provided (for example, by typing in PIN), it is recommended that the first authentication call is only made after that signal is collected.
The Windows Hello companion device framework helps the Windows Hello companion device app to make informed decision on when to make above two calls by providing a complete picture of where user is in authentication flow. Windows Hello companion device framework provides this functionality by providing lock state change notification to app background task.
Details of each of these states are as follows:
State | Description |
---|---|
WaitingForUserConfirmation | This state change notification event is fired when the lock screen comes down (for example, user pressed Windows + L). We recommend not to request any error messages relating to having difficulty finding a device in this state. In general, we recommend to only show messages when intent signal is available. The Windows Hello companion device app should make the first API call for authentication in this state if the companion device collects the intent signal (for example, tapping on NFC reader, press of a button on the companion device or a specific gesture, like clapping), and the Windows Hello companion device app background task receives indication from the companion device that intent signal was detected. Otherwise, if the Windows Hello companion device app relies on the PC to start authentication flow (by having user swipe up the unlock screen or hitting space bar), then the Windows Hello companion device app needs to wait for the next state (CollectingCredential). |
CollectingCredential | This state change notification event is fired when the user either opens their laptop lid, hits any key on their keyboard, or swipes up to the unlock screen. If the Windows Hello companion device relies on the above actions to start collecting the intent signal, then the Windows Hello companion device app should start collecting it (for example, via a pop up on the companion device asking whether user wants to unlock the PC). This would be a good time to provide error cases if the Windows Hello companion device app needs the user to provide a user presence signal on the companion device (like typing in PIN on the Windows Hello companion device). |
SuspendingAuthentication | When the Windows Hello companion device app receives this state, it means that the Companion Authentication Service has stopped accepting authentication requests. |
CredentialCollected | This means that another Windows Hello companion device app has called the second API and that the Companion Authentication Service is verifying what was submitted. At this point, the Companion Authentication Service is not accepting any other authentication requests unless the currently submitted one does not pass verification. The Windows Hello companion device app should stay tuned until next state is reached. |
CredentialAuthenticated | This means that the submitted credential worked. The credentialAuthenticated has the device ID of the Windows Hello companion device that succeeded. The Windows Hello companion device app should make sure to check on that to see if its associated device was the winner. If not, then the Windows Hello companion device app should avoid showing any post authentication flows (like success message on the companion device or perhaps a vibration on that device). Note that if the submitted credential did not work, the state will change to CollectingCredential state. |
StoppingAuthentication | Authentication succeeded and user saw the desktop. Time to kill your background task. Before exiting the background task, explicitly unregister the StageEvent handler. This will help the background task exit quickly. |
Windows Hello companion device apps should only call the two authentication APIs in the first two states. Windows Hello companion device apps should check for what scenario this event is being fired. There are two possibilities: unlock or post unlock. Currently, only unlock is supported. In upcoming releases, post unlock scenarios may be supported. The SecondaryAuthenticationFactorAuthenticationScenario enum captures these two options:
{
SignIn = 0, // Running under lock screen mode
CredentialPrompt, // Running post unlock
}
Complete code sample:
using System;
using Windows.Security.Authentication.Identity.Provider;
using Windows.Storage.Streams;
using Windows.Security.Cryptography;
using System.Threading;
using Windows.ApplicationModel.Background;
namespace SecondaryAuthFactorSample
{
public sealed class AuthenticationTask : IBackgroundTask
{
private string _deviceId;
private static AutoResetEvent _exitTaskEvent = new AutoResetEvent(false);
private static IBackgroundTaskInstance _taskInstance;
private BackgroundTaskDeferral _deferral;
private void Authenticate()
{
int retryCount = 0;
while (retryCount < 3)
{
//
// Pseudo code, the svcAuthNonce should be passed to device or generated from device
//
IBuffer svcAuthNonce = CryptographicBuffer.GenerateRandom(256/8);
SecondaryAuthenticationFactorAuthenticationResult authResult = await
SecondaryAuthenticationFactorAuthentication.StartAuthenticationAsync(
_deviceId,
svcAuthNonce);
if (authResult.Status != SecondaryAuthenticationFactorAuthenticationStatus.Started)
{
SecondaryAuthenticationFactorAuthenticationMessage message;
switch (authResult.Status)
{
case SecondaryAuthenticationFactorAuthenticationStatus.DisabledByPolicy:
message = SecondaryAuthenticationFactorAuthenticationMessage.DisabledByPolicy;
break;
case SecondaryAuthenticationFactorAuthenticationStatus.InvalidAuthenticationStage:
// The task might need to wait for a SecondaryAuthenticationFactorAuthenticationStageChangedEvent
break;
default:
return;
}
// Show error message. Limited to 512 characters wide
await SecondaryAuthenticationFactorAuthentication.ShowNotificationMessageAsync(null, message);
return;
}
//
// Pseudo function:
// The device calculates and returns sessionHmac and deviceHmac
//
await GetHmacsFromDevice(
authResult.Authentication.ServiceAuthenticationHmac,
authResult.Authentication.DeviceNonce,
authResult.Authentication.SessionNonce,
out deviceHmac,
out sessionHmac);
if (sessionHmac == null ||
deviceHmac == null)
{
await authResult.Authentication.AbortAuthenticationAsync(
"Failed to read data from device");
return;
}
SecondaryAuthenticationFactorFinishAuthenticationStatus status =
await authResult.Authentication.FinishAuthencationAsync(deviceHmac, sessionHmac);
if (status == SecondaryAuthenticationFactorFinishAuthenticationStatus.NonceExpired)
{
retryCount++;
continue;
}
else if (status == SecondaryAuthenticationFactorFinishAuthenticationStatus.Completed)
{
// The credential data is collected and ready for unlock
return;
}
}
}
public void OnAuthenticationStageChanged(
object sender,
SecondaryAuthenticationFactorAuthenticationStageChangedEventArgs args)
{
// The application should check the args.StageInfo.Stage to determine what to do in next. Note that args.StageInfo.Scenario will have the scenario information (SignIn vs CredentialPrompt).
switch(args.StageInfo.Stage)
{
case SecondaryAuthenticationFactorAuthenticationStage.WaitingForUserConfirmation:
// Show welcome message
await SecondaryAuthenticationFactorAuthentication.ShowNotificationMessageAsync(
null,
SecondaryAuthenticationFactorAuthenticationMessage.WelcomeMessageSwipeUp);
break;
case SecondaryAuthenticationFactorAuthenticationStage.CollectingCredential:
// Authenticate device
Authenticate();
break;
case SecondaryAuthenticationFactorAuthenticationStage.CredentialAuthenticated:
if (args.StageInfo.DeviceId = _deviceId)
{
// Show notification on device about PC unlock
}
break;
case SecondaryAuthenticationFactorAuthenticationStage.StoppingAuthentication:
// Quit from background task
_exitTaskEvent.Set();
break;
}
Debug.WriteLine("Authentication Stage = " + args.StageInfo.AuthenticationStage.ToString());
}
//
// The Run method is the entry point of a background task.
//
public void Run(IBackgroundTaskInstance taskInstance)
{
_taskInstance = taskInstance;
_deferral = taskInstance.GetDeferral();
// Register canceled event for this task
taskInstance.Canceled += TaskInstanceCanceled;
// Find all device registered by this application
IReadOnlyList<SecondaryAuthenticationFactorInfo> deviceInfoList =
await SecondaryAuthenticationFactorRegistration.FindAllRegisteredDeviceInfoAsync(
SecondaryAuthenticationFactorDeviceFindScope.AllUsers);
if (deviceInfoList.Count == 0)
{
// Quit the task silently
return;
}
_deviceId = deviceInfoList[0].DeviceId;
Debug.WriteLine("Use first device '" + _deviceId + "' in the list to signin");
// Register AuthenticationStageChanged event
SecondaryAuthenticationFactorRegistration.AuthenticationStageChanged += OnAuthenticationStageChanged;
// Wait the task exit event
_exitTaskEvent.WaitOne();
_deferral.Complete();
}
void TaskInstanceCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
_exitTaskEvent.Set();
}
}
}
When the Windows Hello companion device app registers the first companion device, it should also register its background task component which will pass authentication information between device and companion device authentication service.
using System;
using Windows.Security.Authentication.Identity.Provider;
using Windows.Storage.Streams;
using Windows.ApplicationModel.Background;
namespace SecondaryAuthFactorSample
{
public class BackgroundTaskManager
{
// Register background task
public static async Task<IBackgroundTaskRegistration> GetOrRegisterBackgroundTaskAsync(
string bgTaskName,
string taskEntryPoint)
{
// Check if there's an existing background task already registered
var bgTask = (from t in BackgroundTaskRegistration.AllTasks
where t.Value.Name.Equals(bgTaskName)
select t.Value).SingleOrDefault();
if (bgTask == null)
{
BackgroundAccessStatus status =
BackgroundExecutionManager.RequestAccessAsync().AsTask().GetAwaiter().GetResult();
if (status == BackgroundAccessStatus.Denied)
{
Debug.WriteLine("Background Execution is denied.");
return null;
}
var taskBuilder = new BackgroundTaskBuilder();
taskBuilder.Name = bgTaskName;
taskBuilder.TaskEntryPoint = taskEntryPoint;
taskBuilder.SetTrigger(new SecondaryAuthenticationFactorAuthenticationTrigger());
bgTask = taskBuilder.Register();
// Background task is registered
}
bgTask.Completed += BgTask_Completed;
bgTask.Progress += BgTask_Progress;
return bgTask;
}
}
}
The Windows Hello companion device framework is responsible for providing feedback to the user about success or failure of signing in. The Windows Hello companion device framework will provide a stock of (localized) text and error messages for the Windows Hello companion device app to choose from. These will be displayed in the logon UI.
Windows Hello companion device apps can use ShowNotificationMessageAsync to show messages to user as part of the logon UI. Call this API when an intent signal is available. Note that an intent signal must always be collected on the Windows Hello companion device side.
There are two types of messages: guidance and errors.
Guidance messages are designed to show the user how to start the unlock process. These messages are only shown to the user once on the lock screen, upon first device registration, and never shown there again. These messages will continue to be shown under the lock screen.
Error messages are always shown and will be shown after an intent signal is provided. Given that an intent signal must be collected before showing messages to the user, and the user will provide that intent only using one of the Windows Hello companion devices, there must not be a situation where multiple Windows Hello companion devices race for showing error messages. As a result, the Windows Hello companion device framework does not maintain any queue. When a caller asks for an error message, it will be shown for 5 seconds and all other requests for showing an error message in that 5 seconds are dropped. Once 5 seconds has passed, then the opportunity arises for another caller to show an error message. We prohibit any caller from jamming the error channel.
Guidance and error messages are as follows. Device name is a parameter passed by the companion device app as part of ShowNotificationMessageAsync.
Guidance
Errors
The Windows Hello companion device app can enumerate the list of registered companion devices via FindAllRegisteredDeviceInfoAsync call. This API supports two query types defined via enum SecondaryAuthenticationFactorDeviceFindScope:
{
User = 0,
AllUsers,
}
The first scope returns the list of devices for the logged on user. The second one returns the list for all users on that PC. The first scope must be used at un-registration time to avoid un-registering another user's Windows Hello companion device. The second one must be used at authentication or registration time: at registration time, this enumeration can help the app avoid trying to register the same Windows Hello companion device twice.
Note that even if the app does not perform this check, the PC does and will reject the same Windows Hello companion device from being registered more than once. At authentication time, using the AllUsers scope helps the Windows Hello companion device app support switch user flow: log on user A when user B is logged in (this requires that both users have installed the Windows Hello companion device app and user A has registered their companion devices with the PC and the PC is sitting on lock screen (or logon screen)).
The Companion Authentication Service provides the following security protections.
The key to achieve the security protections enumerated above is to protect HMAC keys from unauthorized access and also verifying user presence. More specifically, it must satisfy these requirements:
Training
Learning path
Use advance techniques in canvas apps to perform custom updates and optimization - Training
Use advance techniques in canvas apps to perform custom updates and optimization