All the security stuff I have worked with in the past in ASP.Net for the most part has been role based. This is easy enough to implement and ASP.Net is geared for this type of security model. However, I am looking for something a little more fine grained than simple role based security.
Essentially I want to be able to write code like this:
if(SecurityService.CanPerformOperation("SomeUpdateOperation")){
// perform some update logic here
}
I would also need row level security access like this:
if(SecurityService.CanPerformOperation("SomeViewOperation", SomeEntityIdentifier)){
// Allow user to see specific data
}
Again, fine grained access control. Is there anything like this already built? Some framework that I can drop into ASP.Net and start using, or am I going to have to build this myself?
Have you looked at Authorization Manager (AzMan)? http://msdn.microsoft.com/en-us/library/bb897401.aspx
It was included with Server 2003 and has had a few updates in server 2008, and comes with an MMC admin tool.
You can store you data in an xml file or AD/ADAM partition using server the 2003 version, and in server 2008 they added SQL support.
This tool lets you link your security objects together in a hierarchical structure of roles, tasks & operations.
You can use this as a role based provider in Asp.net but they also include .net classes so you can access the authorization store contents directly.
I think you might be looking for Declarative security. Declarative security allows you to well, 'Declare' who can access what as attributes on the code here is a page on Role Based security also on MSDN. Here is an example:
[PrincipalPermissionAttribute(SecurityAction.Demand, Role="admins")]
public class foo
{
[PrincipalPermissionAttribute(SecurityAction.Demand, Role="Domain Admins")]
public void bar()
{
....
}
}
Related
I'm building an application in ASP.NET MVC4 as a learning exercise. I'm trying to understand
authentication and authorization. That seems fine, role based authorization seems fine for restricting certain controllers/actions to users who are part of a given role.
What I'm struggling with is how I can apply this to data which belongs to an individual user. Using a forum as a simple example how could the functionality be achieved whereby a user can only edit or remove posts that they have created but can view/add comments to posts of other users. Would this have to be done in code by checking the user associated with the post to be updated against the current user before allowing the update to take place, returning unauthorized if they don't match.
Is there a more elegant solution that can be applied rather than applying this kind of logic to multiple controllers/actions?
There's a wealth of information out there I'm just trying to narrow the search. Can anyone suggest a good tutorial/article on this. I've been looking at Forms authentication and Membership but I'd be interested in something using Identity too. I'm also using Entity Framework.
Thanks
Would this have to be done in code by checking the user associated with the post to be updated against the current user before allowing the update to take place, returning unauthorized if they don't match.
Yes, that's exactly what you do. While role-based authorization is a matter of a simple relation between users and roles, data-access level authorization is usually complex and involve custom business rules.
Of course, it could help a lot to create a thin layer of managers that will be commonly used as guards so that you keep all the code close together:
[HttpPost]
public ActionResult PostFoo( FooModel model )
{
// keep the access manager separate from the
// domain layer. operate on IDs.
if ( new UserAccessManager( this.User ).
CanOperateOnFoo( model.IdSomething, model.IdWhateverElse ) )
{
}
else
// return 403 or a meaningful message
}
or
[HttpPost]
public ActionResult PostFoo( FooModel model )
{
// switch to the domain layer
Foo foo = Mapper.Map( model );
// make the access manager part of the domain layer
if ( foo.CanBeOperatedBy( this.User ) )
{
}
else
// return 403 or a meaningful message
}
Would this have to be done in code by checking the user associated with the post to be updated against the current user before allowing the update to take place, returning unauthorized if they don't match.
No, you want to avoid hard-coding authorization logic into your code. Doing so leads to:
authorization silos
poor visibility
a chance there might be errors in the authorization logic
hard-to-maintain logic
Is there a more elegant solution that can be applied rather than applying this kind of logic to multiple controllers/actions?
Yes, there is. Much like you wouldn't hard-code authentication or logging into your app, you want to externalize authorization. This is called Externalized Authorization Management (EAM). There are several frameworks that help you do that from Spring Security in Java to Claims-based authorization in .NET to XACML-based solutions.
There are 2 fundamental authorization models you want to consider:
role-based access control (RBAC)
attribute-based access control (ABAC)
You can read about both on NIST's website (RBAC | ABAC).
Given the sample rule you gave:
A user can only edit or remove posts that they have created but can view/add comments to posts of other users.
RBAC will not be enough. You will need to use ABAC (and XACML) to be able to implement the relationship between the user and the data requested. XACML, the eXtensible Access Control Markup Language is a standard that provides you with:
a standard architecture.
a request/response scheme, and
a policy language.
With the XACML policy language, you can rewrite your example as:
A user can do the action==edit or the action==remove if and only if the post.owner==user.id
A user can do the action==view on any post
A user can do the action==comment on any post
Then, from your code, all you have to do is send an authorization request: Can Alice view post #123?. The authorization engine (also called policy decision point or PDP) will determine who owns the post and will reach a decision, either of a Deny or a Permit.
A key benefit to using externalized authorization and XACML is that you can apply the same consistent authorization to any layer (presentation tier, business tier, ESB, APIs, databases...) and any technology (Java, .NET, Python...).
Other benefits include:
modular architecture
configuration-driven authorization that is easy to grow as requirements change
easy-to-audit authorization
centrally-managed authorization
cheaper to develop and onboard new applications than writing code over and over again
standards-based.
There are several open-source and vendor solutions out there that address this market. Have a look at Axiomatics (disclaimer: I work for Axiomatics) or SunXACML (open source).
HTH,
David.
I'm creating a generic flexible site that I can use over and over again but with different features activated or deactivated. I'm looking for the best method to approach my solution.
Specific areas will need to be closed off in certain circumstances, for instance, the application will contain an event management page, but it will not always be required. The application will pull out the active and deactivated features from a data source.
They're going to be like Application wide settings, that will be required on each page, hiding away those settings that are turned off from the menu and not allowing users to access the deactivated feature pages.
I have thought of a number of ways to achieve this :
Store the feature statuses in the database, then on each time the page / menu is accessed / displayed, call the database requesting whether to hide the page / menu item.
Store the feature statuses in the database and access them on the application startup, store them application wide then they can be accessed as and when.
Put the feature statuses in the web config, this way we don't need to query the database every single time or have globally accessible properties.
I would like you advice on which method would be best, or if a better method is available I would be grateful. I don't want to hit the database too many times, or would a simple check like this not be too performance expensive? I'm also not sure if the web config is secure enough for managing active site features.
Regards,
I think putting configuration in configuration file(web.config) would be better option. Because while displaying page/loading menu going to database every time to see whether it should be de/active, required database trip which is overhead.
And if the configuration is stored in web.config it is easily accessible by admin and also easy to modify without compiling or changing anything.
So, in my view best option is to store configuration in web.config. In addition to that you can also make administration page which will change configuration settings and should be reflected in configuration file.
I suggest 2nd approach - store the settings in the database and then retrieve them at startup and store in application scoped containers.
The advantage of such approach over the web.config is that you can easily take client database and immediately run it in your development environment for testing/debugging. If, on the other hand, some settings are stored outside of the database, cloning the site means that you not only have to clone the database but also all the settings from various other resources (like the web.config).
The answer depends on how often you will be changing the status of the features.
If you are going to only set the statuses once when you clone the site and will never touch it again, go with option #2 (load on application start).
If there is any possibility that you will need to change the status of the features in the future, go with option #1 (get statuses on each page load). A simple datareader read to the db will not affect the speed of your site. The db is your friend, remember that's what it is there for. Also, if you ever need to change the statuses while the site is up and running, this method allows you to do so without restarting the entire application.
Whatever method you finally decide to implement, make sure the "application wide" location you store the settings is multi-threaded ready. Remember, each page request will be run on a separate thread and they will all access the same resource.
My suggestion taken from MS (multi-thread safe Singleton Pattern):
using System;
public sealed class Singleton
{
private static volatile Singleton instance;
private static object syncRoot = new Object();
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
}
I've got confused . We hear a lot about Provider in ASP.NET . Membership-Provider , Role Provider , XmlDataProvider ,CustomProvider, ....
What are those and why we need them in ASP.NET ?
Provider is a synonyme with "Supplier" which means:
Someone whose business is to supply a
particular service or commodity
Just as in real life, a provider is someone / something that helps you solve communicaiton with a certain service or help you solve a problem.
For instance, the Membership Provider in .NET is used to handle Membership such as Authentication, Registering new Users and many more options comes with this.
The Role Provider goes hand in hand with the above, because it helps you handle Roles attached to users that you have in ( They have Memberships! ).
You might want to read this: Microsoft ASP.NET 2.0 Provider Introduction from MSDN
Using the Provider model means that if you don't like the way something in ASP.NET works or you want/need to extend it, you can write your own. As long as it supports the core functionality that ASP.NET needs to work as part of the platform i.e. it inherits from MemrbershipProvider/RoleProvider/WhateverProvider, you can do what you want in the internals.
You can then swap out the default Provider and use yours in it's place e.g. say you don't use SQL Server, you use CouchDB for all your data storage. You can't use the SqlMembershipProvider, but you can write a CouchDBMembershipProvider* - as long as you inherit from MembershipProvider and override its' methods to work with CouchDB you're good to go.
* I'm not saying you should do this, I'm just saying you can :-)
I am trying to build an ASP.NET 3.5 website that allows users to log in and browse a couple of pages. I would like to restrict certain users to be able to view certain pages but I'm having trouble coming up with a custom and flexible system. I have seen MS's version of this but it's not what I am looking for. Can anyone direct me to some good online articles or even a video tutorial so I can do further research. Thanks!
P.S. I have tried creating a class that inherits from System.Web.UI.Page which does some checking but it's getting messy. All my other pages inherit from that common page. Is this a common practice? How have you guys solved this problem in the past?
The best way to implement this would be, Forms Authentication coupled with Custom Role Provider.
Hope you know, for Forms Authentication to work, you need not have to use the Complete Database Setup that MS uses to Authenticate.
You can simply have your own Database and Validate a user yourself, and just set the cookie.
String UserName = "CoolGuy";
Boolean isValidUser = YourClass.YourMethod(UserName);
if (isValidUser)
{ FormsAuthentication.setAuthCookie(UserName, false); }
This will authenticate the user "CoolGuy" for the session, provided YourMethod returns true.
You can use this, coupled with custom role provider. This gives you the facility to check User.IsInRole("Role"); in your code.
To Start with CustomRoleProvider.. here is a good reference... http://davidhayden.com/blog/dave/archive/2007/10/17/CreateCustomRoleProviderASPNETRolePermissionsSecurity.aspx
Raja
Well, without knowing the exact details of your app, one thing you could use is the Role Manager built into the Membership API.
Basically, you would create roles for each page and assign users to the roles (pages) you would want them to view.
In the code behind for each page, on the On_Load event, I would simply call the method
if(Roles.IsUserInRole(rolePageName))
{
//Continue page loading logic
}
{
//Redirect or transfer the user elsewhere
}
For this kind of logic you may want to reconsider using an inherited page, otherwise you're going to have to come up with a way to retrieve the URL of the page and pass that into some long list of if-else or switch statements to call the proper Roles.IsUserInRole method.
I have to call some code in a SharePoint site that runs under the same service ID that the web application is running under. By default, SharePoint impersonates the user viewing the web page, and the users don't have the necessary permissions.
What is the best way to run some code using the web application's service ID, then revert back to using the default impersonation?
SPSecurity.RunWithElevatedPrivileges
Nat is right. You should use SPSecurity.RunWithElevatedPrivileges. Under the covers it does a ReverToSelf that Anthony mentions, but it is much easier to use the helper method. You can use an inline delegate as in the following example.
The main thing to realize is that this delegate runs under a separate application domain which basically means that you want to use a SPSite or SPWeb you must re-instantiate them within the delegate as shown below.
SPSecurity.RunWithElevatedPrivileges(delegate()
{
// Your are now inside the delegate
// Anything provided within this block is marshaled across the app domain
using (SPSite site = new SPSite("http://myserver/sites/mysite"))
{
using (SPWeb web= site.OpenWeb())
{
// Do stuff here
}
}
});
Under ASP I had a utility DLL that I could use to call Win32's RevertToSelf() function (found in the advapi32.dll) to get the ASP to run under the identity of the application pool.
Of course once there, there's no going back to the original identity the thread was using but that's not really a problem. Once the current request had ended, the next request would run again under the users identity (or the anonymous users).
You could probably do the same with PInvoke in ASP.NET but I wouldn't know what effect that might have on the framework. I'm certain it would last only for the current request. I don't think there is any standard .NET API to do this.
easy! Wrap the calls you're making in a HostingEnvironment.Impersonate() block.
http://msdn.microsoft.com/en-us/library/system.web.hosting.hostingenvironment.impersonate.aspx