I have an existing MVC project that uses FormsAuthentication for its authentication.
I need to incorporate the option of logging in with an OpenID IDP in addition to the regular login page already available.
The problem I'm having is challenging the IDP on demand and setting the authentication cookie once the claims are received, I can't find the reason why the cookie is not sticking. The flow seems to be working fine, and I can see the claims in the AuthorizationCodeReceived callback.
Here's the Startup.Auth.cs code:
var notificationHandlers = new OpenIdConnectAuthenticationNotifications
{
AuthorizationCodeReceived = (context) =>
{
string username = context.AuthenticationTicket.Identity.FindFirst("preferred_username").Value;
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, username, DateTime.Now, DateTime.Now.AddMinutes(60), true, "");
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
context.Response.Cookies.Append(FormsAuthentication.FormsCookieName, encryptedTicket);
return Task.FromResult(0);
},
RedirectToIdentityProvider = (context) =>
{
if (context.OwinContext.Request.Path.Value != "/Account/SignInWithOpenId")
{
context.OwinContext.Response.Redirect("/Account/Login");
context.HandleResponse();
}
return Task.FromResult(0);
}
};
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
AuthenticationType = "oidc",
SignInAsAuthenticationType = "Cookies",
Authority = "xxxxxxxxx",
ClientId = "MyClient",
ClientSecret = "xxxxxxxx",
RedirectUri = "http://localhost:52389/",
PostLogoutRedirectUri = "http://localhost:52389/",
ResponseType = "code id_token",
Scope = "openid profile email roles",
UseTokenLifetime = false,
TokenValidationParameters = new TokenValidationParameters()
{
NameClaimType = "preferred_username",
RoleClaimType = "role"
},
Notifications = notificationHandlers
});
app.SetDefaultSignInAsAuthenticationType("Cookies");
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
AuthenticationType = "Cookies",
AuthenticationMode = AuthenticationMode.Passive,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider()
});
app.UseStageMarker(PipelineStage.Authenticate);
And here's the AccountController SignInWithOpenId method:
public ActionResult SignInWithOpenId()
{
if (!Request.IsAuthenticated)
{
HttpContext.GetOwinContext().Authentication.Challenge(OpenIdConnectAuthenticationDefaults.AuthenticationType);
// If I don't have this line, reponse redirects to the forms authentication login... so maybe something is wrong here?
return new HttpUnauthorizedResult("IDP");
}
else
{
return RedirectToAction("Index", "Default");
}
}
Any pointers would be greatly appreciated. Thank you.