Reputation: 1347
I am making an OWIN app to self host a website. I am having trouble with the authentication part. The basic flow I am looking for is:
SecuritySessionToken
and build the ClaimsIdentity
, and then return the AuthenticationTicket
.Step 1 is working fine for me. Steps 2 and 3 are where I'm having trouble.
This is what I have for my configuration method in the startup class:
public void Configuration(IAppBuilder app)
{
CookieAuthenticationOptions options = new CookieAuthenticationOptions
{
AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType,
CookieName = "MyCookieName",
CookiePath = "/cookiePath",
AuthenticationMode = AuthenticationMode.Active
};
// Not relevant how this module is made. It helps with
SessionAuthenticationModule module = this.CreateModule();
app.Use(typeof(MyCookieAuthenticationMiddleware), app, options, module);
WsFederationConfiguration fedConfig = new WsFederationConfiguration();
fedConfig.Issuer = "https://mySTS.com/NotRealUrl/";
SecurityTokenHandlerCollection handlerCollection = new SecurityTokenHandlerCollection(new List<SecurityTokenHandler>() { new SamlSecurityTokenHandler() });
WsFederationAuthenticationOptions wsFederationOptions = new WsFederationAuthenticationOptions
{
Configuration = fedConfig,
Wtrealm = "http://localhost/MyApp/NotRealUrl",
Wreply = "https://mySTS.com/NotRealUrl/Login",
SecurityTokenHandlers = handlerCollection,
AuthenticationMode = AuthenticationMode.Active,
AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType
};
app.Use(typeof(MyWsFederationAuthenticationMiddleware), app, wsFederationOptions);
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.Use<MyMiddleware>();
}
The part up to app.Use(typeof(MyCookieAuthenticationMiddleware), app, options, module);
works fine. That is, when the cookie is there, I use my custom cookie authentication middleware (MyCookieAuthenticationMiddleware
) to generate the AuthenticationTicket
.
The part that doesn't work is the WsFederation authentication middleware part. I created my own middleware for this (MyWsFederationAuthenticationMiddleware
) so that I could take a look at what's going on since doing app.UseWsFederationAuthentication(wsFederationOptions)
directly wasn't working for me. I am looking at the source code for WsFederationAuthenticationHandler.cs
to guide me, but I'm still confused about some overall concepts.
Questions
AuthenticateCoreAsync()
in MyCookieAuthenticationHandler
. But
at what point do I redirect this to the STS to get the SAML token?
Do I just wait for the pipeline to hit AuthenticateCoreAsync()
in
MyWsFederationAuthenticationHandler
, and if the user is not
authenticated, then get the token?WsFederationAuthenticationHandler.cs
, it seems like their
implementation of ApplyResponseChallengeAsync()
might be doing
what I want? More specifically, if it's a 401 status code then make
a WsFederationMessage
and redirect to the STS using that message?Thanks and sorry for the sort of long post.
Update 1
I forgot to mention, when I run my code using app.UseWsFederationAuthentication(wsFederationOptions)
(instead of my own MyWsFederationAuthenticationMiddleware
), I get back a 400 "bad request - request too long" error. The URL is very long and looks like it contains various query parameters, including wtrealm, wctx, wa, and wreply, each of which contains url encoded strings. Looks like wctx is the really long one. I imagine it's some base64 encoded object. Unfortunately I don't really know what's going on.
Upvotes: 0
Views: 3547
Reputation: 477
I think, the problem is, that both Middlewares have the AuthenticationMode
Active
You should change the CookieAuthenticationOptions.AuthenticationType
to the CookieAuthenticationDefaults.AuthenticationType
then set WsFederationAuthenticationOptions.AuthenticationMode
to passive.
I recommend an custom controller. If the user visits this controller you must trigger the Authentication on the OwinContext.Authentication
manually for the WsFederationAuthenticationDefaults.AuthenticationType
and return an 401. That should trigger the ApplyResponseChallengeAsync
in the WsFederationAuthenticationHandler
In the SecurityTokenValidated
Method on the WsFederationAuthenticationOptions.Notifications
you can issue a new AuthTicket with an identity of type CookieAuthenticationDefaults.AuthenticationType
.
Now the identity from the identity provider is converted to a an local identity with cookieauth.
Upvotes: 1