I need some clarifications for ASP.NET Membership; please help me with it.
I am using ASP.NET MCV 3 framework and intending to use ASP.NET Membership for users & authentication management using either LDAP or SQL.
For what I've understood until now; ASP.NET Membership is:
[User] has [Role] or [Role] has [Users]
But in my project I have a more complex business logic; where I need this hierarchy to next level like
[User] has [Role] -> has [Tasks]
So I can dynamically assign/revoke tasks/permissions to my MVC controllers or actions;
I plan to get started with Membership with SQL Provider and than may be later on I'll switch to LDAP/AD.
I've also explored AzMan and NetSqlAzMan; they look ok to resolve the error but their usage seems odd; (not as neat as ASP.NET Membership; where we can simply use annotations to assign roles/tasks to a controller or its action.
Is ASP.NET Membership limited to Roles only? & no tasks/operations?
Or is there any workaround for that?
Can I enjoy the simplicity of usage of ASP.NET Membership and on the same road have a next level hierarchy for Roles -> Tasks -> Operations.
Any help would be greatly appreciated.
Thanks!
ASP.NET's Membership provider only supports roles out of the box. It doesn't support tasks or operations. However it is relatively easy to create a custom Role Provider to meet just about any need.
For a good start check out 'Implementing a Role Provider' at http://msdn.microsoft.com/en-us/library/ie/8fw7xh74.aspx . You can also find a sample Role Provider at http://msdn.microsoft.com/en-us/library/ie/tksy7hd7.aspx .
ASP.NET Membership only supports Roles, no tasks or operations.
You can use attributes to signify which operations are allowed for which roles, like so:
[Authorize(Roles="Administrator")]
public ViewResult Edit(int id)
{
return View("Edit");
}
Or your code can do checking using the IsInRole method:
if (User.IsInRole("Administrator"))
{
...
}
Good luck!
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 am having troubles wrapping my head around the concept of multi tenancy in combination with websecurity (webmatrix framework from microsoft). I am building a mutli tenant website with:
mvc4
entityframework6
websecurity (from webmatrix)
Authenticate
I can allow users to register & login using the WebSecurity methods. I can verify if a user is logged in / is authenticated via User.Identy.IsAuthenticated.
Determine Tenant
I determine the tenant via the url ([companyname].domain.com).
Register a new customer
A new customer can create a tenant via the registering form in my application. If a user registers (without having a companyname present in the url) he will have to give some account inputs as some company inputs. He will then create a new alias which is conform companyname.domain.com. So, long story short, a Tenant is always coupled to 1 or more user(s) (1-N).
Requirement
I need to guarantee that a user from Tenant 'abc' will never be able to login to Tenant 'xyz'. (Therefore I also don't like the WebSecurity framework too much, as it seems a shared database for all my tenants (or am I wrong?)).
My question
Could you guys share some insights in how to handle the check on "tenant" and "authenticated user" in real world multi tenant applications?
The hot topics for me:
Do you validate the tenant + authenticated user once, or in every action in every controller?
Is it safe to rely on the default websecurity class or would I be better of designing my own user tables or are customer MembershipProviders the better alternative?
Should I use cookies or is that a very bad choice.
I would be very much helped if you could share some documentation where I can read all about these questions. I have the strong desire to see some more in detail documentation about multi tenancy, that dives into the actual design (maybe even code examples).
I already read through most of the "general documentation" / "commericial presentations":
http://msdn.microsoft.com/en-us/library/aa479086.aspx
http://www.businesscloud9.com/content/identifying-tenant-multi-tenant-azure-applications-part-2/10245
http://msdn.microsoft.com/en-us/library/windowsazure/hh689716.aspx
http://www.developer.com/design/article.php/3801931/Introduction-to-Multi-Tenant-Architecture.htm
If needed I'll rephrase / add code / do whatever is needed to get help.
Many thanks in advance.
Each solution you could get here would be dependent on what your app does and how it works with data, if you use repository pattern, if you use IoC etc. You might consider instantinating your repository by passing userid to repository class and doing filtering everytime application needs data, you can do that in your controller - this approach is used very often (even in VS SampleProjects - like "SinglePage Application" you might want to download some open source projects and just see how it's done there.
What I do in some of my projects where nothing "really fancy" is required and I don't expect a huge load is this:
- I setup BaseController that every other controller needs to implement
- in onActionExecuting event of the BaseController I do
public Employee CurrentEmployee { get; set; }
protected override void OnActionExecuting(ActionExecutingContext ctx)
{
base.OnActionExecuting(ctx);
string authenticatedUser = User.Identity.Name;
CurrentEmployee = mortenDb.Employees.FirstOrDefault(e => e.Account.Login == authenticatedUser );
}
so in all other controllers I'm able to refer to an Employee object that belongs to currently logged in user. You could do the same with your Company object. So I assume you would query Employees like I do and retrieve the Company reference and pass it to public property on your BaseController. It's maybe not the best solution, but it's rather secure as long as you remember to pull out data via Company object navigation properties (eg. Employees, Tickets, Requests etc. whatever you have in your Model )
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 :-)
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()
{
....
}
}
I am building an application using asp.net mvc, DI, IoC, TDD as a bit of a learning exercise.
For my data access I am using the repository pattern. Now I am looking at membership and how this can work with the repository pattern. I am currently using a Linq to Sql repository but don't want to be tied to SQL Server for membership.
Secondly, I am looking to split out membership into a number of services:
AuthenticationService - identify the user
AuthorizationService - what can they do
PersonalizationService - profile
The personalization service will be what really defines a "customer" in my application and each customer will have a unique id/username that ties back to the AuthenticationService - thus, allowing me to use the default ASP.NET Membership provider, roll my own or use something like Open ID.
Is this a good approach? I don't want to reinvent the wheel but would rather these important parts of my application follow the same patterns as the rest.
Thanks
Ben
Take a look at the RIA Authentication, Roles, and Profiles services.. no need to reinvent the wheel.
To be honest, to achieve what I wanted was quite a simple process. I haven't implemented the AuthorizationService yet but this will follow a similar pattern.
My authentication service is quite simple:
public interface IAuthenticationService
{
bool IsValidLogin(string username, string password);
}
There will be a CreateUser method but I haven't implemented this yet.
Creating an authentication service using the standard membership provider is a simple task:
public class AspNetAuthenticationService : IAuthenticationService
{
public bool IsValidLogin(string username, string password)
{
return Membership.ValidateUser(username, password);
}
}
If I want to swap out the default SqlMembershipProvider with my own then I just need to change web.config. In order to support different types of authentication (perhaps forms auth and open id) I can just create a controller action for each and call the appropriate IAuthenticationService.ValidateUser implementation before setting an auth cookie.
The authentication process if for identifying the "user". In order to get the "Customer" I am using a PersonalizationService. The interface for this is again quite simple:
public interface IPersonalizationService {
Customer GetCustomer(string username);
}
This returns my customer (with addresses, past orders - the stuff we really care about). The GetCustomer method will create a customer object if one doesn't exist with the passed in username. So if using standard forms auth a customer will be created anyway during registration. If using something like OpenID, the first time they login a customer object will be created and linked to their OpenID username (hence the reason for separating what an authenticated "user" is from a "customer".
This process also works well for anonymous checkout since I can create an in memory customer object for "guest" customers, and finally persist this to the database if they make a purchase. In this case, I don't have a user (cause they didn't authenticate) but I do have a customer.
I am quite happy with this implementation. I think I will roll my own Membership Provider (since it's not really that difficult) and I would like to use the repository pattern for the data access. Interested to hear any opinions / suggestions on this approach.
Some resources I have used:
http://noahblu.wordpress.com/2009/02/19/custom-membershipprovider-using-repository-dependency-injection-pattern-magic/
http://davidhayden.com/blog/dave/archive/2007/10/11/CreateCustomMembershipProviderASPNETWebsiteSecurity.aspx
http://pbdj.sys-con.com/node/837990/mobile
http://mattwrock.com/post/2009/10/14/Implementing-custom-Membership-Provider-and-Role-Provider-for-Authinticating-ASPNET-MVC-Applications.aspx