3

我有一個身份服務器(Identity Server 4 2.0.0的ASP.NET Core 2)配置爲使用Kestrel和IISIntegration,並在launchSettings.json上啓用了匿名和Windows身份驗證。我還配置IISOptions這樣的:Windows身份驗證不接受憑據

services.Configure<IISOptions>(iis => 
{ 
    iis.AutomaticAuthentication = false; 
    iis.AuthenticationDisplayName = "Windows"; 
}); 

services.AddAuthentication(); 
services.AddCors() 
     .AddMvc(); 
services.AddIdentityServer(); // with AspNetIdentity configured 

app.UseAuthentication() 
    .UseIdentityServer() 
    .UseStaticFiles() 
    .UseCors(options => options.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin()) 
    .UseMvcWithDefaultRoute(); 

而且我有這個客戶端(也ASP.NET酷睿2與Windows和匿名身份驗證同時啓用,與IISIntegration上運行的紅隼)

services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) 
    .AddOpenIdConnect(config => 
    { 
     config.Authority = "http://localhost:5000"; 
     config.RequireHttpsMetadata = false; 
     config.ClientId = "MyClientId"; 
     config.ClientSecret = "MyClientSecret"; 
     config.SaveTokens = true; 
     config.GetClaimsFromUserInfoEndpoint = true; 
    }); 

services.AddMvc(); 

身份服務器在http://localhost:5000上運行,客戶端在http://localhost:2040上運行。

當我啓動客戶端時,它正確地顯示了Identity Server的登錄屏幕,但是在單擊Windows身份驗證時,只會一直詢問憑據。我已經查看了兩個應用程序的輸出窗口,兩邊都沒有異常提升。我已經嘗試將Identity Server部署到IIS服務器(啓用了Windows身份驗證並在「網絡服務」下運行其池),並重現了相同的行爲。

+0

;'排除故障? – Kostya

+0

@KostyaK如果你引用'services.AddIdentityServer().AddDeveloperSigningCredential()',是的,那已經存在 –

+0

@CodeCaster嘗試從這裏運行官方示例https://github.com/IdentityServer/IdentityServer4.Samples/tree/發佈/ Quickstarts/6_AspNetIdentity/src以查看它是否適用於您的環境。這樣你可以縮小搜索問題的範圍。 – Kostya

回答

3

我終於明白了。我遵循不支持Windows身份驗證的Combined_AspNetIdentity_and_EntityFrameworkStorage快速入門。通過4_ImplicitFlowAuthenticationWithExternal快速入門的相關代碼進行復制修復了問題。

爲了簡單起見,這裏是快速入門的代碼,允許Windows身份驗證,修改爲使用Identity爲用戶存儲:你有沒有嘗試設置`services.AddDeveloperSigningCredential()@CodeCaster

[HttpPost] 
[AllowAnonymous] 
[ValidateAntiForgeryToken] 
public async Task<IActionResult> ExternalLogin(string provider, string returnUrl = null) 
{ 
    var props = new AuthenticationProperties() 
    { 
     RedirectUri = Url.Action("ExternalLoginCallback"), 
     Items = 
     { 
      { "returnUrl", returnUrl }, 
      { "scheme", AccountOptions.WindowsAuthenticationSchemeName } 
     } 
    }; 

    // I only care about Windows as an external provider 
    var result = await HttpContext.AuthenticateAsync(AccountOptions.WindowsAuthenticationSchemeName); 
    if (result?.Principal is WindowsPrincipal wp) 
    { 
     var id = new ClaimsIdentity(provider); 
     id.AddClaim(new Claim(JwtClaimTypes.Subject, wp.Identity.Name)); 
     id.AddClaim(new Claim(JwtClaimTypes.Name, wp.Identity.Name)); 

     await HttpContext.SignInAsync(
      IdentityServerConstants.ExternalCookieAuthenticationScheme, 
      new ClaimsPrincipal(id), 
      props); 
     return Redirect(props.RedirectUri); 
    } 
    else 
    { 
     return Challenge(AccountOptions.WindowsAuthenticationSchemeName); 
    } 
} 

[HttpGet] 
[AllowAnonymous] 
public async Task<IActionResult> ExternalLoginCallback() 
{ 
    var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme); 
    if (result?.Succeeded != true) 
    { 
     throw new Exception("External authentication error"); 
    } 

    var externalUser = result.Principal; 
    var claims = externalUser.Claims.ToList(); 

    var userIdClaim = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject); 
    if (userIdClaim == null) 
    { 
     userIdClaim = claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier); 
    } 

    if (userIdClaim == null) 
    { 
     throw new Exception("Unknown userid"); 
    } 

    claims.Remove(userIdClaim); 
    string provider = result.Properties.Items["scheme"]; 
    string userId = userIdClaim.Value; 

    var additionalClaims = new List<Claim>(); 

    // I changed this to use Identity as a user store 
    var user = await userManager.FindByNameAsync(userId); 
    if (user == null) 
    { 
     user = new ApplicationUser 
     { 
      UserName = userId 
     }; 

     var creationResult = await userManager.CreateAsync(user); 

     if (!creationResult.Succeeded) 
     { 
      throw new Exception($"Could not create new user: {creationResult.Errors.FirstOrDefault()?.Description}"); 
     } 
    } 
    else 
    { 
     additionalClaims.AddRange(await userManager.GetClaimsAsync(user)); 
    } 

    var sid = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId); 
    if (sid != null) 
    { 
     additionalClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value)); 
    } 

    AuthenticationProperties props = null; 
    string id_token = result.Properties.GetTokenValue("id_token"); 
    if (id_token != null) 
    { 
     props = new AuthenticationProperties(); 
     props.StoreTokens(new[] { new AuthenticationToken { Name = "id_token", Value = id_token } }); 
    } 

    await HttpContext.SignInAsync(user.Id, user.UserName, provider, props, additionalClaims.ToArray()); 

    await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme); 

    string returnUrl = result.Properties.Items["returnUrl"]; 
    if (_interaction.IsValidReturnUrl(returnUrl) || Url.IsLocalUrl(returnUrl)) 
    { 
     return Redirect(returnUrl); 
    } 

    return Redirect("~/"); 
} 
相關問題