MVC3 authorization using AD - asp.net

Is it possible to authorise/deny users of an MVC3 application using AD?
My app is secured using Windows authentication at the moment, but that means adding users to groups on the Win2007 server.
I'd like to change that so that users were allowed/denied access to the appliction/and controller actions/view based upon their AD roles instead, so they either auto-logged in (like Windows auth) or they get redirected to a "denied" page.
Any help very gratefully accepted...everything I find seems to be based upon Windows groups, or forms authentication.

You could use the Roles property:
[Authorize(Roles = #"SOMEDOMAIN\somegroup")]
public ActionResult Foo()
{
...
}
Here's a tutorial which explains the steps.

I'm using AD Groups for my intranet app.
<authentication mode="Windows" />
<roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider">
<providers>
<clear />
<add applicationName="/" name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</roleManager>
then just added Authorization attributes to my controller actions that I needed to secure:
[Authorize(Roles = MyNamesspace.Constants.MANAGER_GROUP)]
public ActionResult Blah() {...
And in a view you can use User.IsInRole and the name of their AD/Windows group.
Or get a list of the roles the webserver sees from that user: System.Web.Security.Roles.GetRolesForUser();
Caveat: my server and my clients are all on the same domain. this won't work if you need to do the same for web clients off site against your ActiveDirectory.

Just use the Membership provider framework that comes built-in to Asp.net. You will find that there is already an ActiveDirectoryMembershipProvider out of the box, but you will have to implement the RoleProvider yourself, as membership can be defined different ways in different networks.

Related

ASP.NET Profile Properties returning another users results

I am using ASP.NET profile properties in .NET framework 2.0 application.
Hosting: On Amanzon server
Operating System: Windows Server 2012
Sql Server : 2012
IIS: 8.5
Profile Properties are anonymous users
What is happening with the end users (not able to replicate myself) that the end users are seeing the profile properties of another user
Example Say i have country USA set in my profile property
Next time i visit the webpage it may show some another Country which may be set by another user.
In IIS currently User Mode caching and Kerner Mode Caching enable.
Additionally:
I recently change the hosting means moved to another server so is that anything to do
with properties of anonymous users or do i need to clean all of the current profile users
data which i am scare of
Code:
<profile enabled="true" defaultProvider="AspNetSqlProfileProvider">
<properties>
<add name="ActionRemember" allowAnonymous="true" />
<add name="ActionName" allowAnonymous="true" />
/// huge list of properties .......
</properties>
<providers>
<remove name="AspNetSqlProfileProvider" />
<add name="AspNetSqlProfileProvider" connectionStringName="LocalSql2005Server" applicationName="/" type="System.Web.Profile.SqlProfileProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</profile>
Open to give you more details..
Update: I disabled Kernel Caching for the aspx page and the error still persists
Static variables retain their values across user sessions.
You will run in concurrency issues as more than one thread servicing a request can modify the value of the variable.
What happens if there are 2 users simultaneously logged in from two
computers, User 1 sets the value as 100, then User 2 sets the value as
200. after that user 1 invokes the Get Value button.
What will he see as the value?
The user will see 200 afterwards.
I added a link for additional information here

ASP.Net -- How to do both Forms and Windows Authentication in IIS 7 and higher?

I have an existing Asp.Net 4.0 web application that uses forms authentication. I want to add Windows authentication for domain users. I have read several articles and tried a few different approaches, but have met with various problems.
Here are the best 2 examples I have found that are relevant to IIS 7 and higher.
http://mvolo.com/iis-70-twolevel-authentication-with-forms-authentication-and-windows-authentication/
and
http://devmemass.blogspot.com/2012/02/mixing-forms-and-windows-authentication.html
The short story is that neither of these approaches have worked for me. Does anyone have a better (and especially more thorough) example?
I really only need NTLM / Kerberos authentication handled. I don't want passwords passed in clear text for domain users. I would like IIS to handle the Windows authentication part, then allow me to redirect them to the default page.
I have done this successfully with my applications. If you want to use have the sign on with Windows Authentication, it's pretty easy. If you want to be able to use your Active Directory groups, it's a little more difficult. To just use Forms Authentication with AD you will need the following in your webconfig...
<connectionString>
<add name="ADService" connectionString="LDAP://domain/OU=ougroup,DC=domain,DC=net" />
</connectionString>
Then you will need Membership provider.
<membership defaultProvider="AspNetActiveDirectoryMembershipProvider">
<providers>
<clear />
<!--Membership provider for Active Directory-->
<add name="AspNetActiveDirectoryMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ADService" attributeMapUsername="sAMAccountName" />
</providers>
</membership>
This should do it for you.
If you want to be able to use your AD groups, you will need to create your own RoleProvider.
I used this link here.
However, I did have to change the GetRolesForUser to..
public override string[] GetRolesForUser(string username)
{
List<string> allRoles = new List<string>();
var ctx = new PrincipalContext(ContextType.Domain, "jwaf-dc2.jeffwyler.net");
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, username);
if (user != null)
{
var groups = user.GetGroups();
allRoles.AddRange(groups.Select(x => x.Name));
}
return allRoles.ToArray();
}
I hope this helps get you started.

Is correct this code in web.config for set custom membership

I want use custom membership and custom role providers. I have this classes:
public class CustomRoleProvider : RoleProvider
{
//override methods
}
public class CustomMembershipProvider : MembershipProvider
{
//override methods
}
I want set web.config, Is correct this code?
<membership defaultProvider="CustomMembershipProvider">
<providers>
<clear />
<add name="CustomMembershipProvider" type="Login1.Code.CustomMembershipProvider, Login1, Version=1.0.0.0, Culture=neutral" connectionStringName="LoginDB1Entities" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="CustomRoleProvider">
<providers>
<clear />
<add name="CustomRoleProvider" type="Login1.Code.CustomRoleProvider" connectionStringName="LoginDB1Entities" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" writeExceptionsToEventLog="false" />
</providers>
</roleManager>
Because when I go to the ASP.NET Configuration, and Security tab, but get this message:
There is a problem with your selected data store. This can be caused by an invalid server name or credentials, or by insufficient permission. It can also be caused by the role manager feature not being enabled. Click the button below to be redirected to a page where you can choose a new data store.
The following message may help in diagnosing the problem: The method or operation is not implemented.
Issue here seems to be originating from your connectionStringName property.
make sure you define/add the connection string in your Web.config's <connectionStrings> section
<connectionStrings>
<add name="LoginDB1Entities" ... />
</connectionStrings>
Also, if you ahve added already as above, then make sure you are using the correct settings.
First check where exactly your database is? Find out which instance of the SQL Server is the database of your application using. Modify the connection string to point to that instance.
The method or operation is not implemented
This is the message get if you throw NotImplementedException without any arguments.
The most obvious reason is that one of your custom providers has not implemented one of the expected methods. If you can get a stack trace, you'll see which one.
UPDATE in response to comment:
my custom membership is working in site
The membership and role providers contain methods for two purposes:
Methods needed at runtime for authentication (MembershipProvider) and authorization (RoleProvider). For example, at runtime a RoleProvider only uses the methods IsUserInRole and GetRolesForUser.
Methods needed to manage users (MembershipProvider), and roles / role membership (RoleProvider). These methods are needed if you want to manage your provider's data store using the ASP.NET Configuration and Security tab.
It's perfectly valid to create a provider that only provides the runtime functionality - a so-called "readonly" provider, in which case you'll have to provide some other outside mechanism for managing the provider's data store. For example, WindowsTokenRoleProvider is a readonly provider. But if you do this, you won't be able to manage your provider store using the ASP.NET Configuration and Security tab.
It appears you have failed to implement one or more of the management methods, and instead are throwing NotImplementedException.
Incidentally, NotImplementedException is not the best exception to throw for unsupported methods in a readonly provider. It should only normally used to indicate a method has not yet been implemented in a version under development.
If you don't ever intend to implement the method, it's better to throw NotSupportedException - or in the case of a provider, perhaps a ProviderException.

ASP.NET Membership.CreateUser appears to create multiple user records

Bottom Line Up Front
Should I be seeing multiple user records in aspnet_Users for each user mapping to each of the applications specified in the aspnet_Applications table?
The Situation
I have a web application using ASP.NET forms security. Having created a number of users, I decided to take a look in the AspApplicationServices database which is specified as my provider. In the aspnet_Applications table there are two application records ("/", and "/MyAppNameHere") each with its unique application id.
In the aspnet_Users table, I noticed that I have twice as many users as I expected. One each for both applications (i.e. each user has a record specifying the ID of the "/" and "/MyAppNameHere" application records).
Is this the way it is supposed to work? I have looked about and have found no mention of this activity, or whether it is by design and what it might be for. If it is by design I have to conclude that any changes in user information will be propagated to all of the matching user recods, not just the "root" or the other.
Note: These users were created both through the application (using Membership.Create()) and through the configuration mini-app (Security->Create User).
web.config
<roleManager enabled="true">
<providers>
<clear />
<add applicationName="/" name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" />
<add applicationName="/" name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" />
</providers>
</roleManager>
The reason is that you have different Application names in your Membership provider and Role manager provider.
You set the application name of your membership provider to "/MyAppNameHere".
Initially you didn't set the application name of your role manager provider. By default it uses the ApplicationVirtualPath as documented in http://msdn.microsoft.com/en-us/library/system.web.security.roleprovider.applicationname.aspx. Usually it is the virtual path of your web site ("/" in many cases).
As a result, when you call Membership.CreateUser(), it creates two records in aspnet_users. One for membership application id and one for role provider's application id. The two records have the same user name but have different user Ids (one for each application id).
The call also creates one record in aspnet_membership table (application id, userid, password etc). the Applicatin id and user id are from the record corresponding to the membership provider's application name, i.e., "/MyAppNameHere".
When you create a user role using call such as Roles.AddUserRole(), it will create a record in aspnet_UsersInRoles that uses the user id corresponding to the application id of role manager provider.
I couldn't find official document but http://weblogs.asp.net/gurusarkar/archive/2010/01/09/asp-net-mebership-creates-two-users-in-aspnet-users-table.aspx has some explanation. This diagram helps understand the table relationships.
You're most likely adding a user with a role, without having the out-of-box RoleProvider properly configured.
If you don't specify an ApplicationName in the roleManager section of the web.config it will create another user with the default application name "/" when you try and create a user.
<system.web>
<roleManager enabled="true">
<providers>
<clear/>
<add name="AspNetSqlRoleProvider"
connectionStringName="[ConnectionStringName]"
applicationName="[ApplicationName]"
type="System.Web.Security.SqlRoleProvider" />
</providers>
</roleManager>
</system.web>
Until asawyer posts an answer with his comments, I will just mark an answer myself.
Looks like the multiple records tie application specific users together. There is a general record created, and an application related record created, presumably to provide continuity between applications.

using AD to authenticate to different domains

So we have been using the same login gode to connect to various domains in asp.net, with and without MVC. The code works.
We have a new server, first one to run server 2008 r2, set up with a directory structure similar to one of the ones that has been working.
Using forms authentication, I set up in the web.config
<add name="ADConnectionString" connectionString="LDAP://10.1.XXX.XXX"/>
and
<!--<authentication mode="Windows" />-->
<membership defaultProvider="MyADMembershipProvider" >
<providers >
<add name="MyADMembershipProvider"
type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="ADConnectionString"
connectionUsername="XXXX\Brown.Eric"
connectionPassword="XXXX"
connectionProtection="None"
/>
</providers>
</membership>
It connects to build the membership provider just fine, but when I tryto use the exact same username and password to login on the forms login page (the stock asp.net stuff) it fails to login.
same user, same password that's being used to connect with the membership provider.
If I change the password in the web.config, I get an error that it's incorrect, so I know that the membership provider is getting connected with those credentials.
What I can't figure out is why can't I use the same credentials to login?
I've checked:
The user is not locked.
the user is not set to change password on next logon.
The user is not expired.
Any help or hints are apprecaited.
Thanks,
Cal-
Figured it out, had indavertantly removed the use SAM Account setting from the above
config, and it was wanting me to use userPrincipalName instead.
Switched it back to sam and all worked as expected.
Cal-

Resources