Security > Authentication and user identity
UWP支持若干种用户验证方法,囊括简单的单点登录(SSO),以及安全性更高的两步验证(two factor)。
连接第三方服务,可以使用Web authentication broker。可以搭配Credential Lock来帮助记忆用户口令。
对于企业用户,可以考虑Microsoft Passport and Windows Hello,或者Smart cards或者Figerprint biometrics。
Web authentication broker
通过AuthenticateAsync API,可以方便地从第三方OpenID或者OAuth服务获得验证信息。
一个示例: https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/WebAuthenticationBroker
使用OpenID或者OAuth之前,你地App必须在第三方服务中注册并获得一个ID以及密令。这些是要作为参数添加在请求验证的uri中的。同时要提供一个redirect_uri,作为验证成功后的回调。
Windows.Security.Authentication.Web命名空间中还有一个AuthenticateAndContinue,这是给Windows Phone 8.1用的遗留API,已经废弃了。
默认情况下,AuthenticateBroker不会保留cookie,也就不支持SSO。为了使用SSO,首先目标服务必须支持(允许redirect_uri为ms-app://<appSID>
格式,然后在调用AuthenticateAsync的时候需要使用不带redirect_uri的那个版本。这种情况下redirect_uri会自动填充,通过GetCurrentApplicationCallbackUri可以获取填充的redirect_uri:
string result;
try
{
var webAuthenticationResult =
await Windows.Security.Authentication.Web.WebAuthenticationBroker.AuthenticateAsync(
Windows.Security.Authentication.Web.WebAuthenticationOptions.None,
startURI);
switch (webAuthenticationResult.ResponseStatus)
{
case Windows.Security.Authentication.Web.WebAuthenticationStatus.Success:
// Successful authentication.
result = webAuthenticationResult.ResponseData.ToString();
break;
case Windows.Security.Authentication.Web.WebAuthenticationStatus.ErrorHttp:
// HTTP error.
result = webAuthenticationResult.ResponseErrorDetail.ToString();
break;
default:
// Other error.
result = webAuthenticationResult.ResponseData.ToString();
break;
}
}
catch (Exception ex)
{
// Authentication failed. Handle parameter, SSL/TLS, and Network Unavailable errors here.
result = ex.Message;
}
调试的话可以查看事件日志或者通过Fiddler查看web请求和答复。
事件日志需要打开everntvwr.exe,然后开启Application and Services\Microsoft\Windows\WebAuth\Operational 通道。
Authenticate Broker会在User-Agent字段中添加MSAuthHost/1.0字样。
使用Fildder web调试器的话,需要开启AuthHost的PrivateNetwork权限:
REG ADD "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\authhost.exe" /v EnablePrivateNetwork /t REG_DWORD /d 1 /f
接着设置:
CheckNetIsolation.exe LoopbackExempt -a -n=microsoft.windows.authhost.a.p_8wekyb3d8bbwe
CheckNetIsolation.exe LoopbackExempt -a -n=microsoft.windows.authhost.sso.p_8wekyb3d8bbwe
CheckNetIsolation.exe LoopbackExempt -a -n=microsoft.windows.authhost.sso.c_8wekyb3d8bbwe
D:\Windows\System32>CheckNetIsolation.exe LoopbackExempt -s
List Loopback Exempted AppContainers
[1] -----------------------------------------------------------------
Name: microsoft.windows.authhost.sso.c_8wekyb3d8bbwe
SID: S-1-15-2-1973105767-3975693666-32999980-3747492175-1074076486-3102532000-500629349
[2] -----------------------------------------------------------------
Name: microsoft.windows.authhost.sso.p_8wekyb3d8bbwe
SID: S-1-15-2-166260-4150837609-3669066492-3071230600-3743290616-3683681078-2492089544
[3] -----------------------------------------------------------------
Name: microsoft.windows.authhost.a.p_8wekyb3d8bbwe
SID: S-1-15-2-3506084497-1208594716-3384433646-2514033508-1838198150-1980605558-3480344935
然后在防火墙开启一个规则,将流入的数据导入Fiddler。
实际经验
对于OneDrive,request_uri中要指定redirect_uri否则会出现:
We're unable to complete your request
invalid_request: The provided value for the input parameter 'redirect_uri' is not valid. The expected value is a URI which matches a redirect URI registered for this client application.
WebAuthenticationBroker的意义在于通过AuthHost提供一个安全的Webview,让用户可以放心输入密码。
AuthenticateAsync的第三个参数endUri是让AuthHost得以匹配服务器返回的数据,知道何时结束并关闭弹出的Webview。SSO的情况下,endUri不需要指定,因为默认为App的SID,比如:“ms-app://S-1-15-2-3506084497-1208594716-3384433646-2514033508-1838198150-1980605558-3480344935”。 这个SID需要在第三方服务商那边指定,并且能够返回给AuthHost,这样才能让AuthHost知道何时该结束进程。
参考
- Security - Access Online Services with the Windows Runtime and OAuth
- Application types for Microsoft identity platform
- Revisiting Fiddler and Win8+ Immersive applications
(未完待续)
2020-04-27更新
从Fiddler中看,最新的Authhost的应用包名字变成了
- microsoft.windows.authhost.a_8wekyb3d8bbwe
- microsoft.windows.authhost.sso_8wekyb3d8bbwe
(更新完)