I am attempting to write an ASP.NET application that uses a hybrid authentication scheme. A user can either have his username and password hash stored in the UserStore, or he can authenticate via Azure Active Directory.
I have created the login form pictured. It has the standard UserName
and Password
inputs, but also has a "Login via Active Directory" button.
This works well.
Now for the problem: The application's home page has the [Authorize]
attribute.
public class DefaultController : Controller
{
[Authorize]
public ViewResult Index()
{
// Implementation
}
}
If the user is not logged in, I want it to redirect to the page Account/Login
, allowing the user to choose the authentication method.
Once I added IAppBuilder.UseOpenIdConnectAuthentication
to the pipeline setup, it no longer redirects to that page. Instead, it goes straight to the Microsoft Login page.
How do I configure it so that OpenID authentication is part of the system, but allow me to specify how to perform redirections when the user is not authenticated?
Here's the code where I set up the pipeline:
appBuilder.SetDefaultSignInAsAuthticationType(CookieAuthenticationDefaults.AuthenticationType_;
var cookieAuthenticationOptions = new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationType.ApplicationCookie,
LoginPath = new Microsoft.Owin.PathString("/Account/Login"),
Provider = new Security.CookieAuthenticationProvider()
};
appBuilder.UseCookieAuthentication(cookieAuthenticationOptions);
// Now the OpenId authentication
var notificationHandlers = new OpenIdConnectAuthenticationNotificationHandlers
{
AuthorizationCodeReceived = async(context) => {
var jwtSecurityToken = context.JwtSecurityToken;
// I've written a static method to convert the claims
// to a user
var user = await GetOrCreateUser(context.OwinContext, jwtSecurityToken.Claims);
var signInManager = context.OwinContext.Get<SignInManager>();
await signInManager.SignInAsync(user, true, false);
}
}
var openIdOptions = new OpenIdConnectAuthenticationOptions
{
ClientId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx",
Authority = "https://login.microsoftonline.com/xxxxx.onmicrosoft.com",
PostLogoutRedirectUri = "https://localhost:52538/Account/Login",
Notifications = notifcationHandlers
}
appBuilder.UseOpenIdConnectAuthentication(openIdOptions);
When you click "Active Directory Signin", it posts to "Account/SignInWithOpenId"
public ActionResult SignInWithOpenId()
{
// Send an OpenID Connect sign-in request.
if (!Request.IsAuthenticated)
{
var authenticationProperties = new AuthenticationProperties
{
RedirectUri = "/"
};
HttpContext.GetOwinContext().Authentication.Challenge
(
authenticationProperties,
OpenIdConnectAuthenticationDefaults.AuthenticationType
);
return new EmptyResult();
}
else
{
return RedirectToAction("Index", "Default");
}
}