Starting with the ASP.NET 5 Web App Template using Individual User Accounts I have managed to get external authentication working with Microsoft accounts. When users click Login they are redirected to ExternalLogin
in AccountController
like this
<form asp-controller="Account" asp-action="ExternalLogin" method="post" asp-route-returnurl="@ViewData["ReturnUrl"]" class="nav navbar-right">
<button type="submit" class="btn btn-null nav navbar-nav navbar-right" name="provider" value="Microsoft" title="Log in"><span class="fa fa-sign-in"/> Log In</button>
</form>
That gets them logged in using thier Microsoft account and all seems to work nicely. But how do I intercept direct attempts to access privileged actions [Authorize]
so that the user is redirected to ExternalLogin
? Can a default action be set in Startup.cs
?
EDIT 1 Attempting to follow the advice of @Yves I have created CustomAutorizationFilter
in a Filters folder. It doesn't check for any conditions
public class CustomAutorizationFilter : IAuthorizationFilter
{
public void OnAuthorization(Microsoft.AspNet.Mvc.Filters.AuthorizationContext context)
{
//if (...) // Check you conditions here
//{
context.Result = new RedirectToActionResult("ExternalLogin", "Account", null);
//}
}
}
and have edited ConfigureServices
as below
services.AddMvc(config =>
{
config.Filters.Add(typeof(Filters.CustomAutorizationFilter));
});
When I run the app locally it no longer goes to the Home page. It returns a blank http://localhost:52711/Account/ExternalLogin
Obviously there is much I do not understand.
Edit 2: Here is the signature of ExternalLogin
// POST: /Account/ExternalLogin
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public IActionResult ExternalLogin(string provider, string returnUrl = null)
This is how ExternalLogin
comes out of the box in the ASP.Net 5 Web App Template.
You can register an IAuthorizationFilter
or an IActionFilter
implementations to accomplish this. In these filters you can check if the request is trying to access a privileged action, if the user is logged in or have enough permission to do it.
If you are using AutorizeAttribute
, I suggest you to use AutorizationFilter
.
If you go with your own custom attributes, then use ActionFilter
.
Here is an example:
MVC calls IAuthorizationFilter.OnAuthorization
method before every action execution.
public class CustomAuthorizationFilter : IAuthorizationFilter
{
public void OnAuthorization(Microsoft.AspNet.Mvc.Filters.AuthorizationContext context)
{
if (...) // Check you conditions here
{
context.Result = new RedirectToActionResult("ExternalLogin", "Account", null);
}
}
}
To register this filter, in Startup.cs edit your ConfigureServices
method:
services.AddMvc(config =>
{
config.Filters.Add(typeof(CustomAuthorizationFilter ));
});
Or if you wan to use your own attributes you can use ActionFilter
's OnActionExecuting
method to check if everything is happening as you wish...