Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I manually check the url authorization in MVC5?

IIS-Manager

To restrict the access to an web app, an Administrator is able to set the url authorization of users and groups via the IIS-Manager:

IIS Autohrization Rules

Web.config

The IIS-Manager stores the Authorization Rules in the web.config of the app:

<security>
  <authorization bypassLoginPages="true"> 
    <remove users="*" roles="" verbs="" />
    <add accessType="Allow" users="Testuser" />
    <add accessType="Deny" users="*" /> 
  </authorization>
</security>

When bypassLoginPages is set to true, all users are authorized to access the login page. When an user is not logged in, he will automatically be redirected to the login page:

<authentication mode="Forms">
  <forms [...] loginUrl="~/Auth/Login" [...] >
    [...]
  </forms>
</authentication>

MVC5 App:

The user has to login in via an custom login page by his Windows SamAccountName and password. The credentials will be sent to the Login action of the AuthController:

[AllowAnonymous]
public class AuthController : Controller
{
    public ActionResult Login
    {
        // validation of SamAccountName and Password against Active Directory here.

        [...]

        // We want to check the authorization here.

        // create authentication ticket
        FormsAuthenticationTicket lFormsAuthenticationTicket = new FormsAuthenticationTicket(1,
            SamAccountName,
            DateTime.Now,
            DateTime.Now.AddMinutes(AuthCookieTimeout),
            RememberMe,
            CustomData,
            FormsAuthentication.FormsCookiePath);

        // Encrypt the ticket.
        string lEncryptedTicket = FormsAuthentication.Encrypt(lFormsAuthenticationTicket);

        var lAuthCookie = new HttpCookie(FormsAuthentication.FormsCookieName, lEncryptedTicket);

        // Create the cookie.
        Response.Cookies.Add(lAuthCookie);

        [...]

        return RedirectToAction("Index", "Main"); // redirect to the main controller
    }
}

All restricted controllers are making the authorization check via the [Authorize] attribute automatically:

[Authorize]
public class MainController : Controller
{
    [...]
}

An decoration like [Authorize(Users="User1,User2")] is no solution because the code is not accessible by the Endusers which should have the possibility to configurate the access to the app.

When a user is not authorized, then he will be redirected to the login page. That works fine. But I need to make the authorization check in the Login action before. So my question:

How can I manually validate in my AuthController if the logged in user is authorized to redirect to the MainController?

like image 571
Simon Avatar asked Nov 18 '16 08:11

Simon


3 Answers

Two options,

Either use the "Roles" option under Authorize like so:

 [Authorize(Roles="TestUsers,Admins")]

And then add the users that should be allowed access to this action to those roles. Roles are provided as part of the ClaimsPrincipal used by ASP Identity.

Or alternatively, provide your own implementation of the Authorize attribute that tests the currently logged in user for whatever business rules you have and then either allow or disallow access.

like image 176
Calin Leafshade Avatar answered Sep 26 '22 12:09

Calin Leafshade


Q: How can I manually validate in my AuthController if the logged in user is authorized to redirect to the MainController?

Since you are using Authorize attribute, you don't need to check authorization manually in the action. These are some rules:

  • Limit access to Authenticated users: [Authorize]
  • Limit access to some specific users: [Authorize(Users="User1,User2")]
  • Limit access to some specific roles: [Authorize(Roles="Administrators,PowerUsers")]

Since you decorated the MainController with Authorize attribute, it means no one can access its actions without login. So in Logon action you don't need to check if the user is authorized to redirect to main controller. There isn't any security flaw here and you don't need to worry about authorization when you use RedirectToAction("Index", "Main").

Q: A definition in the the Authorize attribute would not solve the problem. How can Administrators restrict users and groups when they buy the software? Thy have no access to the code.

Roles are created for such requirement. You should use [Authorize(Roles="Role1")] above MainController and then each user of Role1 can access the actions of main controller. It can simply be done in user and role management of your application. So:

  1. At development time, decorate controllers and actions with static roles
  2. At run-time, you can manage user role using your application.

Note

In most applications roles are static and you can say which role can have access to which action. In such cases the current Authorize attribute would be enough for authorization. Just add users to roles at run-time. Identity Samples contains required models, views and controllers to do so.

In a case which you want to create new roles at run-time or change permissions of a role at run-time, you need to create a new Authorize attribute which reads role of user from a config file or database and also read permissions of a role from a config file or database and decide about authorization.

like image 20
Reza Aghaei Avatar answered Sep 24 '22 12:09

Reza Aghaei


You should not use <authorization> tag in ASP.Net MVC. It is meant for ASP.Net Web Form. You can read more in SO.

In ASP.Net MVC, you want to use [Authorize] attribute. In addition, you want to use OWIN middleware instead of old FormsAuthenticationTicket.

It has few pieces, so I created a sample project in GitHub AspNetMvcActiveDirectoryOwin. The original souce is to authenticate with AD, but you just need to tweak ActiveDirectoryService class.

The following three are the main classes -

  1. AccountController

  2. ActiveDirectoryService

  3. OwinAuthenticationService replaces FormsAuthentication.

like image 32
Win Avatar answered Sep 23 '22 12:09

Win