使用 WsFederation 的授权属性从不执行带注释的控制器操作
Authorize attribute using WsFederation never executes annotated controller action
我正在使用 WsFederation 中间件访问 ADFS 服务器进行身份验证。 ADFS 被赋予一个特定的端点以在中间件和 ADFS 之间的对话结束时回调。如果我没有在我的代码中提供一个实际的端点(一些响应 route = callback 端点的动作),我会得到一个 404。如果我在那个端点实现了一个动作,我没有得到任何有用的东西(例如 'User' 未设置)和 - 无论我在响应结束时做什么,都会直接返回到用户的浏览器。我用 [Authorize] 装饰的动作在任何时候都没有执行。
From startup:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
// set up ADFS authentication
services.AddAuthentication(sharedOptions => {
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
}).AddWsFederation(options =>
{
options.MetadataAddress = "<adfs-server>/FederationMetadata/2007-06/FederationMetadata.xml";
options.Wtrealm = "<my-apps-server>/authviaadfs/auth-callback";
}).AddCookie("Cookies", o => { });
// set up custom authorization
services.AddAuthorization(options => { });
services.AddControllersWithViews();
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
//app.UseHsts();
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
From MyController:
[Authorize]
public IActionResult MyProtectedPage()
{
... code that never, ever, executes when decorated with [Authorize]
}
[Route("/authviaadfs/auth-callback")]
public IActionResult AuthCallback()
{
... code that executes after I log in via ADFS
... response that returns to the original caller of "MyProtectedPage"
}
谁能告诉我我做错了什么?我遵循了六个不同的 Google 搜索网站的方法,这些网站说“这就是您向 ADFS 进行身份验证的方式”(所有内容略有不同,但要点是相同的,包括仅设置 'MetadataAddress' 和 [= 的选项19=]).
好吧,我明白了 - “在现实世界中无用的 Google 示例”和“bad/missing 如何做某事的文档”的另一个示例。
如果您想使用“/”以外的端点,除了“MetadataAddress”和“Wtrealm”之外,还有另一个“选项”需要设置 - 一个名为“CallbackPath”的选项。这告诉中间件你的代码中的什么路由“吞并处理”;如果你不设置它(因为我最初没有,按照食谱)那么你的中间件不知道要拦截哪个请求。因此,就我在问题中提供的示例代码而言,在设置 options.MetadataAddress 和 options.Wtrealm 之后,您将设置以下内容:
options.CallbackPath = "/authviaadfs/auth-callback";
这告诉中间件在请求管道内拦截对“/authviaadfs/auth-callback”的任何调用,并使用请求和 headers 完成身份验证,然后有效地将控制权交给您受保护的控制器操作。中间件创建一个关联 cookie,它随第一次重定向一起发送到您的 ADFS 服务器,然后在“/authviaadfs/auth-callback”中使用该 cookie 将来自 ADFS 的 return 调用与正确的请求上下文相匹配正在认证中。
我正在使用 WsFederation 中间件访问 ADFS 服务器进行身份验证。 ADFS 被赋予一个特定的端点以在中间件和 ADFS 之间的对话结束时回调。如果我没有在我的代码中提供一个实际的端点(一些响应 route = callback 端点的动作),我会得到一个 404。如果我在那个端点实现了一个动作,我没有得到任何有用的东西(例如 'User' 未设置)和 - 无论我在响应结束时做什么,都会直接返回到用户的浏览器。我用 [Authorize] 装饰的动作在任何时候都没有执行。
From startup:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
// set up ADFS authentication
services.AddAuthentication(sharedOptions => {
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
}).AddWsFederation(options =>
{
options.MetadataAddress = "<adfs-server>/FederationMetadata/2007-06/FederationMetadata.xml";
options.Wtrealm = "<my-apps-server>/authviaadfs/auth-callback";
}).AddCookie("Cookies", o => { });
// set up custom authorization
services.AddAuthorization(options => { });
services.AddControllersWithViews();
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
//app.UseHsts();
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
From MyController:
[Authorize]
public IActionResult MyProtectedPage()
{
... code that never, ever, executes when decorated with [Authorize]
}
[Route("/authviaadfs/auth-callback")]
public IActionResult AuthCallback()
{
... code that executes after I log in via ADFS
... response that returns to the original caller of "MyProtectedPage"
}
谁能告诉我我做错了什么?我遵循了六个不同的 Google 搜索网站的方法,这些网站说“这就是您向 ADFS 进行身份验证的方式”(所有内容略有不同,但要点是相同的,包括仅设置 'MetadataAddress' 和 [= 的选项19=]).
好吧,我明白了 - “在现实世界中无用的 Google 示例”和“bad/missing 如何做某事的文档”的另一个示例。
如果您想使用“/”以外的端点,除了“MetadataAddress”和“Wtrealm”之外,还有另一个“选项”需要设置 - 一个名为“CallbackPath”的选项。这告诉中间件你的代码中的什么路由“吞并处理”;如果你不设置它(因为我最初没有,按照食谱)那么你的中间件不知道要拦截哪个请求。因此,就我在问题中提供的示例代码而言,在设置 options.MetadataAddress 和 options.Wtrealm 之后,您将设置以下内容:
options.CallbackPath = "/authviaadfs/auth-callback";
这告诉中间件在请求管道内拦截对“/authviaadfs/auth-callback”的任何调用,并使用请求和 headers 完成身份验证,然后有效地将控制权交给您受保护的控制器操作。中间件创建一个关联 cookie,它随第一次重定向一起发送到您的 ADFS 服务器,然后在“/authviaadfs/auth-callback”中使用该 cookie 将来自 ADFS 的 return 调用与正确的请求上下文相匹配正在认证中。