I'm creating an app with ASP.NET WebForms. I have custom database with users table. It contains name and role. How can I add roles from DB to website? I want to use something like this:
<location path="path">
<system.web>
<authorization>
<allow roles="role"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
where role should be imported.
Thank you!
You can implement a custom RoleProvider.
As a minimum you need to implement Intialize (of course) and the methods GetRolesForUser and IsUserInRole. The other methods are only needed if you want to be able to administer roles through the RoleProvider.
IsUserInRole can often be implemented as something close to:
public bool IsUserInRole(string username, string roleName)
{
return GetRolesForUser(username).Contains(roleName);
}
so apart from initialization, which in your case will probably only be storing a database connection string, you only have one simple method to implement.
Related
I created an ASP.NET MVC app with the following override via a custom AuthorizeAttribute implementation:
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return base.AuthorizeCore(httpContext);
}
However, within this method, httpContext.User.Identity.Name is "". I need to get a handle to the current Identity.Name so I can retrieve some data based on that value. I have the following entries in web.config:
<authentication mode="Windows" />
<authorization>
<deny users="?"/>
</authorization>
At minimum, I think that the MVC site should prompt me for credentials with the configuration above, right?
I was able to get the network user ID with the following alternate code:
Request.LogonUserIdentity.Name
Are there any implications or impacts of using this code as opposed to:
httpContext.User.Identity.Name
I am building an intranet site where users will be on the corporate domain and have different permission levels. I'm currently using <authentication mode="Windows"/> to control site access, but it seems like I should be using ASP.NET Identity.
For example, say my application is a dashboard for each department in the organization. I want to create a single AD group called DashboardUsers and put everyone that can touch the site in this group.
I also want to restrict the views in the dashboard. For example, I only want the IT group to see their view, and the Finance folks see theirs, etc.
Question -- should I be using Windows Authentication to control access to the site, and then use ASP.NET Identity for user level permissions?
I have done something similar to this using only WindowsAuthentication. You can tag your actions with the Authorize Attribute:
[Authorize(Roles = #"DashboardUsers")]
As long is this user is a member of the DashboardUsers AD group they will get access to this action. It seems like MVC magic, but it really is that simple.
Unfortunately this approach will not allow you to overload an action for different Roles as the Authorize Attribute is not part of the method's signature. In your views, you would have to show different anchor tags based on the current users role.
ie:
[Authorize(Roles = #"DashboardUsers\Manager")]
public ActionResult IndexManagers()
{
..
}
or
[Authorize(Roles = #"DashboardUsers\Finance")]
public ActionResult IndexFinance()
{
..
}
EDIT AFTER COMMENT:
Since your Identity is coming from AD, you could use logic in your controller like:
if(User.IsInRole("Finance"))
{
..
}
else if(User.IsInRole("IT"))
{
..
}
And this will check which AD Group they belong too. I know it's not very elegant, but I can't imagine mixing Windows Auth with a custom identity and managing permissions in your own db would be elegant either.
I have run into this dilemma before and wound up creating a custom role provider that i used in conjunction with windows authentication. I'm not sure you need the OWIN middleware when authenticating against AD.
public class MyAwesomeRoleProvider : RoleProvider
{
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
{
// i talk to my database via entityframework in here to add a user to a role.
}
// override all the methods for your own role provider
}
config file
<system.web>
<authentication mode="Windows" />
<roleManager enabled="true" defaultProvider="MyAwesomeRoleManager">
<providers>
<clear />
<add name="MyAwesomeRoleManager" type="MyAwesomeNamespace.MyAwesomeRoleProvider" connectionStringName="MyAwesomeContext" applicationName="MyAwesomeApplication" />
</providers>
</roleManager>
</system.web>
I have implemented the ASPNET membership provider and at the Login1_LoggedIn event, I tried to get Membership.GetUser() or Page.Identity.User but both of them returned null.
I tried different solutions suggested by others including changing form path="/" but have no luck. However the LoginName control works and showing the username correctly.
Does anyone has an idea why?
Try to disable non-authenticated users in web.config:
<authorization>
<deny users="?" />
</authorization>
the HttpContext.Current.User will not pupulated until you call :
FormsAuthentication.SetAuthCookie(UserName, False)
or
FormsAuthentication.RedirectFromLoginPage(UserName, False)
I have found out why, ScottGu has explained it well in his blog post.
http://forums.asp.net/t/982749.aspx
Normally use authorization settings to interact with the roles.
<location path="Register.aspx">
<system.web>
<authorization>
<allow roles="Administrator"/>
<deny users="?"/>
</authorization>
</system.web>
</location>
But I would like to have this setup in the database in a table
tblAuthorization
-IdAuthorization (Identy(1,1))
-IdCompany=5
-IdRol=5 (Administrator”)
-Path=”Register.aspx”
Is there a setting for a class to do this? There is something like Profile, RoleProvider ..
<roleManager enabled="true" defaultProvider="MyAccessRolProvider">
<providers>
<clear />
<add name="MyAccessRolProvider" type="MyAccessRolProvider" connectionStringName="MyConnectionString" applicationName="/" />
<add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
</providers>
</roleManager>
Right now the only I think that can to implement a validation in the Page_Load event
And if it is invalid making a Redirect but I would do a little more "Professional"
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if(!ValidateAuthorization())
{
Response.Redirect("Login.aspx");
}
}
}
Could help me with examples?
Thank you very much in advance
Your best bet is to implement a custom RoleProvider - you seem to be heading in this direction as your question includes a configuration section with a custom RoleProvider (MyAccessRolProvider).
You need to specify the fully-qualified name of your RoleProvider, e.g. MyNamespace.MyAccessRoleProvider, MyAssembly.
MSDN describes how to do this, including a sample implementation.
With the understanding that you are taking about authorization at the page level you could add a HTTP module (IHttpModule) and use your module to do the authorization checking. If the authorization failed then you could redirect as appropriate.
Something like this might work:
public class MyAuthorizationModule : IHttpModule
{
public void Init(HttpApplication application)
{
application.AuthorizeRequest += (new EventHandler(AuthorizeRequest));
}
private void AuthorizeRequest(Object source, EventArgs e)
{
bool isAuthorized = //your code here to check page authorization
if (!isAuthorized)
{
var response = //will need to get current response
response.Redirect("Login.aspx", true);
}
}
}
Note: Don't forget you'll need to add the module to your web application.
There is no out of the box support for this as far as I know however I would suggest you implement something as follows:
Create a new class that derives from AuthorizeAttribute, add an ID property and override the "AuthorizeCore" method.
public class CustomAutorizeAttribute : AuthorizeAttribute
{
public Guid ActionId { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
//Check user has access to action with ID = ActionId
//implementation omitted
}
}
You can add a new database table to hold on the Actions and their associated ID values. You can either add the record to the table manually or write some code to do this using reflection (I would advise this if you have quite a few actions and are likely to add more in the future).
Once this is done you can assign users or application roles access to these actions.
In you custom Authorize attribute you have to check whether the user has access to the given action returning true or false accordingly from the AuthorizeCore method.
I would advise grabbing a collection of all actions a user has access to when a user logs in and storing them in either the server cache or some kind of distributed cache so that you aren't hitting your database on every request.
UPDATE - Sorry just realised you're using ASP.NET Forms and not MVC. My approach is for an MVC application so its probably not relevant although I'll leave it up here in case any MVC developers happen to stumble across your question.
I am building a website on an intranet and one of the directories can only be accessed by hard coded authorized users. They are defined in web.config. It looks similar to this.
<location path="admin">
<system.web>
<authorization>
<allow users="user1"/>
<allow users="user2"/>
<allow users="user3"/>
<allow users="user4"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
What I want then is to create a link to this directory which only appears to those users...
At the moment, to build the link I'm rechecking there windows usernames and hard coding them in again like this...
<%
if (HttpContext.Current.User.Identity.Name == "user1" ||
HttpContext.Current.User.Identity.Name == "user2" ||
HttpContext.Current.User.Identity.Name == "user3" ||
HttpContext.Current.User.Identity.Name == "user4")
{
Response.Write("<a href='admin/Default.aspx'>Admin Site</a>");
}
%>
But what I want to do is reference my list from the webiconfig file and say something like
if (HttpContext.Current.User.Identity.Name == // a user from the web.config list
Is this possible and if so can you help me... Thanks
You can get the authorization rules from web.config like this:
AuthorizationSection configSection =
(AuthorizationSection)ConfigurationManager.GetSection("system.web/authorization");
var users = new List<string>();
var rules = configSection.Rules;
foreach (AuthorizationRule rule in rules)
{
if (rule.Action == AuthorizationRuleAction.Allow)
{
foreach (string user in rule.Users)
{
if (!users.Contains(user)) users.Add(user);
}
}
}
But you must also pay atention to the precedence of the rules.