Extending Active Directory security with actions and roles - c#

We are building an intranet application that would use integrated windows authentication. The application would require custom actions and roles to secure different parts and functions.
My current idea is to extend active directory by storing the roles and actions in a different database linked to an active directory user using the SID. That way we know who the user is and fetch his allowed roles (with the actions) from our database without much hassle.
Do you think this is a good approach or are there better ways of dealing with these things?
I have read this post: User Group and Role Management in .NET with Active Directory
But Active Directory does not support programmatically creating roles and there is no support for custom actions whatsoever.

A couple of options spring to mind:
you could use ADAM (aka AD LDS) for your roles store - the programming model is the same as AD, which is nice;
you could us AzMan (aka Authorization Manager) - it integrates nicely with ASP.NET and you can use it with the builtin Roles provider. It can store its data in XML or in the AD. Also, the EntLib comes with an AzMan wrapper so you've another way to use it. I quite like AzMan because you can make changes to user roles on the fly.

Related

Best practices for centralized identity/auth for multiple internal applications

We have about 10 internal .NET Core 2.1+ and .NET 5 MVC web applications, all using Windows auth with hard-coded permissions based on AD groups. Some extend roles and permissions to the database, but each project have their own scheme.
I’m trying to move to a centralized identity database that all applications can talk to, as well as claims-based permissions (CanEditThing instead of wrapping in User.IsInRole(“Marketing”)). A benefit of this is to keep Active Directory data synchronized in one location instead of putting the same slow DirectorySearcher boilerplate code in each application, as well as quickly generate reports for Auditors showing who has been authorized access to what application.
What is the best or standard way to handle this? All applications share a central Users/Permissions database via common connection string? Or, authenticate users via IdentityServer and JWT combo and keep individual permissions confined to the individual application’s db? Is there a better way to handle this?
Thanks for your insight!

ASP.NET MVC using Azure AD authentication -- how to allow users to administer group/role assignments?

I'm developing an ASP.NET MVC application and using Azure AD for single sign on. I'm at a point where I'm looking at how to handle user roles for authorization. I understand that I can create roles or groups from inside the Azure portal, but everything I've read seems to suggest that the only way to add or remove people to those groups or roles is from within the portal. But we don't want to be in a situation where our developer group is handling role/permission assignments for this application's users.
What I really want is some sort of interface within the application where an Admin can select an AD user, select one (or more) of the application's roles, and add the user into those roles.
Is there a way to pull a list of available application roles from Azure AD, then send back which of those roles should get attached to a user? Most of the documentation I've seen seems to assume that you have a pre-defined list of users that you manage through the portal.
Should I be using separate tables in ASP.NET Identity? I had hoped Azure AD integration would allow me to skip having a database user store.
Take a look at https://github.com/Azure-Samples/active-directory-dotnet-webapp-groupclaims . The code and ADAL reference can certainly be updated as it's quite old, but this should serve as a good starting point.

MVC 3 Membership and Authorization

I am developing an MVC3 application and I have gotten to the point where I need to start securing out different areas of the intranet site to particular users.
The site is being used on the intranet and uses windows authentication for login.
Within the database I have a users table which contains numerous fields that determines the users role. This is maintained in the admin area of the site.
Certain users will have the ability to access the admin area, some users will only have the ability to read certain areas of the site but not contribute, etc etc. There are some complicated business rules.
I am looking for how to secure out different areas. I have read a good few articles around using the authorize attribute on controllers for particular groups, this doesn't seem to be a good fit as I understand it I would have to control what users are in what groups from within the configuration of the application whereas the admin users of the application should be ones controlling this via the application itself.
Any suggestions are welcome.
If you are mainly concerned about managing users, ASP.NET does a great job of this with their built-in Web Application Administration Tool. On the top-right of the Solution Explorer, to the right of the refresh button, is a hammer-and -earth tool that you can click on. It allows you to manage users and roles, and from there you can assign the users to roles. Perhaps your admins can use this.
This tells you how:
http://www.asp.net/mvc/tutorials/mvc-music-store/mvc-music-store-part-7
As far as having to put authorize attributes on the controllers/methods, I don't see any way around that. Let me know if I have misunderstood your question.
Assign users to roles and use AuthorizeAttribute.

Is it possible to have regular logins and ActiveDirectory logins in the same ASP.NET app?

I currently have an app which using Active Directory for authentication. In other words, the IIS virtual directory is setup Active Directory authentication and I do no have to deal with it at all. If you are on the domain, you can get in.
Some customers now also want to add a feature where they can log in using a standard userid/password combo. The scenario being a contractor coming in for a few days with their laptop and need access to the app. There is no point of creating an Active Directory account for such a person.
Is this possible in an ASP.NET app? How would I go about it?
If you converted your app to use Forms Authentication, then you could configure 2 membership providers; one to authenticate against active directory, and the other could use the standard SqlMembershipProvider. This second provider is the one you would create your temporary accounts in.
In regards to authenticating against multiple providers, this is quite straight-forward. This article describes the process.
If you convert the application to use Forms Authentication, you can then process the login method to authenticate off of either Active Directory, or your own internal user database, depending on whatever criteria you expect. There are several articles out there on how to write your own code to perform a simple authentication against Active Directory.
I'd say you probably want your own Authentication Provider as discussed in this article. You'd build the validation logic to auth against the right store depending on your criteria.

Should we develop a custom membership provider in this case?

Summary
Long story short, we've been tasked with gutting the authentication and authorization parts of a fairly old and bloated asp.net application that previously had all of these components written from scratch. Since our application isn't a typical one, and none of us have experience in asp.net's built in membership provider stuff, we're not sure if we should roll our own authentication and authorization again or if we should try to work within the asp.net membership provider mindset and develop our own membership provider.
Our Application
We have a fairly old asp.net application that gets installed at customer locations to service clients on a LAN. Admins create users (users do not sign up) and depending on the install, we may have the software integrated with LDAP.
Currently, the LDAP integration bulk-imports the users to our database and when they login, it authenticates against LDAP so we dont have to manage their passwords. Nothing amazing there.
Admins can assign users to 1 group and they can change the authorization of that group to manage access to various parts of the software.
Groups are maintained by Admins (web based UI) and as said earlier, granted / denied permissions to certain functionality within the application.
All this was completely written from the ground up without using any of the built in .net authorization or authentication. We literally have IsLoggedIn() methods that check for login and redirect to our login page if they aren't.
Our Rewrite
We've been tasked to integrate more tightly with LDAP, they want us to tie groups in our application to groups (or whatever types of containers that LDAP uses) in LDAP so that when a customer opt's to use our LDAP integration, they dont have to manage their users in LDAP AND in our application.
The new way, they will simply create users in LDAP, add them to Groups in LDAP and our application will see that they belong to the appropriate LDAP group and authenticate and authorize them.
In addition, we've been granted the go ahead to completely rip out the User authentication and authorization code and completely re-do it.
Our Problem
The problem is that none of us have any experience with asp.net membership provider functionality. The little bit of exposure I have to it makes me worry that it was not intended to be used for an application such as ours. Though, developing our own ASP.NET Membership Provider and Role Manager sounds like it would be a great experience and most likely the appropriate thing to do.
Basically, I'm looking for advice, should we be using the ASP.NET Membership provider & Role Management API or should we continue to roll our own? I know this decision will be influenced by our requirements so I'm going over them below
Our Requirements
Just a quick n dirty list
Maintain the ability to have a db of users and authenticate them and give admins (only, not users) the ability to CRUD users
Allow the site to integrate with LDAP, when this is chosen, they don't want any users stored in the DB, only the relationship between Groups as they exist in our app / db and the Groups/Containers as they exist in LDAP.
.net 3.5 is being used (mix of asp.net webforms and asp.net mvc)
Has to work in ASP.NET and ASP.NET MVC (shouldn't be a problem I'm guessing)
This can't be user centric, administrators need to be the only ones that CRUD (or import via ldap) users and groups
We have to be able to Auth via LDAP when its configured to do so
I always try to monitor my questions closely so feel free to ask for more info. Also, as a general summary of what I'm looking for in an answer is just. "You should/shouldn't use xyz, here's why".
Links regarding asp.net membership provider and role management stuff are very welcome, most of the stuff I'm finding is 5+ years old.
Security in the context of your problem involves two separate operations: authentication and authorization and those are divided in .NET into MembershipProviders and RoleProviders. I would strongly recommend using both (meaning custom or built-in) to do your authentication and authorization. Doing so, provides a path to upgrade should you later find better tools to do the job and makes it easier for other developers to understand the security.
Now, for authentication, I would, as others have stated, use either the SqlMembershipProvider or the ActiveDirectoryMembershipProvider. My experience has been that in 99% of the cases the ActiveDirectoryMembershipProvider provides enough functionalty for what is need when working against a full AD store (i.e. not ADAM aka ActiveDirectory Application Mode). I have had problems with the ActiveDirectoryMembershipProvider in multi-domain situations but in general finding a way of using it rather than rolling your own is much better. Similarly, the SqlMembershipProvider for authentication, works well and scales well.
Authorization however is an entirely different kettle of fish. This is really where your pain will be felt. First, there is no "ActiveDirectoryRoleProvider". That means if you want to integrate with AD groups, you have three choices:
Use AzMan
Do it yourself via a custom RoleProvider
Find someone that has done it for you.
Use ADFS or Microsoft's new Federated Services
Choice 1: AzMan
AzMan (Authorization Manager) (See also Windows Authorization Manager) is a tool Microsoft wrote to manage application authorization. AzMan has some nice features to it:
It can link your roles to AD groups (or Windows groups)
It can be stored as a file so you can keep it with the application.
Nicely breaks up authorization into tasks, operations and roles.
Comes with a separate administrative tool
The 2008 version will interact with SQL authentication stores.
The catch is that AzMan can be a bear to develop against and understanding the tool is not for someone that isn't experienced. I found that documentation was scant but that was a few years ago. In addition, the AuthorizationStoreRoleProvider does not support Tasks even though AzMan itself does. Tasks are the most granular things that can be done and are group into Operations which themselves can be grouped into Roles into which users or AD groups can be dropped. Documentation has gotten a little better. I do know that when I last worked with AzMan, it's lack of inherit interaction with a database authentication store made it a bit of a pain to work with.
Choice 2: Write your own RoleProvider
This can be a painful experience with LDAP. You would only need a custom RoleProvider in the case where you wanted to query against AD groups and did not want to use AzMan if you planned on using the SqlRoleProvider in non-AD environments.
Another alternative which I have used, is to manage roles in the database and allow the MembershipProvider to be whatever it wants. This still entails writing a custom provider (but a significantly simpler one) and it makes it easy to move the application into an AD environment with little mess. If you store roles in the database and if you want to allow administrators to associate multiple levels of groups to your roles, then you'll have to write that into your custom RoleProvider.
If you plan on using the SqlRoleProvider you also can run into a few issues. If you use the SqlRoleProvider with the SqlMemberProvider in a single application environment then it will work quite well and is very easy to setup. However, if you have multiple applications that you want to authenticate against a single store, then the SqlRoleProvider will not work properly in all cases out of the box without modification.
Choice 3: Find someone that has done it for you.
Specifically, I mean find someone that has developed an ActiveDirectoryRoleProvider. You can easily Google for various choices but I have not used them and would want to pour over any code that anything to do with security in my application.
Choice 4: Active Directory Federated Services
Microsoft has really been pushing this solution which does promise single sign-on if you can get it working. The catch to this solution is getting it setup especially between you and a partner.
I have been very please with the ease of the Membership Provider and Role Provider classes. They just work. The best part in my opinion, is that for my local development, I'm using a SQL Provider to logon to the local database which has the same user names as some of the people I want to test as (Admin, advanced user, basic user) with generic passwords. Then, when I publish my application, it uses the ActiveDirectory Membership Provider and integrates seamlessly. I don't have to change one piece of code for access restrictions. (Except for the differences between my web.config files)
With your situation, it does seem best to write your own custom provider, simply because you want to discover the user in your database but compare their password to LDAP. Also, these seamlessly integrate with both Webforms and MVC.
I would recommend Scott Mitchell's Multipart Series on the providers. Very extensive and thorough.
Also I would add that just because some of the articles are old, doesn't meant they don't still apply. The membership provider framework has been out for a number of years now, so it makes sense that some of the articles are gathering Ethernet dust.
I'm dealing with some of this same stuff so I'm going to start this answer with just a little bit and hopefully build onto it over time.
A quick answer is that, given your requirements, I'm going to suggest that you might want to research the TWO built-in providers that Microsoft makes available to you: SQL Server-based and Active Directory-based. Out of the box, with just the flip of some configuration in your .config file, you can flip the switch from using SQL Server to using Active Directory. Unless I'm misunderstanding your needs, it may sound like this is exactly what you need in your two scenarios. If you do it this way, 100% of your application can look and function identically, even with the same codebase. Migrating data from an existing application of one deployment to the other gets more interesting (and I have no experience with that, unfortunately), but clean deployments of one versus the other should be pretty simple.
Now obviously, if you don't like the behavior of the built-in providers, you can create your own.
Where I am at in my work is that we have been using the SQL-based provider and we need to move to Active Directory and the built-in provider may or may not be sufficient for our needs (I am still evaluating that, and very active in doing so at the moment). I have also worked with some proof-of-concept code so that, in the case that we need to, I have confidence that we can create our own provider reasonably well.
So I know that this is not exactly an answer to your question(s) but I hope that this gives you something to think about for now and helps you in some way. Like I said, I'm happy to add more to this as I grow in knowledge here myself.
FYI material
[How Do I:] Create a Custom Membership Provider? - Video Tutorial from ASP.Net official site. A very nice introduction into the topic.
Simple LDAP Membership Provider - Forum post of a very simple LDAP membership provider.
GPL .Net LDAP Membership Provider - It's GPL, so it may not work for commercial applications. Also hasn't been worked on in a while. But I guess it's still worth mentioning.
Notes
You may have to fight the clients temptation to use LDAP as a database. Be strong! LDAP can be use for Authentication and even Authorization. But you may eventually need to store a lot more information. The only reasonable way to do this is to map your LDAP uid to a database user table and run off that. Your membership provider can make this transparent to the rest of your project. But the client must understand that although LDAP affords them single sign-on, it's shouldn't be used as a database replacement.
Personally, I would stick to the Membership API but try to write a performant backend. Maybe something of a little caching and automatically maps LDAP users to the database user table on the uid as a key. The nice thing about LDAP is it has quite a bit of support in .Net. You won't have to manage sockets, etc. unless you really want to. Due to this, my LDAP/directory access code is usually under a dozen lines per method easily. And that's often good enough for production.
Just to throw another idea into the ring - have you considered Federated authentication and Claims-based authorization? It looks like it may be a good fit for your scenario. Basically this enables you to decouple the authentication from your application into a federated service provider (think OpenID) that manages authentication and issues a token to your application. There are service providers available that will integrate with LDAP, AD, and other directory standards. ADFS (Active Directory Federation Services, formerly Geneva Server) is one example that links with AD.
When configured appropriately, properties that are associated with an identity, such as group membership, can be passed to your application as a "claim" that is associated with the identity - your application can do what it likes with the claim. The point is that your application can find out which groups a user belongs to, and other properties e.g. email address, by examining the claims that are passed within the token.
The advantage of federated authentication is twofold. First, you can integrate with any directory you like, not just LDAP, as long as there is a provider (or of course you can write your own provider). Second, it keeps authentication out of your application code so you can vary the implementation in the future to support different scenarios.
Check out http://msdn.microsoft.com/en-us/magazine/ee335707.aspx for an introduction to the Windows Identity Foundation (formerly code-named 'Geneva Framework'). Or check out the team blog.

Categories

Resources