Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirect loop with .Net MVC Authorize attribute with ADFS Claims

I have a problem configuring ADFS with my .Net MVC 5 app.

I have configured my project in VS 2015 to use claims and it works ok, but I have an issue.

I can sign in, ussing ADFS, I can check user roles etc. The problem occures when i try to use

[Authorize(Roles="somenonExistingRole")]

despite that I'm already authenticated I am redirected to ADFS page, when Authentication takes place again, and I'm redirected to my page, where loop occures. Page send me to ADFS portal , ADFS redirects my to portal, and after few tries i get an error from ADFS ( to many requests )

Do I have to implement something like Role provider by myself? or i need to configure something extra. Maybe i could just limit number of tries? Why am I redirected to ADFS when I have my roles allready?

there is not much to show actualy in the code, ut as requested: the controller that im testing:

 public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
        [Authorize]
        public ActionResult About()
        {
            var u = HttpContext.User;


            if (u.IsInRole("/"))
            {
                ViewBag.Message = "User is in role.";
            }
            else
            {
                ViewBag.Message = "User is NOT in role.";
            }

            return View();
        }
        [Authorize(Roles = "/nonexistingRole")]
        public ActionResult Contact()
        {

            ViewBag.Message = "Your contact page.";

            return View();
        }
    }

and the configure auth section

public void ConfigureAuth(IAppBuilder app)
{
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

    app.UseCookieAuthentication(new CookieAuthenticationOptions());

    app.UseWsFederationAuthentication(
        new WsFederationAuthenticationOptions
        {
            Wtrealm = realm,
            MetadataAddress = adfsMetadata, 

        });
}
like image 278
bunny1985 Avatar asked Jan 22 '16 08:01

bunny1985


1 Answers

To fix the loop problem, you should override the AuthorizeAttribute.

By Default, MVC returns a 401 Unauthorized when a user's roles do not meet the AuthorizeAttribute requirements. This initializes a reauthentication request to the identity provider. Since the user is already logged in, AAD returns to the same page, which then issues another 401, creating a redirect loop. Here, we override the AuthorizeAttribute's HandleUnauthorizedRequest method to show something that makes sense in the context of our application.

This class was generated when creating a new MVC project using VS 2015 :

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{        
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAuthenticated)
        {
            //One Strategy:
            //filterContext.Result = new System.Web.Mvc.HttpStatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);

            //Another Strategy:
            filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary(
                    new
                    {
                        controller = "Error",
                        action = "ShowError",
                        errorMessage = "You do not have sufficient priviliges to view this page."
                    })
                );
        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}
like image 82
Thomas Avatar answered Oct 28 '22 19:10

Thomas