WPF:使用WPF应用程序中的默认网络凭据和凭据存储来管理自动登录(译文)
By S.F.
本文链接 https://www.kyfws.com/news/wpf-managing-automatic-login-using-default-network/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 4 分钟阅读 - 1645 个词 阅读量 0WPF:使用WPF应用程序中的默认网络凭据和凭据存储来管理自动登录(译文)
原文地址:https://www.codeproject.com/Tips/5280534/WPF-Managing-Automatic-Login-using-Default-Network
原文作者:Pusparag Subudhi
译文由本站翻译
前言
具有凭据管理器的WPF身份验证框架 使用WPF和凭据管理器的身份验证框架和凭据存储 下载源文件276.9 KB
介绍
在这里,在本文中,我创建了一个简单的WPF应用程序,该应用程序试图使用"默认网络"凭据针对WebApi服务对用户进行身份验证.如果成功,将为将来的所有webapi请求存储该文件.如果失败,则我们将显示一个登录窗口以捕获凭证,并在成功认证后将其保存以备将来使用.它还使用凭据管理器软件包将凭据存储在系统上.
背景
在当今的微服务体系结构世界中,所有业务逻辑都驻留在服务中.甚至古老的WPF桌面应用程序也都保持不变.解决方案朝着WPF桌面应用程序包含表示和数据验证逻辑的方向发展.在后端,它与需要使用身份验证和授权框架进行保护的Web API进行交互. 使用桌面应用程序时,通常的首选项是使用默认的Windows身份验证.但是在某些情况下,用户可能还希望使用其他凭据.
使用代码
该应用程序是围绕"CredentialManagement
" nuget软件包构建的,该软件包为Windows Credential Management API提供了包装.
逻辑从App.xaml.cs文件开始,在此文件中我们在构造函数中调用" CreateHttpClientHandler". CreateHttpClientHandler是HttpClientFactory类中的static方法,它使用DefaultNetworkCredentials连接到WebApi.网址可以是任何服务,也可以是专门为测试成功连接而创建的服务.使用单独的API测试连接是一种更好的方法,因为它可以减少应用程序服务器中的负载,还可以防止恶意用户.
在HttpClientFactory中特别重要的代码是:
private static async Task<bool> CreateHttpHandlerUsingWindowsDefaultCredentialsAsync()
{
try
{
var response = await StoreCredentialsIfDomainControllerIsAccessibleAsync
(CredentialCache.DefaultNetworkCredentials, false);
if(!response.IsSuccessStatusCode)
{
//server responds but windows credential cannot login
if(response.StatusCode==HttpStatusCode.Unauthorized)
{
return false;
}
}
return true;
}
catch(Exception e)
{
if (e.InnerException is WebException webException)
{
if (webException.Response is HttpWebResponse webResponse)
{
if (webResponse.StatusCode == HttpStatusCode.Unauthorized)
return false;
}
}
throw;
}
}
public static async Task<HttpResponseMessage>
StoreCredentialsIfDomainControllerIsAccessibleAsync(
NetworkCredential credentials, bool rememberCredentials)
{
var uriForTestingConnection = $"{BaseAddress}<url for testing connection>";
var httpClient = new HttpClient(new HttpClientHandler
{ Credentials = credentials });
var res = await httpClient.GetAsync(uriForTestingConnection);
if (res.IsSuccessStatusCode)
{
HttpClientFactory hc = Instance;
hc.Credentials = credentials;
if (rememberCredentials)
CredentialUtil.SetCredentials
(BaseAddress, credentials.UserName, // store domain and username
// in Credential.Username
credentials.Password, PersistanceType.Enterprise);
else
CredentialUtil.RemoveCredentials(BaseAddress);
}
return res;
}
对webApi连接的测试是在StoreCredentialsIfDomainControllerIsAccessibleAsync方法中完成的,该方法将默认网络凭据添加到HttpClientHandler中,并调用Get方法.如果响应是"成功"代码,则使用" CredentialUtil"类存储凭据. " WebApi"调用被包装在" Try Catch"块中,以处理" webApi"可能关闭并因此返回失败状态代码的情况. " CredentialUtil"是" CredentialManagerNuget"包的包装,该包存储映射到基本URL的" UserName"和" Password".它包含用于存储,检索和删除密码的方法.
public static class CredentialUtil
{
public static string GetPasswordIfRemembered(string target)
{
var cm = new Credential {Target=target };
cm.Load();
return cm.Password;
}
public static string GetUserNameIfRemembered(string target)
{
var cm = new Credential { Target=target};
cm.Load();
return cm.Username;
}
public static bool SetCredentials(string target, string username,
string password, PersistanceType persistenceType)
{
return new Credential
{
Target = target,
Username = username,
Password = password,
PersistanceType = persistenceType
}
.Save();
}
public static bool RemoveCredentials(string target)
{
return new Credential { Target=target}.Delete();
}
}
如果使用默认的网络凭据登录失败,则会加载"登录对话框".用户可以提供其凭据来访问该服务,该服务在经过验证后将加载主应用程序页面.在随附的示例中,使用MVVMLight框架完成Login视图的加载. 我已经附上了实施解决方案,该解决方案需要配置为更新有效的Api Urls/端点.
历史
- 日
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C# .NET Dev WPF Intermediate authentication 新闻 翻译