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:
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
?
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.
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:
[Authorize]
[Authorize(Users="User1,User2")]
[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:
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.
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 -
AccountController
ActiveDirectoryService
OwinAuthenticationService replaces FormsAuthentication.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With