Last week I was testing the WSFederation authentication middleware that Microsoft released as part of .NET Core 2.0.
Here is how I configured it inside my ASP.NET Core app:
public class Startup | |
{ | |
public Startup(IConfiguration configuration) | |
{ | |
Configuration = configuration; | |
} | |
public IConfiguration Configuration { get; } | |
// This method gets called by the runtime. Use this method to add services to the container. | |
public void ConfigureServices(IServiceCollection services) | |
{ | |
services.AddAuthentication(sharedOptions => | |
{ | |
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; | |
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; | |
sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme; | |
}) | |
.AddWsFederation(options => | |
{ | |
options.Wtrealm = Configuration["wsfed:realm"]; | |
options.MetadataAddress = Configuration["wsfed:metadata"]; | |
}) | |
.AddCookie(); | |
services.AddMvc(options => | |
{ | |
options.Filters.Add(new RequireHttpsAttribute()); | |
}); | |
} | |
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | |
public void Configure(IApplicationBuilder app, IHostingEnvironment env) | |
{ | |
app.UseAuthentication(); | |
app.UseMvc(routes => | |
{ | |
routes.MapRoute( | |
name: "default", | |
template: "{controller=Home}/{action=Index}/{id?}"); | |
}); | |
} |
I added the Authenticate attribute to one of my controllers and when I invoked it, I was succesfully redirect to our ADFS server. However after logging in, when I was redirect back to the application I noticed that the ClaimsPrincipal remained empty.
It was only by carefully looking at the documentation I noticed my mistake:
By default, the new middleware:
· Doesn't allow unsolicited logins. This feature of the WS-Federation protocol is vulnerable to XSRF attacks. However, it can be enabled with the AllowUnsolicitedLogins option.
· Doesn't check every form post for sign-in messages. Only requests to the CallbackPath are checked for sign-ins. CallbackPath defaults to /signin-wsfed but can be changed. This path can be shared with other authentication providers by enabling the SkipUnrecognizedRequests option.
Our ADFS server was configured to redirect me to a FederationResult controller, but by default the middleware only checks request directed to /signin-wsfed.
After setting the CallbackPath correctly, everything worked:
.AddWsFederation(options =>
{
options.Wtrealm = Configuration["wsfed:realm"];
options.MetadataAddress = Configuration["wsfed:metadata"];
options.CallbackPath = "/FederationResult";