I am kind of successful by doing this in the Startup.Auth.cs file
// Configure the db context and user manager to use a single instance per request
Try this
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = ClientId,
Authority = Authority,
Notifications = new OpenIdConnectAuthenticationNotifications()
{
RedirectToIdentityProvider = (context) =>
{
if (context.Request.Path.Value == "/Account/ExternalLogin" || (context.Request.Path.Value == "/Account/LogOff" && context.Request.User.Identity.IsExternalUser()))
{
// This ensures that the address used for sign in and sign out is picked up dynamically from the request
// this allows you to deploy your app (to Azure Web Sites, for example)without having to change settings
// Remember that the base URL of the address used here must be provisioned in Azure AD beforehand.
string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
context.ProtocolMessage.RedirectUri = appBaseUrl + "/";
context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
}
else
{
//This is to avoid being redirected to the microsoft login page when deep linking and not logged in
context.State = Microsoft.Owin.Security.Notifications.NotificationResultState.Skipped;
context.HandleResponse();
}
return Task.FromResult(0);
},
}
});
EDIT:
Forgot this extension method
public static class IdentityExtensions
{
public static bool IsExternalUser(this IIdentity identity)
{
ClaimsIdentity ci = identity as ClaimsIdentity;
if (ci != null && ci.IsAuthenticated == true)
{
var value = ci.FindFirstValue(ClaimTypes.Sid);
if (value != null && value == "Office365")
{
return true;
}
}
return false;
}
}
EDIT 2:
You have to have some custom logic in the ExternalLoginCallback (AccountController) e.g. add the Sid claim. In this case there is also logic to check if the user allows external login.
// GET: /Account/ExternalLoginCallback
[AllowAnonymous]
public async Task<ActionResult> ExternalLoginCallback(string returnUrl, string urlHash)
{
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
return RedirectToAction("Login");
}
var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Sid, "Office365"));
// Sign in the user with this external login provider if the user already has a login
var user = await UserManager.FindAsync(loginInfo.Login);
if (user == null)
{
user = await UserManager.FindByNameAsync(loginInfo.DefaultUserName);
if (user != null)
{
if(user.AllowExternalLogin == false)
{
ModelState.AddModelError("", String.Format("User {0} not allowed to authenticate with Office 365.", loginInfo.DefaultUserName));
return View("Login");
}
var result = await UserManager.AddLoginAsync(user.Id, loginInfo.Login);
if (result.Succeeded)
{
if (claims != null)
{
var userIdentity = await user.GenerateUserIdentityAsync(UserManager);
userIdentity.AddClaims(claims);
}
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
return RedirectToLocal(returnUrl);
}
else
{
ModelState.AddModelError("", String.Format("User {0} not found.", loginInfo.DefaultUserName));
return View("Login");
}
}
else
{
if (user.AllowExternalLogin == false)
{
ModelState.AddModelError("", String.Format("User {0} not allowed to authenticate with Office 365.", loginInfo.DefaultUserName));
return View("Login");
}
if (claims != null)
{
var userIdentity = await user.GenerateUserIdentityAsync(UserManager);
userIdentity.AddClaims(claims);
}
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
return RedirectToLocal(returnUrl);
}
}