我们有一个 Asp Net Core Web API 服务器和 Angular 客户端。 Asp Net Core Web API 设置为进行 Windows 身份验证。此设置适用于 PC、Mac 和 Android 设备上的所有浏览器,并显示以下登录提示以输入 Windows 用户和密码。
但在 iPhone 上,所有浏览器都不会提示输入用户名和密码,因此 Angular 客户端无法执行任何 API 调用。
Angular 客户端:HttpInterceptor 实现,确保将凭据传递到跨源 Web api。
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if ((this.authService.getConfig() !== undefined &&
request.url.indexOf(this.authService.getConfig().logURL) === -1)) {
const apiRoot = this.authService.getApiRoot();
const authReq = request.clone({
url: `${apiRoot}/${request.url}`,
withCredentials: true
});
return next.handle(authReq);
} else {
return next.handle(request);
}
}
Web API 设置为协商 Windows 身份验证
services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
.AddNegotiate();
IIS 启用了 Windows 身份验证和匿名身份验证
如果您对调试此问题有任何建议或知道任何解决方案,请告诉我。谢谢!
通过你的描述,以及我所做的调查和本博客中的解释。看来这与iOS操作系统有关,Windows身份验证在iPhone上受到了限制。
完全可以用角度来判断浏览器的设备(如
window.navigator.userAgent.toLowerCase();
),如果发现是iPhone设备,我们就显示我们自己创建的表单页面,然后进行身份验证。
我的测试代码
前端代码没有角度,它只是用于测试登录方法。
@{
ViewData["Title"] = "Login";
}
<h2>Login</h2>
<form method="post" action="/WinLogin/Login">
<label for="username">Username:</label>
<input type="text" id="username" name="username" required>
<br>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
<br>
<input type="submit" value="Login">
</form>
登录方法
public class WinLoginController : Controller
{
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, out IntPtr phToken);
[HttpGet]
public IActionResult Login()
{
return View();
}
[HttpPost]
public IActionResult Login(string username, string password)
{
IntPtr tokenHandle = new IntPtr(0);
bool returnValue = LogonUser(username, ".", password, 2, 0, out tokenHandle);
if (!returnValue)
{
int ret = Marshal.GetLastWin32Error();
throw new Win32Exception(ret);
}
using (WindowsIdentity identity = new WindowsIdentity(tokenHandle))
{
var principal = new WindowsPrincipal(identity);
HttpContext.User = principal;
return RedirectToAction("Index", "Home");
}
}
}
测试结果