我正在尝试构建一个集中式代理,它将拦截所有请求并使用openidconnect处理身份验证。
目前代理请求只返回401,因此中间件假设要挑战并将我重定向到登录页面。问题是使用.Net Core 1.1的实现,但它似乎不适用于.Net Core 2.
我已经简化了代码但是这样做了,我被重定向到google的登录页面。
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication();
services.AddProxy();
}
public void Configure(IApplicationBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AutomaticAuthenticate = true,
});
app.UseGoogleAuthentication(new GoogleOptions
{
AutomaticChallenge = true,
SignInScheme = "oidc",
ClientId = "clientId",
ClientSecret = "clientSecret",
});
app.MapWhen(
context => context.RequestStartsWith("http://www.web1.com"),
builder => builder.RunProxy(baseUri: new Uri("http://www.proxy1.com"))
);
}
}
这不适用于.Net Core 2.0的实现,我得到一个401异常页
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme;
})
.AddCookie()
.AddGoogle(options =>
{
options.ClientId = "clientId";
options.ClientSecret = "clientSecret";
});
services.AddProxy();
}
public void Configure(IApplicationBuilder app)
{
app.UseAuthentication();
app.MapWhen(
context => context.RequestStartsWith("http://www.web1.com"),
builder => builder.RunProxy(baseUri: new Uri("http://www.proxy1.com"))
);
}
}
有什么想法吗?
答案 0 :(得分:1)
查看源代码后,发现Asp.Net Core 2中的身份验证中间件在响应返回401状态代码后没有质询,因此只返回HttpUnauthorizedResult
不再起作用。 Authorize
属性有效的原因是它返回ChallengeResult
,最终会调用ChallengeAsync
。
解决方法是,我创建了自己的中间件来处理401状态代码
public class ChallengeMiddleware
{
private readonly RequestDelegate _next;
private readonly IAuthenticationSchemeProvider _schemes;
public ChallengeMiddleware(RequestDelegate next, IAuthenticationSchemeProvider schemes)
{
_next = next;
_schemes = schemes;
}
public async Task Invoke(HttpContext context)
{
context.Response.OnStarting(async () =>
{
if (context.Response.StatusCode == 401)
{
var defaultChallenge = await _schemes.GetDefaultChallengeSchemeAsync();
if (defaultChallenge != null)
{
await context.ChallengeAsync(defaultChallenge.Name);
}
}
await Task.CompletedTask;
});
await _next(context);
}
}