After searching through lots of examples online I'm struggling with what seems to be a fairly simple requirement.
I'm trying to extend an existing ASP.NET Application that uses Form Authentication today so that it can use OpenID Connect for authentication as well as some role information coming from the Identity Provider. In particular I'm integrating with an existing hosted Identity Provider that I do not have control over.
I'm using ASP.NET MVC with the Owin components for OpenIdConnect. Namely,
Microsoft.Owin.Security
Microsoft.Owin.Security.Cookies
Microsoft.Owin.Security.OpenIdConnect
I am successfully able to:
So far so good! HOWEVER.
What I'm failing to grasp and what most Owin examples I've seen don't seem to explain: what, if any, extra configuration is required to get ASP.NET to actually create an authenticated session in my application based on the redirect from the Identity Provider back to my application.
The general feeling I get from the documentation is that I should NOT have to do extra configuration within the Owin libraries -- that once I've configured the system to use cookie authentication and the OpenId Connect libraries -- that it should just work. However, this doesn't seem to be as easy as it looks. I'm guessing I'm missing something.
Some specific considerations/observations:
Per suggestions I've found, I've set the authentication node this way in the web.config, but it doesn't seem to make a difference if I exclude this node.
<system.web>
<authentication mode="None" />
</system.web>
To summarize:
Lastly, if I'm NOT supposed to be setting up the Authenticated session manually after redirect from the Identity Provider (if it's supposed to work automatically), any suggestions for common mistakes on this configuration?
For completeness:
My Owin pipeline Startup Configuration method:
public void Configuration(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
//no problems on these as far as I can tell
ClientId = "client_id_string",
ClientSecret = "client_secret_string",
Authority = "url_to_identity_provider",
Scope = "email name etc",
//I'm properly redirected to this URL but not sure
//if I should need to create the session manually
RedirectUri = "http://mymachine/mymvcapp/authorize",
//this causes the redirection to come with the access_token,
//which is valid
ResponseType = "token",
SignInAsAuthenticationType = "Cookies",
Notifications = new OpenIdConnectAuthenticationNotifications()
{
RedirectToIdentityProvider = (context) =>
{
//I'm able to break into this method
return Task.FromResult(0);
},
MessageReceived = (context) =>
{
//doesn't seem to run this line
return Task.FromResult(0);
},
SecurityTokenReceived = (context) =>
{
//doesn't seem to run this line
return Task.FromResult(0);
},
SecurityTokenValidated = (context) =>
{
//doesn't seem to run this line
return Task.FromResult(0);
},
AuthorizationCodeReceived = (context) =>
{
//doesn't seem to run this line
return Task.FromResult(0);
},
AuthenticationFailed = (context) =>
{
//doesn't seem to run this line
return Task.FromResult(0);
},
},
});
}
My secured method that properly initiates the login flow:
[Authorize]
public class HomeController : Controller
{
//I'm sent to the login flow the first time this is hit
public ActionResult Index()
{
return View();
}
}
My method at the RedirectUri that does get called but does indicate that the ASP.NET authenticated session was created:
public class AuthorizeController : Controller
{
// [Authorize] -- currently this Authorize attribute is turned off
//so the method is anonymous.
//If I turn that back on, I get infininte redirect loops to
//the Identity Provider
public ActionResult Index()
{
//the incoming request to this controller method from the
//identity provider DOES include valid access_token and id_token
//(which can be used against the user info endpoint) but does not
//create a valid ASP.NET session for my web app
//Request.IsAuthenticated is always false
//should there be a manual creation of the ASP.NET
//session/cookie information in this controller method?
//note: to me it would make most sense if this attribute was not
//anonymous since it's unlikely that the Request would ever appear
//as IsAuthenticated == true, but if you read the entire question
//it will be clear why I'm trying this method with anonymous access
return View();
}
}
As you found out, you can't put an [Authorize] attribute on the method the external server uses to notify you the user was authorized - the session isn't authorized yet, you're just being notified that it should be.
Fortunately, creating that session is not difficult: How can I manually create a authentication cookie instead of the default method?
(I'm pretty sure you have to do this yourself with the basic Microsoft Owin stuff - and you always can do it yourself if you want.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With