I'm trying to develop an ASP.NET MVC application which has few views. I have the following code for controller to restrict access for users:
Controller:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (!string.IsNullOrEmpty(model.ReturnUrl))
return Redirect(model.ReturnUrl);
return RedirectToAction("Edit", "Home");
}
ModelState.AddModelError("Password", "The user name or password provided is incorrect");
}
// if we got this far, something failed, redisplay form
return View(model);
}
In Web.Config:
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/Home/Login" timeout="10" />
</authentication>
<authorization>
<allow users="*" />
</authorization>
<membership defaultProvider="LabourTimeProvider">
<providers>
<clear />
<add name="LabourTimeProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider" connectionStringName="LabourTime" attributeMapUsername="sAMAccountName" />
</providers>
</membership>
<roleManager defaultProvider="CustomRoleProvider" >
<providers>
<clear />
<add name="CustomRoleProvider" type="LabourTime.CustomRoleProvider" />
</providers>
</roleManager>
</system.web>
<location path="Home/Login">
<system.web>
<authorization>
<allow roles="mydomain\mygroup" />
<deny users="*" />
</authorization>
</system.web>
</location>
<location path="Home/Edit">
<system.web>
<authorization>
<allow roles="mydomain\mygroup" />
<deny users="*" />
</authorization>
</system.web>
</location>
In location path, if I use something like,
allow users = "my-user", it is working fine. Only the user is having access.
However, I would like a group of users in the mygroup to access the page. I don't know how to achieve this. I tried this code by doing some research but it didn't work. What to do I do in order to get access for the whole group?
When I try to login using an ID from the group, it doesn't work. Any suggestion is appreciated. Thanks!
There are different ways of achieving access by groups. Since you already use attributes I would suggest using the following approach:
[Authorize(Roles="Administrators")]
public class AdminController : Controller
{
.....
}
When you wanna put logic within your code you can use a construction like this:
if (Roles.IsUserInRole(userName, "ConfirmedUser")
{
.....
}
In your example, it is clear you are talking about a domain joined users group (part of an Intranet). In general Group Policy Objects (GPO) and Security Groups (SGs) are created within in Active Directory (AD), and domain users are member of these SGs.
In other cases DB hosted on DB Server can also be linked to same SGs, and in some cases DBs are not linked to any AD SGs, but have a different login account for an added security.
Access to these SGs are managed by IT Support Specialists of a given organization.
<authorization>
<allow users="*" />
</authorization>
Having said that, upon using <allow users="*" /> within Web.config will only allow domain users whose domain accounts are member of their appropriate Security Groups (SGs), created for their organization with in Active Directory (AD). As long as the application being developed is deployed on Application server joined to same domain, the GPOs and SGs security automatically gets synchronized to users and computer accounts for that domain. Therefore, only users member of SGs are able to access the application within an Intranet.
Related
I've got a ASP.NET MVC page that I'd like to secure with a login and not only authenticate against an Active Directory using Forms Authentication, but also grant access only to specific roles.
web.config
<system.web>
<authentication mode="Forms">
<forms name=".ADAuthCookie" loginUrl="~/Home/Login" timeout=45 protection="All" />
</authentication>
<authorization>
<allow roles="Admin" />
<deny users="*" />
</authorization>
...
Controllers
[HttpGet]
public ActionResult Index() {
return View("~/ng-app/index_template.cshtml");
}
[HttpGet, AllowAnonymous]
public ActionResult Login() {
return View("~/ng-app/login_template.cshtml");
}
[HttpPost, AllowAnonymous]
public ActionResult Login(LoginDto dto) {
... // validate dto & stuff
FormsAuthentication.SetAuthCookie(loginModel.Username, loginModel.RememberMe);
}
Now, basic protection and general authentication works perfectly. I can log in with my domain account and I don't have access to any other pages as anonymous users. However, I'm somehow unable to restrict access only to a certain role. When I add <allow roles="Admin" /> to the authorization section, it does absolutely nothing. When I additionally add <deny users="*" />, I lock myself out and even after successful login, the server always returns 302 Found without doing any redirects or serving the actual file.
You should be doing the allowed roles on the controller declaration
So above your actionresult declaration put this above
[HttpGet]
[Authorize(Roles="Admin")]
public ActionResult AuthorizedView() {
return View("~/ng-app/admin_template.cshtml");
}
This will then do a check to see if the user is in the role declared or not
To declare the roles in the webconfig you could do something like below
<authorizationConfiguration>
<controllerAuthorizationMappings>
<add controller="Home" role="GeneralAccess">
<!-- Define allowed roles for actions under the Home Controller -->
<actionAuthorizationMappings>
<add action="MyTopSecretActionForSuperCoolPeopleOnly" roles="Developer,Manager,Fonzie" />
</actionAuthorizationMappings>
</add>
</controllerAuthorizationMappings>
</authorizationConfiguration>
And here is a link to the site
http://www.ryanmwright.com/2010/04/25/dynamic-controlleraction-authorization-in-asp-net-mvc/
There is far to much for me to bring it into this thread, I will turn it in to a wiki answer when I have 5 minutes
Just like the title states. Need the windows logon and domain info from within our asp.net page.
I tried
string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
but it returns the IIS App Pool not the user name
Thanks
Try HttpContext.User, accessible simply as User from the code behind. It returns both the domain and username, but should be easy enough to trim for your needs. It's worked for me in the past. You can also use this to manage roles in your application, if you need to.
EDIT
Below are the relevant portions of my web.config. I also used aspnet_regsql.exe to setup the tables needed for the role manager in my database. I could then use User.Identity.Name and User.Identity.IsInRole
<connectionStrings>
<clear/>
<add name="SqlRoleManagerConnection"
connectionString="myConnectionString">
</add>
</connectionStrings>
<system.web>
<authentication mode="Windows" />
<authorization>
<deny users="?"/>
</authorization>
<roleManager enabled="true" defaultProvider="SqlRoleManager">
<providers>
<clear/>
<add name="SqlRoleManager"
type="System.Web.Security.SqlRoleProvider"
connectionStringName="SqlRoleManagerConnection"
applicationName="myAppName" />
</providers>
</roleManager>
</system.web>
This is my code in VB.net
var strUser = System.Web.HttpContext.Current.User.Identity.Name
so C# must be in the lines of: (not tested)
string strUser = System.Web.HttpContext.Current.User.Identity.Name;
In the Web.Config file
<configuration>
<system.web>
<authentication mode="Windows"/>
<identity impersonate="true" />
</system.web>
</configuration>
I have an MVC 4 application which is open to all users, no login needed. There is one controller only which I need to apply Windows Authentication to via a Web.Config, like this:
<authentication mode="Windows" />
<authorization>
<allow users="domain\jsmith" />
<deny users="*" />
</authorization>
The controller would MySite.Com/MyApp/MyAdminReportController
If this is possible, how?
I think you just need Windows auth and specify paths which are only need authorization. If you don't need Forms auth as well it looks like this:
<configuration>
...
<system.web>
......
<authentication mode="Windows">
</authentication>
</system.web>
<location path="MyAdminReport">
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</location>
</configuration>
This is web config approach, other options is adding [Authorize] attribute to your controllers (even not hole controller you can add this attr for only specific actions too).
[Authorize]
public class MyAdminReportController : Controller
{
//[Authorize]
public ActionResult PrivatePage()
{
return View();
}
}
I have web config:
<location allowOverride="true" path="Admin/Secure">
<system.web>
<authorization>
<allow users="SpecificUserName1" />
<allow users="SpecificUserName2" />
<deny users="*" />
</authorization>
</system.web>
</location>
I need to get all users (SpecificUserName1, SpecificUserName2) in runtime.
How can i accomplish this?
UPDATE I need to do this in View
Now i use default approach:
#if (Request.IsAuthenticated)
{
//secure menu
}
Now:
Menu showing for all users in domain, but access granted only users which exists in web.config
Need:
Hide menu/allow access for all users in domain except users which exists in web.config
UPDATE
I found the solution
http://forums.asp.net/t/1787320.aspx/1
UrlAuthorizationModule.CheckUrlAccessForPrincipal(Request.Url.AbsolutePath, HttpContext.Current.User, HttpContext.Current.Request.HttpMethod);
First things first, don't use web.config to control authorization in an ASP.NET MVC application.
Use the [Authorize] attribute. Decorate the corresponding controller/action with it:
[Authorize(Users = "SpecificUserName1, SpecificUserName2")]
public ActionResult Secure()
{
...
}
You could then externalize those usernames in a constant and reuse the value. By the way depending on where exactly you need those values, there might be other ways to retrieve them.
I am using the code below to access a page base based upon user authentication
if (user.FirstOrDefault() == HashedPassword)
{
string roles = "Member";
// Create the authentication ticket
FormsAuthenticationTicket authTicket = new
FormsAuthenticationTicket(1, // version
loginName.Text, // user name
DateTime.Now, // creation
DateTime.Now.AddMinutes(60),// Expiration
false, // Persistent
roles); // User data
// Now encrypt the ticket.
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
// Create a cookie and add the encrypted ticket to the
// cookie as data.
HttpCookie authCookie =
new HttpCookie(FormsAuthentication.FormsCookieName,
encryptedTicket);
// Add the cookie to the outgoing cookies collection.
Response.Cookies.Add(authCookie);
Response.Redirect("/Members/ClientAccount.aspx");
}
else
{
Response.Redirect("signin.aspx");
}
}
The user is getting directed to ClientAccount.aspx if the login details are correct but I want that to happen only if his/her role is set as Admin as shown in the web.config file below .
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="members.aspx">
<system.web>
<authorization>
<allow roles="Member" />
<allow roles="Admin" />
<deny users="?" />
</authorization>
</system.web>
</location>
<location path="ClientAccount.aspx">
<system.web>
<authorization>
<allow roles="Admin" />
<deny roles="Member"/>
<deny users="?" />
</authorization>
</system.web>
</location>
</configuration>
How do I make this happen ?
I guess the web.config file is not looking at the cookie to do the authorization so I am doing something wrong there.
Double check your location path relative to the web.config, my guess is that is the problem.
<location path="/Members/ClientAccount.aspx">
...
</location>
Of course you'll need to do something else instead of this line, you were just doing this for testing I'd assume?
Response.Redirect("/Members/ClientAccount.aspx");
i.e. redirect them to a page you know they're not allowed to hit. I figure you're going to beef that part up once you're sure its not allowing members to access that page.
You should make sure your web.config has the following tag:
<authentication mode="Forms" />
You need to configure it right, there are lots of options:
<authentication mode="Forms">
<forms loginUrl="Login.aspx"
protection="All"
timeout="30"
name=".ASPXAUTH"
path="/"
requireSSL="false"
slidingExpiration="true"
defaultUrl="default.aspx"
cookieless="UseDeviceProfile"
enableCrossAppRedirects="false" />
</authentication>
http://msdn.microsoft.com/en-us/library/ff647070.aspx
hey there, did you mean to have
<deny roles="Member"/>
right now, the deny policy really doesn't need the member role listed. If you are wanting member to also be allowed to that page, you will need to swap out the deny, to allow:
<authorization>
<allow roles="Admin" />
<allow roles="Member"/>
<deny users="?" />
</authorization>