I am beginner with mvc3 and i and i have created an internet application for which i need to apply windows authentication and check for the user roles in the AD. Is that possible with LDAP? I have searched online but nothing seems clear. Hence, request you guys to assist or post some links which have clear explanation of the procedure to be followed.
Thanks in advance!
It is possible,
Have a look at this URL
Yes it is possible. There are many samples of this online.
In your web.config add the LDAP connection string:
<connectionStrings>
<add name="ADConnectionString" connectionString="LDAP://what ever it is" />
</connectionStrings>
Also add the following:
<authentication mode="Forms">
<forms name=".ADAuthCookie" loginUrl="~/Account/LogOn" timeout="15" slidingExpiration="false" protection="All" />
</authentication>
<membership defaultProvider="ADMembershipProvider">
<providers>
<clear />
<add name="ADMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider" connectionStringName="ADConnectionString" attributeMapUsername="sAMAccountName" />
</providers>
</membership>
The rest should work the same as normal SQL membership:
public ActionResult LogOn()
{
return View();
}
[HttpPost]
public ActionResult LogOn(LogOnViewModel viewModel, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(viewModel.UserName, viewModel.Password))
{
}
}
}
Your LogOnViewModel:
public class LogOnViewModel
{
public string UserName { get; set; }
public string Password { get; set; }
}
I hope this can help you in the right direction.
Related
I use custom membership for Users and Roles in my MVC3 application. I have custom user/roles class. And I have the extended the RoleProvider and MembershipProvider classes for this.
I seem to have a case of roles going missing sometimes in my application and my Authorize [Roles='xyz'] attribute not working correctly and trying to redirect to Account/LogOn. When my user logs into the application, all I do is
if (ModelState.IsValid)
{
if (MyCustomSecurity.Login(model.UserName, model.Password, model.RememberMe))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
--other stuff
}
MyCustomSecurity.Login method basically looks up the user in the database and if valid sends a true value back.
When trying to debug the issue with my application, I came across the links below
http://www.codeproject.com/Articles/578374/AplusBeginner-27splusTutorialplusonplusCustomplusF
ASP.NET MVC Forms Authentication + Authorize Attribute + Simple Roles
Should I also be overriding FormsAuthentication_OnAuthenticate() as mentioned in this link? Or does the RoleProvider extended class take care of this?
Thank You
If you use roles in AuthorizeAttribute, and roles are your own classes, so you need to override RoleProvider, especially method GetRolesForUser:
public class CustomRoleProvider : RoleProvider
{
public override string[] GetRolesForUser(string username)
{
// put your logic to discover which roles the user has
}
}
After doing that, you have to register you CustomRoleProvider in Web.Config:
<roleManager enabled="true" defaultProvider="CustomRoleProvider">
<providers>
<clear/>
<add name="CustomRoleProvider" type="%YOURNAMESPACE%.CustomRoleProvider" />
</providers>
</roleManager>
I am working with ASP.NET Membership Providers. I am using SqlMembership Provider, I have overriden the CreateUser class as shown below.
As you can see I have a SportDetails fields which contains many values, this I want to use in the CreateUser method. How do I pass these values ? since these values are taken from ViewModel. Infact SportDetails is my viewModel for registration page.
public class CustomMembershipProvider : SqlMembershipProvider
{
public SportsDetails SportsDetails { get; set; }
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
{
string.empty
MembershipUser membershipUser = base.CreateUser(username, password, "", null,null, false, null, out status);
// here is where I want to be able to use the value from Sports Details.
return membershipUser;
}
}
and my web.config
<membership defaultProvider="CustomMembershipProvider">
<providers>
<clear/>
<add name="CustomMembershipProvider" type="Service.Security.CustomMembershipProvider" connectionStringName="my_db" requiresQuestionAndAnswer="false" enablePasswordRetrieval="false" enablePasswordReset="true" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="3" minRequiredNonalphanumericCharacters="0" passwordFormat="Clear" passwordAttemptWindow="10" applicationName="myApp" />
</providers>
</membership>
Please help me out on this.
Found the answer the hard way ;)
I used Interface for this.
below is my interface used.
public interface ISportsDetailer{
public SportDetails SportsDetails { get; set; }
}
and then in my custom provider I had this Interface implemented as
public class CustomMembershipProvider : SqlMembershipProvider, ISportsDetailer
{}
and to call CreateUser and pass these values before it, I used
((ISportsDetailer)Membership.Provider).SportsDetails = valueFromModel;
Hope this helps some one in future :)
I have a class MainController and I have applied Authorize attribute to Index method but its not re-directed it to the LogOn page.
[Authorize]
public ActionResult Index()
{
MyBusinessObject obj = new MyBusinessObject(1);
return View(obj );
}
I have following added to web.config
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication
Any ideas what I may be missing?
I'm trying to use a custom role provider in an MVC3 app. I've already got the membership provider working ok using Ninject but can't seem to get the role provider working. The Membership provider doesn't require a parameterless constructor but role provider does. Here's some code snippets:
Web.config
<membership>
<providers>
<clear/>
<add name="MyMembershipProvider" type="MyApp.Models.NHibernateMembershipProvider"
applicationName="myApp" />
</providers>
</membership>
<roleManager enabled="true">
<providers>
<add name="MyRolesProvider" type="MyApp.Models.NHibernateRoleProvider"
applicationName="myApp" />
</providers>
</roleManager>
I have a Ninject module.
public class MyNinjectModule : NinjectModule
{
public override void Load()
{
this.Bind<ISession>().ToMethod(
x => MyApp.MvcApplication.SessionFactoryData.GetCurrentSession());
// Respository
this.Bind<IUserRepository>().To<UserRepository>();
this.Bind<MembershipProvider>().To<NHibernateMembershipProvider>();
this.Bind<RoleProvider>().To<NHibernateRoleProvider>();
}
}
The custom Membership provider
public class NHibernateMembershipProvider : MembershipProvider
{
private IUserRepository _repo;
public NHibernateMembershipProvider(IUserRepository repository)
{
_repo = repository;
}
...
The role provider
public class NHibernateRoleProvider : RoleProvider
{
private IUserRepository _repo;
public NHibernateRoleProvider(IUserRepository repository)
{
_repo = repository;
}
...
I then configure my controller to require an authorize
[Authorize(Roles="Admin")]
public ActionResult Edit(int? id)
{
...
I get this error when starting the app.
Parser Error Message: No parameterless constructor defined for this object.
Source Error:
Line 49: <roleManager enabled="true">
Line 50: <providers>
Line 51: <add name="MyRolesProvider" type="MyApp.Models.NHibernateRoleProvider"
Line 52: applicationName="myApp" />
Line 53: </providers>
I can access the users through the membership provider, so the repository is being injected ok, but the roles provider seems to be different. Why does the role provider require a constructor-less parameter? Is there a simple way to get the role provider to work with Ninject. Any help appreciated.
Since the role provider, in this case the NHibernateRoleProvider is instantiated by the ASP.NET framework the best solution is to use the service locator pattern. The service locator pattern is normally considered to be an anti-pattern but sometimes you have to be pragmatic and accepted the limitation on the framework that is being used (in this case the ASP.NET framework).
Assuming you are using an implementation of the IDependencyResolver interface for Ninject. The following code should work.
public class NHibernateMembershipProvider : MembershipProvider
{
private IUserRepository _repo;
public NHibernateMembershipProvider()
{
_repo = DependencyResolver.Current.GetService<IUserRepository>();
}
// ...
}
Alternatively, if you're using the Ninject.Web.Mvc nuget package you can always use property injection on your role provider as illustrated here:
ASP.NET MVC 3 Ninject Custom Membership and Role Provider
I have created application in mvc3 and I used the default account controller for my users.
I followed instructions from http://www.asp.net/mvc/tutorials/authenticating-users-with-forms-authentication-cs to put all tables (from aspnetdb) in one database.
My trouble is how to set webconfig and connection string corectly?
I set the conn string to my databse but if I try to register Visual studio create aspnetdb and put my user info there.
I am trying to find solution to stop vs creating aspnetdb.
My hosting provider is http://www.inside.hr it is hosting company from Croatia
If your shared hosting environment only allows you to use one database, you can add the ASP.NET Membership database tables to your existing database. Joe Stagner has a walkthrough on how to do that here.
Can you update your question to tell us where you're hosting? That will help.
I'm not sure if I follow you correctly, but did you try something like this:
<connectionStrings>
<add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient" />
<add name="MyDevArmyDB" connectionString="Data Source=DATASOURCE;Initial Catalog=devarmydb;Persist Security Info=True;User ID=USERID;Password=PASSWORDSTRING"
providerName="System.Data.SqlClient" />
</connectionStrings>
DATASOURCE- replace with the address of your database
USERID- replace with the actual user id
PASSWORDSTRING- replace with the actual password
Accessing the DB is done like this:
public class SqlUserRepository : IUserRepository
{
private DataContext dataContext;
private Table<User> usersTable;
public IQueryable<User> Users { get { return usersTable; } }
public SqlUsersRepository(string databaseName)
{
HttpRequestWrapper request = new HttpRequestWrapper(System.Web.HttpContext.Current.Request);
Configuration config = WebConfigurationManager.OpenWebConfiguration(request.ApplicationPath);
dataContext = new DataContext(config.GetConnetionString(databaseName));
}
}
Note that GetConnectionString is an extension function which supports encryption/decryption of the connection string (if you decide to protect the connection string):
public static class ConfigExtension
{
public static string GetConnetionString(this Configuration config, string databaseName, string provider = "RSAProtectedConfigurationProvider")
{
string sectionName = "connectionStrings";
ConfigurationSection section = config.GetSection(sectionName);
if (section != null && !section.SectionInformation.IsProtected)
{
section.SectionInformation.ProtectSection(provider);
config.Save();
}
return WebConfigurationManager.ConnectionStrings[databaseName].ConnectionString;
}
}