【发布时间】:2018-10-26 16:40:31
【问题描述】:
我需要将使用 Windows 身份验证的单点登录添加到我的 Intranet Angular Web 应用程序(托管在 IIS 上),该应用程序使用 JWT Bearer 令牌进行身份验证。控制器使用[Authorize] 属性进行保护,并且 JWT Bearer 令牌身份验证正在工作。所有的控制器都暴露在api/ 路由下。
这个想法是在sso/ 路由下发布一个新的SsoController,它应该使用Windows 身份验证进行保护,并公开一个WindowsLogin 操作,该操作为应用程序返回一个有效的不记名令牌。
当我使用 ASP.net Web Forms 时,它非常简单,您只需在 web.config/system.webServer 部分启用 Windows 身份验证,在 system.web 部分禁用它在应用程序范围内,然后在下面再次启用它<location path="sso"> 标签。这样,ASP.net 仅为 sso 路由下的请求生成 NTLM/Negotiate 质询。
我几乎可以正常工作 - SsoController 获取 Windows 用户名并创建 JWT 令牌就好了,但管道仍在为 all HTTP 401 生成 WWW-Authenticate: NTLM 和 WWW-Authenticate: Negotiate 标头响应,而不仅仅是sso 路由下的响应。
我如何告诉管道我只希望对所有 api/ 请求进行匿名或不记名身份验证?
提前感谢您的帮助。
程序.cs
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseIISIntegration();
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// Set up data directory
services.AddDbContext<AuthContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("AuthContext")));
services.AddAuthentication(IISDefaults.AuthenticationScheme);
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "AngularWebApp.Web",
ValidAudience = "AngularWebApp.Web.Client",
IssuerSigningKey = _signingKey,
ClockSkew = TimeSpan.Zero //the default for this setting is 5 minutes
};
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
{
context.Response.Headers.Add("Token-Expired", "true");
}
return Task.CompletedTask;
}
};
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseAuthentication();
app.UseWhen(context => context.Request.Path.StartsWithSegments("/sso"),
builder => builder.UseMiddleware<WindowsAuthMiddleware>());
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
}
WindowsAuthMiddleware.cs
public class WindowsAuthMiddleware
{
private readonly RequestDelegate next;
public WindowsAuthMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext context)
{
if (!context.User.Identity.IsAuthenticated)
{
await context.ChallengeAsync(IISDefaults.AuthenticationScheme);
return;
}
await next(context);
}
}
web.config
<system.webServer>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="true"/>
<security>
<authentication>
<anonymousAuthentication enabled="true" />
<windowsAuthentication enabled="true" />
</authentication>
</security>
</system.webServer>
【问题讨论】:
-
也许这也给了你一些提示,你可以如何做到这一点docs.microsoft.com/en-us/aspnet/core/security/authorization/…
标签: iis asp.net-core windows-authentication asp.net-core-2.1