如何解决在 IIS 上使用 IdentityServer4 进行 Windows 身份验证
我正在尝试使用 Windows 身份验证凭据将我的本机(Winforms、控制台应用程序)客户端连接到 IIS 上托管的 Identity Server。重点是让用户通过 AD 进行身份验证,并使用这些凭据从 Identity Server(通过商业 https://commercial.abp.io/ 平台运行)获得正确的声明和角色。
编辑: 我发现这不是客户端相关的问题,因为即使直接在托管站点上我也无法使用我的外部登录名(Windows 凭据)。
这个东西在由 IISExpress 托管时在本地运行,然后我将它发布到 IIS 并在 IIS 设置中启用了匿名和 Windows 身份验证,这就是问题开始的地方。
当我运行它并单击外部登录(Windows 凭据)按钮时,我通常会重定向到 https://myserver/Error?httpStatusCode=401 并且我会提示输入我的 Windows 凭据(即使我正确插入,也只需再次重复提示)。
我有时会使用我的 Windows 凭据登录(这是目标)。使用用户名和密码登录工作正常。
我在这里看到有人提到的类似问题: https://github.com/IdentityServer/IdentityServer4/issues/4937 没有任何解决方案\答案。
我的客户端基本上是来自这个 https://github.com/damienbod/AspNetCoreWindowsAuth
的示例 NativeConsolePKCEClientstatic string _authority = "https://myserver/";
string redirectUri = "https://127.0.0.1:45656";
var options = new OidcclientOptions
{
Authority = _authority,ClientId = "native.code",ClientSecret = "secret",RedirectUri = redirectUri,Scope = "openid profile",FilterClaims = false,browser = browser,Flow = OidcclientOptions.AuthenticationFlow.AuthorizationCode,ResponseMode = OidcclientOptions.AuthorizeResponseMode.Redirect,LoadProfile = true
};
_oidcclient = new Oidcclient(options);
var result = await _oidcclient.LoginAsync();
在服务器端启动配置服务:
private void ConfigureAuthentication(ServiceConfigurationContext context,IConfiguration configuration)
{
context.Services.Configure<IISOptions>(iis => // IISOptions
{
iis.AuthenticationdisplayName = "Windows";
iis.AutomaticAuthentication = false;
});
context.Services.AddAuthentication()
.AddJwtBearer(options =>
{
options.Authority = configuration["AuthServer:Authority"];
options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]); ;
options.Audience = "ABPIdentityServer";
});
}
这是 ProcessWindowsLoginAsync 质询方法:
private async Task<IActionResult> ProcessWindowsLoginAsync(string returnUrl)
{
// see if windows auth has already been requested and succeeded
var result = await HttpContext.AuthenticateAsync(Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme);
if (result?.Principal is WindowsPrincipal wp)
{
// we will issue the external cookie and then redirect the
// user back to the external callback,in essence,tresting windows
// auth the same as any other external authentication mechanism
var props = new AuthenticationProperties()
{
RedirectUri = "./ExternalLoginCallback",Items =
{
{ "returnUrl",returnUrl },{ "scheme",Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme },}
};
var id = new ClaimsIdentity(Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme);
id.AddClaim(new Claim(JwtClaimTypes.Subject,wp.Identity.Name));
id.AddClaim(new Claim(JwtClaimTypes.Name,wp.Identity.Name));
// add the groups as claims -- be careful if the number of groups is too large
{
var wi = (WindowsIdentity)wp.Identity;
var groups = wi.Groups.Translate(typeof(NTAccount));
var roles = groups.Select(x => new Claim(JwtClaimTypes.Role,x.Value));
id.AddClaims(roles);
}
await HttpContext.SignInAsync(IdentityConstants.ExternalScheme,new ClaimsPrincipal(id),props);
return Redirect(props.RedirectUri);
}
else
{
// trigger windows auth
// since windows auth don't support the redirect uri,// this URL is re-triggered when we call challenge
return Challenge("Windows");
}
}
我怀疑在调用 Challenge 时这段代码会以某种方式返回重定向到错误页面,但我不确定,我现在知道为什么。
那我错过了什么?是否可以在 IIS 上同时运行 Windows 和匿名身份验证?
在这里我也发现了类似的问题: identity server 4 windows authentication
但所提供的答案对我没有帮助。
解决方法
我强烈怀疑这不是客户端问题,而是令牌提供者的问题(不是 ID4 库,而是您安装了 ID4 库的库)。
我相信您已经在 AccountController->Login
操作中添加了以下代码,但是确保您已在其中添加了成功检查,如果您错过了,那么您的应用程序将进入无限循环。
[HttpGet] public async Task<IActionResult> Login(string returnUrl)
{
if(loginViewModel.ExternalLoginScheme == "Windows")
{
var authenticationResult = await HttpContext.AuthenticateAsync("Windows").ConfigureAwait(false);
if (authenticationResult.Succeeded && authenticationResult?.Principal is WindowsPrincipal windowsPrinciple)
{
// Add your custom code here
var authProps = new AuthenticationProperties()
{
RedirectUri = Url.Action("Callback"),Items =
{
{ "returnUrl",returnUrl },{ "scheme","Windows"},}
};
await HttpContext.SignInAsync();
return Redirect(RedirectUri);
}
else
{
return Challenge("Windows");
}
}
}
我希望这能帮助您解决问题。 快乐编码!!
,仅供可能感兴趣的任何人使用。我找到了导致重定向错误的原因。
它与我用于生成基本应用程序的 ABP 套件有某种联系。 在 ApplicationInitialization 中有一个中间件叫做
app.UseErrorPage();
当 Windows 凭据受到质疑时,哪个将其视为错误并重定向到 https://myserver/Error?httpStatusCode=401。
我不确定这个中间件是如何工作的以及为什么有时登录会起作用,但删除这部分解决了我的问题。
我希望这对某人有所帮助,不知何故,有时..
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。