Using OAuthWebSecurity for external login and SqlMembershipProvider for internal login - asp.net-mvc-4

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 :)

Related

Is Active Directory authentication used?

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

Umbraco not authenticating against Active Directory

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.

How do I get WebSecurity.Login to work?

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
}

WebSecurity.InitializeDatabaseConnection fails with "The Role Manager feature has not been enabled." when called from console program

I have a MVC4 application using SimpleMembership to authenticate users.
I want to add users from a console program.
The console program that references a class library that has the method that will do the user creation.
It looks like this:
public class UserBuilder
{
private static readonly SimpleMembershipInitializer _membershipInitializer;
private static readonly bool _isInitialized;
private static readonly object _initializerLock = new object();
static UserBuilder()
{
LazyInitializer.EnsureInitialized(ref _membershipInitializer, ref _isInitialized, ref _initializerLock);
}
public void HandleEvent(UserAdded #event)
{
if (!WebSecurity.UserExists("ReportModels"))
{
WebSecurity.CreateUserAndAccount("ReportModels", "ReportModels");
};
}
private class SimpleMembershipInitializer
{
public SimpleMembershipInitializer()
{
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
}
}
}
When I start my console application I get System.Configuration.Provider.ProviderException {"The Role Manager feature has not been enabled."} at the line starting with WebSecurity.InitializeDatabaseConnection.
What do I need to do to accomplish this?
I've tried:
adding the nuget package Microsoft ASP.NET Web Pages 2 Web Data to both the console project and the class library project.
the answers listed in this post: SimpleMembershipProvider not working.
verified the connection string.
verified that the tables are in place in the database.
verified that creating users and authenticating them from the MVC4 project works.
Finally solved it thanks to information found in this blog post: http://insomniacgeek.com/to-call-this-method-the-membership-provider-property-must-be-an-instance-of-extendedmembershipprovider/ and some googling.
In essence I needed to add this to my app.config file:
<system.web>
<profile defaultProvider="SimpleProfileProvider">
<providers>
<add name="SimpleProfileProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData"
connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</profile>
<membership defaultProvider="SimpleMembershipProvider">
<providers>
<add name="SimpleMembershipProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData" />
</providers>
</membership>
<roleManager defaultProvider="SimpleRoleProvider" enabled="true">
<providers>
<add name="SimpleRoleProvider" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData"/>
</providers>
</roleManager>
</system.web>
Please note the enabled="true" on the roleManager element. Without that the same exception will be thrown.

User can successfully log in but log in page shows up instead of redirecting

I have a moved a project from asp.net mvc 2 to asp.net 4 and after a bit of fixing everything seemed to work.
EXCEPT for the parts of the app where you have to authorize. Without authorizing it is possible to view non-authorize pages but as soon as you try to log-in everything goes
bananas. When you log-in you get logged in (you see your name in the log-in partial) but not redirected and prompted to log-in again and you can not reach parts of the
app that is for non-authorized users. Everything works on localhost but not at deployed site.
At first i thought there was a problem with my machinekey and app-pool recykling, so i added one. Still same problem.
I know that MVC uses websecurity instead of membership but i've read that an Membership solution can exist in a mvc 4 project, and i would be glad to use my custom membershipprovider and roleprovider and save some time if it is possible.
Controller:
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (MembershipService.ValidateUser(model.UserName, model.Password))
{
FormsService.SignIn(model.UserName, true);
FormsAuthentication.SetAuthCookie(model.UserName, true);
var role = userRepo.usersInRoles.First(x => x.userMail == model.UserName);
if (role.roleName == "Business")
return RedirectToAction("Start", "Business");
if (role.roleName == "Admin")
return RedirectToAction("Index", "Admin");
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
return View(model);
}
Config settings for Membership & Role
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
<membership defaultProvider="AccountMembershipProvider">
<providers>
<clear />
<add name="AccountMembershipProvider" type="MyApp.UI.Infrastructure.AccountMembershipProvider" applicationName="/" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="RoleMembershipProvider">
<providers>
<clear />
<add name="RoleMembershipProvider" type="MyApp.UI.Infrastructure.RoleMembershipProvider" />