Extending ClaimsIdentity in MVC3 - asp.net-mvc

I've got my claims set-up with MVC3 using azure and everything is going well.
What I need to do now is extend the Claims Identity that's in the current thread / http context and add my own information (DOB, Address.. that sort of stuff)
so my question is - where is the best place to do this? any examples would be great..
I presume that when the user is authenticated id then have to go to the DB and pull back the relevant record for the user then add it to the custom Claims Identity object?

Typically you will have a httpmodule that will inspect the cookies and once the FedAuth token is found, you have a hook to build your Claims Principal and identities.
You don't typically need to store the user's entire profile, just useful things that wont typically change that often. I do this inside of an actionfilter.
Here is the code I found that does all of this.
https://github.com/wcpro/ScaffR/tree/master/src/ScaffR.Security/content/CodeTemplates/Scaffolders/ScaffR.Security
You may have to do a little digging but its all there.
Here is the code for the http module
public class ClaimsTransformationHttpModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.PostAuthenticateRequest += context_PostAuthenticateRequest;
}
void context_PostAuthenticateRequest(object sender, EventArgs e)
{
var context = ((HttpApplication) sender).Context;
if (FederatedAuthentication.SessionAuthenticationModule != null &&
FederatedAuthentication.SessionAuthenticationModule.ContainsSessionTokenCookie(context.Request.Cookies))
{
return;
}
var transformer = FederatedAuthentication.FederationConfiguration.IdentityConfiguration.ClaimsAuthenticationManager;
if (transformer != null)
{
var transformedPrincipal = transformer.Authenticate(context.Request.RawUrl, context.User as ClaimsPrincipal);
context.User = transformedPrincipal;
Thread.CurrentPrincipal = transformedPrincipal;
}
}
public void Dispose() { }
}
Here is the Claims Transformer
public partial class ClaimsTransformer : ClaimsAuthenticationManager
{
partial void SetCustomPrincipalClaims(IUserService userService, ref ClaimsPrincipal principal);
public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
{
if (!incomingPrincipal.Identity.IsAuthenticated)
{
return incomingPrincipal;
}
var newPrincipal = Transform(incomingPrincipal);
EstablishSession(newPrincipal);
return newPrincipal;
}
ClaimsPrincipal Transform(ClaimsPrincipal incomingPrincipal)
{
var nameClaim = incomingPrincipal.Identities.First().FindFirst(ClaimTypes.Name);
var userService = DependencyResolver.Current.GetService<IUserService>();
var user = userService.GetByUsername(nameClaim.Value);
var id = new ApplicationIdentity(user);
var principal = new ClaimsPrincipal(id);
SetCustomPrincipalClaims(userService, ref principal);
return principal;
}
private void EstablishSession(ClaimsPrincipal principal)
{
if (HttpContext.Current != null)
{
var sessionToken = new SessionSecurityToken(principal);
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionToken);
}
}
}
Then here is the configuration
<?xml version="1.0" encoding="utf-8"?>
<system.identityModel>
<identityConfiguration>
<claimsAuthenticationManager type="Barbarella.Core.Common.Security.ClaimsTransformer, Barbarella.Core" />
</identityConfiguration>
</system.identityModel>
And this...
<system.identityModel.services>
<federationConfiguration>
<cookieHandler mode="Default" requireSsl="false" />
</federationConfiguration>
</system.identityModel.services>
And this...
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<add name="ClaimsTransformationModule" type="Barbarella.Core.Common.Security.ClaimsTransformationHttpModule, Barbarella.Core" />
<add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</modules>
Dont forget to add your configuration sections
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
Here is my code for the ApplicationIdentity (overrides ClaimsIDentity)... This is the code that answers your question really...
public sealed partial class ApplicationIdentity : ClaimsIdentity
{
partial void SetCustomIdentityClaims(User user);
private readonly User _user;
public ApplicationIdentity(User user) : base("Application")
{
_user = user;
AddClaim(new Claim(ClaimTypes.Name, user.Username));
AddClaim(new Claim(ApplicationClaimTypes.UserId, user.Id.ToString(CultureInfo.InvariantCulture)));
AddClaim(new Claim(ApplicationClaimTypes.FirstName, user.FirstName));
AddClaim(new Claim(ApplicationClaimTypes.LastName, user.LastName));
AddClaim(new Claim("Time", DateTime.Now.ToString()));
SetCustomIdentityClaims(_user);
}
public User User
{
get { return _user; }
}
public int UserId
{
get { return int.Parse(FindFirst(ApplicationClaimTypes.UserId).Value); }
}
public string Username
{
get { return FindFirst(ClaimTypes.Name).Value; }
}
}

Related

WF Unity or another way for IoC/DI

Good evening everyone.
Currently, I'm new person in IoC/DI. I have a Winform project with C#. Please view some codes and help me resolve below issue:
1/ IRepository
namespace Framework.Repositories
{
public interface IRepository<T> : IDisposable where T:class
{
T Get(int id);
IEnumerable<T> GetAll();
IEnumerable<T> Find(Expression<Func<T, bool>> predicate);
}
}
2/ Repository
namespace Framework.Repositories
{
public class Repository<T> : IRepository<T> where T : class
{
private bool _disposed = false;
private static bool _isTransactionStarted;
protected readonly DbContext Context;
private DbContextTransaction _transaction { get; set; }
public Repository(DbContext context)
{
Context = context;
_isTransactionStarted = false;
if (context == null)
throw new NullReferenceException(nameof(context));
if (Context.Set<T>() == null)
throw new NullReferenceException("_context.Set<T>()");
}
public T Get(int id) => Context.Set<T>().Find(id);
public IEnumerable<T> GetAll() => Context.Set<T>().ToList();
public IEnumerable<T> Find(Expression<Func<T, bool>> predicate) => Context.Set<T>().Where(predicate);
}
}
3/ Model
namespace PRO.Model
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
[Table("Employee")]
public partial class Employee
{
[Key]
public long EmpId { get; set; }
[StringLength(15)]
public string Username { get; set; }
public string Password { get; set; }
[StringLength(50)]
public string UserGroup { get; set; }
[Required]
[StringLength(50)]
public string FirstName { get; set; }
[StringLength(50)]
public string LastName { get; set; }
[Required]
[StringLength(1)]
public string EmpStatus { get; set; }
}
}
4/ IEmployeeRepository
namespace PRO.Repositories
{
public interface IEmployeeRepository:IRepository<Employee>
{
Employee UserLogin(string username, string password);
}
}
5/ EmployeeRepository
namespace PRO.Repositories
{
public class EmployeeRepository : Repository<Employee>,IEmployeeRepository
{
public EmployeeRepository(DbContext context) : base(context)
{
}
public Employee UserLogin(string username, string password)
{
try
{
return Find(x=>x.Username == username && x.Password == password && x.EmpStatus == BooleanType.Yes ).FirstOrDefault();
}
catch (Exception ex)
{
throw new RepositoryException(ex);
}
}
public MyDbContext myDbContext => Context as MinhTamHotelDbContext;
}
}
6/ IEmployeeService
namespace PRO.Services
{
public interface IEmployeeService
{
Employee UserLogin(string username, string password);
}
}
7/ EmployeeService
namespace PRO.Services
{
public class EmployeeService : IEmployeeService
{
public IEmployeeRepository EmployeeRepos { get; set; }
public Employee UserLogin(string username, string password)
{
return EmployeeRepos.UserLogin(username, password);
}
}
}
8/ DbContext
namespace PRO.Repositories
{
using System.Data.Entity;
public partial class MyHotelDbContext: DbContext
{
public MyHotelDbContext()
: base("name=MyHotelDbContext")
{
}
public virtual DbSet<Employee> Employees { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//DbContext Here
}
}
}
9/App.config
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration, Version=2.1.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>
<connectionStrings>
<add name="MinhTamHotelDbContext" connectionString="data source=.;initial catalog=WiF;persist security info=True;user id=sa;password=#success#;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
</connectionStrings>
<alias alias="transient" type="Microsoft.Practices.Unity.TransientLifetimeManager, Microsoft.Practices.Unity, Version=2.1.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<alias alias="perResolve" type="Microsoft.Practices.Unity.PerResolveLifetimeManager, Microsoft.Practices.Unity, Version=2.1.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<alias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity, Version=2.1.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<alias alias="AreaRepository" type="PRO.Repositories.AreaRepository, PRO.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="IAreaRepository" type="PRO.Repositories.IAreaRepository, PRO.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="EmployeeRepository" type="PRO.Repositories.EmployeeRepository, PRO.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="IEmployeeRepository" type="PRO.Repositories.IEmployeeRepository, PRO.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="GnrlCodeRepository" type="PRO.Repositories.GnrlCodeRepository, PRO.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="IGnrlCodeRepository" type="PRO.Repositories.IGnrlCodeRepository, PRO.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="AreaService" type="PRO.Services.AreaService, PRO.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="IAreaService" type="PRO.Services.IAreaService, PRO.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="EmployeeService" type="PRO.Services.EmployeeService, PRO.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="IEmployeeService" type="PRO.Services.IEmployeeService, PRO.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="GnrlCodeService" type="PRO.Services.GnrlCodeService, PRO.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="IGnrlCodeService" type="PRO.Services.IGnrlCodeService, PRO.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="IRepository" type="Framework.Repositories.IRepository, Framework.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="Repository" type="Framework.Repositories.Repository, Framework.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<container>
<register type="IAreaRepository" mapTo="AreaRepository">
<lifetime type="perResolve" />
</register>
<register type="IEmployeeRepository" mapTo="EmployeeRepository">
<lifetime type="perResolve" />
</register>
<register type="IGnrlCodeRepository" mapTo="GnrlCodeRepository">
<lifetime type="perResolve" />
</register>
<register type="IEmployeeService" mapTo="EmployeeService">
<property name="EmployeeRepos" dependencyType="IEmployeeRepository" />
<lifetime type="perResolve" />
</register>
<register type="IGnrlCodeService" mapTo="GnrlCodeService">
<property name="GnrlCodeRepos" dependencyType="IGnrlCodeRepository" />
<lifetime type="perResolve" />
</register>
<register type="IAreaService" mapTo="AreaService">
<property name="AreaRepos" dependencyType="IAreaRepository" />
<lifetime type="perResolve" />
</register>
</container>
10/ In my login form
public partial class UserLogin : Form
{
private IEmployeeService _employeeSvr = null;
public IEmployeeService EmployeeSrv
{
get { return _employeeSvr ?? (_employeeSvr = UnityInstanceProvider.CreateInstance<IEmployeeService>()); }
set { _employeeSvr = value; }
}
private void btnLogin_Click(object sender, System.EventArgs e)
{
try
{
this.Cursor = Cursors.WaitCursor;
var employee = EmployeeSrv.UserLogin(txtUsername.Text.TrimEx(), txtPassword.Text.TrimEx());
//MsgBox.ShowInfoMsg(employee.ToJsonObject().ToStringEx());
if (employee != null)
{
Visible = false;
AreaMap.Instance.Show();
}
}
catch (Exception ex)
{
ex.ExceptionHandler();
}
finally
{
this.Cursor = Cursors.Default;
}
}
}
My Error is:
Resolution of the dependency failed, type = "PRO.Services.IEmployeeService", name = "(none)".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The type DbConnection does not have an accessible constructor.
-----------------------------------------------
At the time of the exception, the container was:
Resolving PRO.Services.EmployeeService,(none) (mapped from PRO.Services.IEmployeeService, (none))
Resolving value for property EmployeeService.EmployeeRepos
Resolving PRO.Repositories.EmployeeRepository,(none) (mapped from PRO.Repositories.IEmployeeRepository, (none))
Resolving parameter "context" of constructor PRO.Repositories.EmployeeRepository(System.Data.Entity.DbContext context)
Resolving System.Data.Entity.DbContext,(none)
Resolving parameter "existingConnection" of constructor System.Data.Entity.DbContext(System.Data.Common.DbConnection existingConnection, System.Data.Entity.Infrastructure.DbCompiledModel model, System.Boolean contextOwnsConnection)
Resolving System.Data.Common.DbConnection,(none)
Somebody can help me resolve this problem ?
In case Unity doesn't support multiple inheritance (EmployeeRepository: Repository, IEmployeeRepository), Have another way to replace Unity ?
Thank you so much

MVC4: model backing the 'SisContext' context has changed since the database was created. Consider using Code First Migration to update database

I asked this question before as well but I'm posting it again, hoping may b i can get help
Here it goes
When I try to Login with details that are available in database(SIS) I get this error.
The model backing the 'SisContext' context has changed since the database was created. Consider using Code First Migrations to update the database. Thing is Database(SIS) was manually added using add existing item and not generated automatically and when I click on show all files button on solution explorer after running application, i get new database called`ASPNETDB.mdf`
My SisContext looks like this
public class SisContext : DbContext
{
//protected override void OnModelCreating(DbModelBuilder modelBuilder)
//{
// modelBuilder.Conventions.Remove<System.Data.Entity.Infrastructure.IncludeMetadataConvention>();
//}
public DbSet<User> Users { get; set; }
public DbSet<AspNetUser> AspNetUsers { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<BusinessUnit> BusinessUnits { get; set; }
public DbSet<LicenseHolder> LicenseHolders { get; set; }
public DbSet<License> Licenses { get; set; }
public SisContext():base("SIS")
{
if (HttpContext.Current == null)
{
Database.SetInitializer<SisContext>(null);
}
}
}
I have another class called DataContextInitializer which looks like this
public class DataContextInitializer:DropCreateDatabaseAlways<SisContext>
{
protected override void Seed(SisContext context)
{
WebSecurity.Register("Demo", "123456", "demo#demo.com", true, "Demo", "Demo");
Roles.CreateRole("Admin");
Roles.AddUserToRole("Demo", "Admin");
}
}
In my AccountController the Login method is as follows;
public class AccountController : Controller
{
//
// GET: /Account/
[HttpGet]
public ActionResult Login()
{
return View();
}
[HttpPost]
[AllowAnonymous]
public ActionResult Login(LoginModel model)
{
if(Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
return RedirectToAction("Index", "Home");
}
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(model);
}
public ActionResult Index()
{
return View();
}
}
ValidateUser method that is being used in above Login action is in class CodeFirstMembershipProvider class which inherits from MembershipProvider
public override bool ValidateUser(string username, string password)
{
if (string.IsNullOrEmpty(username))
{
return false;
}
if (string.IsNullOrEmpty(password))
{
return false;
}
using (SisContext Context = new SisContext())
{
AspNetUser User = null;
User = Context.AspNetUsers.FirstOrDefault(Usr => Usr.Username == username);//error mentioned above is shown here
if (User == null)
{
return false;
}
if (!User.IsApproved)
{
return false;
}
if (User.IsLockedOut)
{
return false;
}
String HashedPassword = User.Password;
Boolean VerificationSucceeded = (HashedPassword != null && Crypto.VerifyHashedPassword(HashedPassword, password));
if (VerificationSucceeded)
{
User.PasswordFailuresSinceLastSuccess = 0;
User.LastLoginDate = DateTime.UtcNow;
User.LastActivityDate = DateTime.UtcNow;
}
else
{
int Failures = User.PasswordFailuresSinceLastSuccess;
if (Failures < MaxInvalidPasswordAttempts)
{
User.PasswordFailuresSinceLastSuccess += 1;
User.LastPasswordFailureDate = DateTime.UtcNow;
}
else if (Failures >= MaxInvalidPasswordAttempts)
{
User.LastPasswordFailureDate = DateTime.UtcNow;
User.LastLockoutDate = DateTime.UtcNow;
User.IsLockedOut = true;
}
}
Context.SaveChanges();
if (VerificationSucceeded)
{
return true;
}
else
{
return false;
}
}
}
in my web config I have added my custommembershipProvider
<membership defaultProvider="CodeFirstMembershipProvider">
<providers>
<clear />
<add name="CodeFirstMembershipProvider" type="Sorama.CustomAuthentication.CodeFirstMembershipProvider" connectionStringName="SisContext" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="CodeFirstRoleProvider">
<providers>
<clear />
<add name="CodeFirstRoleProvider" type="Sorama.CustomAuthentication.CodeFirstRoleProvider" connectionStringName="SisContext" />
</providers>
</roleManager>
<!--<httpModules>
<add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
<add name="DomainServiceModule" type="System.ServiceModel.DomainServices.Hosting.DomainServiceHttpModule, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</httpModules>-->
<httpRuntime maxRequestLength="2147483647" executionTimeout="180" />
<httpModules>
<add name="DomainServiceModule" type="System.ServiceModel.DomainServices.Hosting.DomainServiceHttpModule, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</httpModules>
</system.web>
<connectionStrings>
<add name="SISContext" connectionString="Data Source=(LocalDB)\v11.0;attachdbfilename=|DataDirectory|\SIS.mdf;integrated security=True;connect timeout=30;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
</connectionStrings>

IChartStorageHandler implementation, handler does not trigger

I'm trying to implement IChartStorageHandler via .Net4.5/MVC4 application to use on Azure based on http://goo.gl/WAapl
I couldn't be able to hit none of the breakpoints that I set in the class below. So my question is, "is there any trick that I can use to force it"? Thank you!
You may find the details about the parameters at http://msdn.microsoft.com/en-us/library/dd456629.aspx
namespace MvcWebRole1.Codes
{
public class ChartImageHandler : IChartStorageHandler
{
public ChartImageHandler()
{
throw new NotImplementedException();
}
#region IChartStorageHandler Members
public void Delete(string key)
{
throw new NotImplementedException();
}
public bool Exists(string key)
{
throw new NotImplementedException();
}
public byte[] Load(string key)
{
throw new NotImplementedException();
}
public void Save(string key, byte[] data)
{
throw new NotImplementedException();
}
#endregion
}
}
web.config part #1
<appSettings>
<add key="ChartImageHandler" value="handler=MvcWebRole1.Codes.ChartImageHandler, MvcWebRole1; webDevServerUseConfigSettings=false;" />
</appSettings>
web.config part #2
<system.webServer>
<handlers>
<remove name="ChartImageHandler"/>
<add name="ChartImageHandler" path="ChartImg.axd" verb="GET,HEAD,POST" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode" />
</handlers>
</system.webServer>
controller
public ActionResult ChartImage()
{
// get data
string path = HttpContext.Server.MapPath("~/App_Data/Test.csv");
IEnumerable<Bar> data = BarRepository.Get(path);
// generate chart
byte[] chartResult = data.Generator();
// return the chart
return File(chartResult, "image/png");
}
public static class ChartOperations
{
private static Chart _chart1;
public static byte[] Generator(this IEnumerable<Bar> data)
{
// initial variable tasks
_chart1 = new Chart() {DataSource = data.ToList()};
// generate the chart
DoTheHardWork();
// save chart to memory string
var image = new MemoryStream();
_chart1.SaveImage(image);
var result = image.GetBuffer();
return result;
}
}
Can you check if you have any entries for ChartImageHandler under system.web/httpHandlers? If yes, then please remove it.
also, it might not relate to this but in you web.config part #1, shouldn't you mention storage=file; as well so as to make it look like :
<add key="ChartImageHandler" value="storage=file;handler=MvcWebRole1.Codes.ChartImageHandler, MvcWebRole1; webDevServerUseConfigSettings=false;" />
This might be a stupid question to ask but when you are trying to hit a break point in your handler are you actually opening a page that includes ASP.NET Charts? The Chart handler will be hit only when charts are being loaded.
Perhaps you could launch the debugger as soon as your class is created?
public ChartImageHandler()
{
System.Diagnostics.Debugger.Launch();
//throw new NotImplementedException();
}
More at http://msdn.microsoft.com/en-us/library/system.diagnostics.debugger.launch.aspx

Entity Framework: Why SimpleMembership looking for Default Connection

I have explicitly set AccountsContext to use mytestdb as the connection string for SimpleMembership, as below -
public class AccountsContext : DbContext
{
public AccountsContext()
: base("mytestdb")
{
}
}
But Database initialized in following line of code is still looking for DefaultConnection for some reason. Although I have removed reference to DefaultConnection completely from web.config.
public sealed class InitializeSimpleMembershipAttribute : ActionFilterAttribute
{
private static SimpleMembershipInitializer _initializer;
private static object _initializerLock = new object();
private static bool _isInitialized;
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Ensure ASP.NET Simple Membership is initialized only once per app start
LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);
}
}
Here is the Web.config file with commented sections -
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<!--<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />-->
</configSections>
<connectionStrings>
<add name="mytestdb" connectionString="Data Source=(local);Initial Catalog=mytestdb;User ID=****;Password=****" providerName="System.Data.SqlClient" />
<!--<add name="DefaultConnection"
connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-LakshyaMvc-20130205074346;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-***.mdf"
providerName="System.Data.SqlClient" />-->
</connectionStrings>
<!--<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
</entityFramework>-->
Any help in this regard will be much helpful.
Take a look at the SimpleMembershipInitializer private class inside the ~/Filters/InitializeSimpleMembershipAttribute.cs file:
private class SimpleMembershipInitializer
{
public SimpleMembershipInitializer()
{
Database.SetInitializer<UsersContext>(null);
try
{
using (var context = new UsersContext())
{
if (!context.Database.Exists())
{
// Create the SimpleMembership database without Entity Framework migration schema
((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
}
}
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
}
catch (Exception ex)
{
throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex);
}
}
}
Do you notice the following line:
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
That's where it is coming from. By the way if you had looked at the exception stacktrace you got it would have pointed you to this location.
Also in the ~/Models/AccountModel.cs file you might have the following context defined by default:
public class UsersContext : DbContext
{
public UsersContext()
: base("DefaultConnection")
{
}
public DbSet<UserProfile> UserProfiles { get; set; }
}

I can't set up a connection string for ASP.Net MVC v4.0 with standard method of Authentication

Please I need help with this scenario:
I want to use the default ASP Membership/Authentication in my MVC app, connected to a VPN.
In web.config I setup the connection "MyCustomConnection":
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
...
<add name="MyCustomConnection" connectionString="Data Source=172.x.x.y\somewhere;Initial Catalog=The.Main.DB;User ID=sa;Password=sapass;Trusted_Connection=True;Integrated Security=SSPI" providerName="System.Data.SqlClient" />
</connectionStrings>
Then in InitializeSimpleMembershipAttribute I have:
public sealed class InitializeSimpleMembershipAttribute : ActionFilterAttribute
{
private static SimpleMembershipInitializer _initializer;
private static object _initializerLock = new object();
private static bool _isInitialized;
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Ensure ASP.NET Simple Membership is initialized only once per app start
LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);
}
private class SimpleMembershipInitializer
{
public SimpleMembershipInitializer()
{
Database.SetInitializer<UsersContext>(null);
try
{
using (var context = new UsersContext())
{
if (!context.Database.Exists())
{
// Create the SimpleMembership database without Entity Framework migration schema
((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
}
}
WebSecurity.InitializeDatabaseConnection("MyCustomConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
}
catch (Exception ex)
{
throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex);
}
}
}
}
When the debugger hit(After a click in the Login Hyperlink of the Basic Template) WebSecurity.InitializeDatabaseConnection("MyCustomConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true), threw an exception:
Cannot open database "The.Main.DB" requested by the login. The login failed.
Login failed for user 'VPN\MYUSER'.
Additionally in User Context:
public class UsersContext : DbContext
{
public UsersContext()
: base("MyCustomConnection")
{
}
public DbSet<UserProfile> UserProfiles { get; set; }
}
My question is:
Why WebSecurity.InitializeDatabaseConnection("MyCustomConnection",... is trying to connect with the user of vpn and no with 'sa'(and his password 'sapass') as my connection string.
Thanks.
The issue is with the connection string, specifically the use of Trusted_Connection=True;Integrated Security=SSPI for more information, check here: Difference between Integrated Security = True and Integrated Security = SSPI

Resources