Mvc, Authorize bounces authorized users

2019-06-26 22:26发布

I'm trying to make a section of a MVC 5 webpage restricted to users of a certain Active directory group, however the [Authorize] attribute (on controller) blocks logged in users aswell.

My Login page code behind looks as follows:

public class AccountController: Controller
{

    [AllowAnonymous]
    public ActionResult Login(string returnUrl)
    {
        ViewBag.ReturnUrl = returnUrl;
        return View();
    }

    // POST: /Account/Login
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Login(LoginModel model, string returnUrl)
    {
        if (ModelState.IsValid)
        {
            ActiveDirectoryHelper ad = new ActiveDirectoryHelper();

            if (Membership.ValidateUser(model.UserName, model.Password))
            {
                if (ad.CheckGroupMembership(model.UserName))
                {
                    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);

                    if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                        && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
                        return RedirectToAction("Index", "Home");
                    }
                }
                else
                {
                    ModelState.AddModelError("", "Credentials are correct but you are no authorised \n You Need membership in group: HKF-HIT-FortigateAPI-GS");
                }
            }
            else
            {
                ModelState.AddModelError("", "The user name or password provided is incorrect");
            }
        }
        // if we got this far, something failed, redisplay form
        return View(model);
    }
    // POST: /Account/LogOff
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult LogOff()
    {
        FormsAuthentication.SignOut();
        return RedirectToAction("Index", "Home");
    }
}
public class ActiveDirectoryHelper
{
    string group = "HKF-HIT-FortigateAPI-GS";
     public bool CheckGroupMembership(string name)
    {
        var context = new PrincipalContext(
                            ContextType.Domain,
                            "AD-Domain", @"Username", "Password");

        var userPrincipal = UserPrincipal.FindByIdentity(
                            context,
                            IdentityType.SamAccountName,
                            name);

        var test = userPrincipal;

        if (userPrincipal.IsMemberOf(context,
             IdentityType.Name,
             group))
        {
            return true;
        }
        return false;
    }
}

The user passes and is redirected to Index in Home controller.

This controller however has the [Authorized] value set as follows:

[Authorize]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}

And here the user in bounced back to the loginpage, as if he was not Authorized.

Also this is web.config:

In the browser i can see the ADAuthCookie.

Edit: Ading pictures of Request data:

Account Post:

enter image description here

Fiddler:

enter image description here

Index Get:

enter image description here

Fiddler:

enter image description here

EDIT: Question has been solved, after going trough the amazing guide linked by in the comments i realised i was never handling my cooke in the Global.asaz.cs Class.

Adding an overide to Application_PostAuthenticateRequest solved my problem.

The code i added ended up using:

protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
    HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];

    if (authCookie != null)
    {
        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

        JavaScriptSerializer serializer = new JavaScriptSerializer();

        CustomPrincipalSerializeModel serializeModel = serializer.Deserialize<CustomPrincipalSerializeModel>(authTicket.UserData);

        CustomPrincipal newUser = new CustomPrincipal(authTicket.Name);
        newUser.Name = serializeModel.Name;
        HttpContext.Current.User = newUser;
    }
}

In global.asax and i also added:

CustomPrincipalSerializeModel serializeModel = new CustomPrincipalSerializeModel();
serializeModel.Name = model.UserName;

JavaScriptSerializer serializer = new JavaScriptSerializer();

string userData = serializer.Serialize(serializeModel);

FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
         1,
         model.UserName,
         DateTime.Now,
         DateTime.Now.AddMinutes(15),
         false,
         userData);

string encTicket = FormsAuthentication.Encrypt(authTicket);
HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
Response.Cookies.Add(faCookie);

To my login page.

1条回答
劳资没心,怎么记你
2楼-- · 2019-06-26 23:19

AuthorizeAttribute checks the HttpContext.User value (an IPrincipal implementation) and the HttpContext.User.Identity value (an IIdentity implementation).

All of the security frameworks (Identity, Membership, etc.) from Microsoft use these interfaces to communicate with MVC/ASP.NET. If you are using a custom security framework, you also need to implement these interfaces and set them in the AcquireRequestState (if using session state) or PostAuthorizeRequest event.

See ASP.NET MVC - Set custom IIdentity or IPrincipal for an example of the latter along with custom IPrincipal and IIdentity implementations.

查看更多
登录 后发表回答