I'm creating an internet site for the follow configuration:
- public website
- users need to authenticate agains active directory
- roles are servered by an 3th party ERP system, also using AD for authentication
What I have done
So I tried to follow this guide (https://our.umbraco.org/wiki/how-tos/membership-providers/active-directory-membership-provider) for the authentication, and wrote a custsom role provider for the ERP roles. I used the built in template for the login form.
The role part works just fine. The authentication does not.
The problem
It seems that Umbraco is still using the UmbracoMembershipProvider. When I create a member in umbraco I can login with the umbraco credentials. When I try any AD accounts it won't authenticate.
I tried to
Change the LDAP connectionstring to use a non existing OU or CN. It gives me errors, so connection to AD is made somewhere in the proces.
I also tried RB.ActiveDirectoryProviders. Same result.
I don't get any exception thrown, just "Invalid username or password". The logs say:
2015-08-19 08:45:20,764 [126] INFO Umbraco.Core.Security.UmbracoMembershipProviderBase - [P6460/T133/D8] Login attempt failed for username nico from IP address ::1, the user does not exist
My best guess I made some configuration error.
So how do I use Active Directory as only MembershipProvider?
Any help is welcome.
My setup:
local box with iis/umbraco/VS2012 running a virtual PC with the AD. I run Umbraco 7.2.8 in Visual Studio/IISExpress. I used the Nuget package of Umbraco.
web.config
<connectionStrings>
<add name="ADConnectionString" connectionString="LDAP://192.168.2.50/dc=XXX,dc=YYY" />
</connectionStrings>
<membership defaultProvider="ADMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
<clear />
<add name="UmbracoMembershipProvider" type="Umbraco.Web.Security.Providers.MembersMembershipProvider, Umbraco" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="4" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true"
requiresQuestionAndAnswer="false" defaultMemberTypeAlias="Member" passwordFormat="Hashed" />
<add name="UsersMembershipProvider" type="Umbraco.Web.Security.Providers.UsersMembershipProvider, Umbraco" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="4" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true"
requiresQuestionAndAnswer="false" passwordFormat="Hashed" />
<add name="ADMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ADConnectionString" connectionUsername="[USER]" connectionPassword="[PASSWORD]"
attributeMapUsername="sAMAccountName" />
</providers>
</membership>
#using (Html.BeginUmbracoForm<UmbLoginController>("HandleLogin"))
{
<fieldset>
<legend>Login</legend>
#Html.ValidationSummary("loginModel", true)
#Html.LabelFor(m => loginModel.Username)
#Html.TextBoxFor(m => loginModel.Username)
#Html.ValidationMessageFor(m => loginModel.Username)
<br />
#Html.LabelFor(m => loginModel.Password)
#Html.PasswordFor(m => loginModel.Password)
#Html.ValidationMessageFor(m => loginModel.Password)
<br />
<button>Login</button>
</fieldset>
}
After hours of searching I finally resolved this. It seems that the UmbLoginController always uses the UmbracoMembershipProvider. This is in my opinion not transparent.
Anyhow, I created a new surface controller like mentioned here and everything works fine now.
Related
I've inherited MVC4 application. It looks like Windows Authentication is used, but I also was told that "Active Directory Authentication" is used for some permissions. I do not see anything in web.config about Active Directory.
In web.config:
<authentication mode="Windows" />
<roleManager defaultProvider="DefaultRoleProvider">
<providers>
<add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=21bf1234ad634e53" connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</roleManager>
In Controller:
[Authorize(Roles = #"ABCD\EFG"), HandleError(ExceptionType = typeof(UnauthorizedAccessException), View = "UnauthorizedUser", Order = 1)]
public class HomeController : Controller
{ .............
}
public ActionResult MyAction()
{
if (!User.IsInRole(#"ABCD\EFG"))
{
// some code
}
//.............
}
Is "Active Directory Authentication" used in this application ?
Thank you
The windows authentication will indeed integrate with Active Directory as long as the application server is on the domain your users are registered in.
The below line in your config file enables such functionality.
<authentication mode="Windows" />
This post might help you get further:
Configure ASP.NET MVC for authentication against AD
In my MVC4 project I have defined connection string to database and have defined it as SqlMembershipProvider, it works fine for local account (Login and register). but in external (facebook) login and in ExternalLoginCallback method I got this error :
"To call this method, the "Membership.Provider" property must be an instance of "ExtendedMembershipProvider"."
Here is membership node in web.config:
<membership defaultProvider="SqlProvider">
<providers>
<clear/>
<add name="SqlProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="DefaultConnection" />
</providers>
</membership>
I got the error here in ExternalLoginCallback method:
if (OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false))
{
return RedirectToLocal(returnUrl);
}
while the result containing all the required information I wanted.
I found some answers on the net such as using WebMatrix.WebData and simpleMembershipProvider, but I do not want to use simpleMembershipProvider.
Any help will be appreciated :)
I've been tasked with rewriting an existing Asp.Net Classic web app in MVC4, using the existing DB and authentication.
The old app still uses the "aspnet_" prefix to its tables. I've modified the new site's web.config to include these providers (copied straight form the old site)
<roleManager enabled="true">
<providers>
<remove name="AspNetSqlRoleProvider" />
<add connectionStringName="LocalSqlServer" applicationName="MyApp" name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<remove name="AspNetWindowsTokenRoleProvider" />
<add applicationName="IOL" name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</roleManager>
<membership defaultProvider="AspNetSqlMembershipProvider">
<providers>
<remove name="AspNetSqlMembershipProvider" />
<add connectionStringName="LocalSqlServer" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" applicationName="MyApp" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<remove name="AspNetAdminMembershipProvider" />
<add connectionStringName="LocalSqlServer" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" applicationName="IOL" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" name="AspNetAdminMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</membership>
In my account controller's login action:
public ActionResult Login(LoginModel model, string returnUrl)
{
var auth = Membership.ValidateUser(model.UserName, model.Password);
if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
{
return RedirectToLocal(returnUrl);
}
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(model);
}
The auth variable is true if I remove the [InitializeSimpleMembership] from the controller, if I add it back, I get an error stating "Cannot convert type 'System.Guid' to 'int'". he Websecurity.Login() method fails both with and without the class attribute.
So in a nutshell, if I remove the simple membership, the forms auth validate user works, but when I inspect the User.Identity.IsAuthenticated object, is says false.
What am I missing? I'm not even sure if I'm implementing this security model correctly, I can't find any information on it.
You cannot use the old membership providers with SimpleMembership (e.g. WebSecurity). You need to use the SimpleMembershipProvider. And you will have to migrate the data from the old table structures to the schema used by SimpleMembership. The only thing you can customize in SimpleMembership tables is the table that contains the user profile information, which you can read about here.
Migrating to MVC4 and SimpleMembership will already put you behind the curve. SimpleMembership has been depreciated for ASP.NET Identity. ASP.NET Identity requires MVC5, which you should migrate to anyway to take advantage of all of the added features as well of the general benefits of keeping your underlying components current. ASP.NET Identity is much more flexible than SimpleMembership (SimpleMembership was designed to be simple and not exactly flexible) and there is even an article that walks you through the steps of migrating SQL Membership to ASP.NET Identity.
I'm trying to get the default login model for MVC4 working, but out of the box, I don't think I'm doing it right. This is the default code:
if (WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
{
return RedirectToLocal(returnUrl);
}
When I build, run and try to log in, I get the following error:
An exception of type 'System.InvalidOperationException' occurred in WebMatrix.WebData.dll but was not handled in user code
Additional information: To call this method, the "Membership.Provider" property must be an instance of "ExtendedMembershipProvider".
I thought it was an issue with my provider resources, but I've installed Entity First Tools 6.0.2, System.web.providers, and Microsoft.aspnet.providers.core and am still getting this issue. I found some indications, it might be because I'm connecting to a SQL database, but I couldn't find a resolution.
Someone indicated I need to use System.Web.Http instead of System.Web.Mvc, but that wasn't it.
This is my connection string:
<add name="DefaultConnection" providerName="System.Data.SqlClient" connectionString="Server=servername;Initial Catalog=mercury;Integrated Security=SSPI" />
This is my profile and membership info:
<profile defaultProvider="DefaultProfileProvider">
<providers>
<add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</profile>
<membership defaultProvider="DefaultMembershipProvider">
<providers>
<add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
I read something else indicating I needed to initialize my SimpleMembershipProvier, but I have a custom initializer built to run from application_start so I an seed my database with data:
Database.SetInitializer<UsersContext>(new DatabaseInitializer());
new UsersContext().UserProfiles.Find(1);
My data initializer has this code to initialize my database:
private void SeedMembership()
{
WebSecurity.InitializeDatabaseConnection("UsersContext", "UserProfile", "UserId", "UserName", autoCreateTables: true);
}
So, I have no idea where to look at next.
There are a few places where things could have gone wrong. For starters I'd downgrade Entity 6 to Entity 5 since EF 6 is made to support MVC which uses the Claims Identity model rather than Simple Membership API. You can go to package manager console and choose the relevant app
Uninstall-Package EntityFramework Version 6.0.2
then
Install-Package EntityFramework version 5.0.0
Hope this gets you going.
You can also wrap the Initializer in a check method
if(!Websecurity.Initialized){
///Initialize Websecurity
}
I have a problem with using [Authorize(Roles = "admin")] attribute.
[Authorize(Roles = "admin")]
public ActionResult GetAllLocations()
{
I am getting the following error
You must call the "WebSecurity.InitializeDatabaseConnection" method
before you call any other method of the "WebSecurity" class. This call
should be placed in an _AppStart.cshtml file in the root of your site.
I have built a MVC 4 application using EF 5 Code first with my own database.
A little background:
I have created a custom membership provider I have inherited from
MembershipProvider
I have look at a lot of questions in this site about this issue, but
didn't found an answer.
In some answers i saw how to disable the membership provider
like this:
<add key="enableSimpleMembership" value="false"/>
<add key="autoFormsAuthentication" value="false"/>
This is how i implemented my custom membership provider
<membership defaultProvider="ATWMembershipProvider">
<providers>
<clear/>
<add name="ATMMembershipProvider" type="AroundTheWorldWeb.Infrastructure.AuthenticationProvider.ATMMembershipProvider"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
equiresUniqueEmail="false"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="6"
minRequiredNonalphanumericCharacters="0"
passwordAttemptWindow="10" applicationName="myApplication" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="AspNetSqlRoleProvider">
<providers>
<remove name="AspNetSqlRoleProvider" />
<add name="AspNetSqlRoleProvider" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<!-- note: WebMatrix registers SimpleRoleProvider with name
'AspNetSqlRoleProvider'. I don't know why but i kept it. -->
</providers>
</roleManager>
I fixed this problem by creating the MVC 4 from template. I think there some DLL's aren't loaded when choosing Empty template. So i have created it from a template and override all the Account's methods And also implemented custom member and role provider