I am using LDAP for User Authentication in MVC.My code goes below as follows:
public ActionResult Login(LoginViewModel model, string returnUrl)
{
bool validation;
try
{
LdapConnection ldc = new LdapConnection(new LdapDirectoryIdentifier((string)null, false, false));
NetworkCredential nc = new NetworkCredential(model.UserName, model.Password, "XXXXXXX");
ldc.Credential = nc;
ldc.AuthType = AuthType.Negotiate;
ldc.Bind(nc); // user has authenticated at this point, as the credentials were used to login to the dc.
validation = true;
return RedirectToAction("Index", "Home");
//validation = true;
}
catch (LdapException)
{
validation = false;
}
return View(model);
}
but i am getting an error as "LDAP server not available"
Web.Config:
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="10"/>
</authentication>
<membership defaultProvider="AspNetActiveDirectoryMembershipProvider">
<providers>
<clear />
<add name="AspNetActiveDirectoryMembershipProvider"
type="System.Web.Security.ActiveDirectoryMembershipProvider,System.Web, Version=2.0.0.0,Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="ADConnectionString"
attributeMapUsername="sAMAccountName" />
</providers>
</membership>
<add name="ADConnectionString" connectionString="LDAP://XXXXXXX:389/DC=XXXX,DC=XXXX" />
You did not set the path to the LDAP server (currently it is null)
LdapConnection ldc = new LdapConnection(
new LdapDirectoryIdentifier((string)null, false, false)
);
To debug, get rid of try..catch and see where exactly the error comes from. You might need to verify the path with your network administrator or use any tool like LDAP Browser where you could see if path and credentials would work.
Also, make sure that the way you want to authenticate is correct. If this is an intranet application then it might be that you could setup integrated Windows authentication which will not require any custom login process and can be configured on IIS.
Related
I am using SignalR on a Asp.net Web Api project.
I am connecting to the hubs from separate Asp.net MVC projects.
Everything works fine until now.
However, i need to implement Authentication on the SignalR Hubs, in order to do this, i simply need a token to be send as QueryString parameter:
// Hub implementation on Asp.Net Web Api project
public class AppHub : Hub
{
public override async Task OnConnected()
{
string token = Context.QueryString["token"];
var validateResult = ValidateRequestService.ValidateToken(token);
Groups.Add(Context.ConnectionId, validateResult.UserName);
base.OnConnected();
}
}
// Javascript implementation on Asp.net MVC project
$.connection.hub.url = 'http://webApiProject.com/signalr';
$.connection.hub.qs = { 'token': '#(ViewBag.SessionToken)' };
This works.
The problem is that i store sensitive information (token) on the client (browser). If a hacker inspects the source code of the page, it can easily see the token key.
Is there any way to encrypt / decrypt the query string parameter so it will be encrypted on the client side?
I can easily encrypt it on the client, but the problem is that it will be sent encrypted to the Web Api server as well.
Would an HttpModule work in this case?
To implement a custom memebership provider implement System.Web.Security.MembershipProvider
Example from one of my projects
public class MembershipProvider : System.Web.Security.MembershipProvider
{
...
public override bool ValidateUser(string username, string password)
{
return DependencyResolver.Current.GetService<IUserManager>().ValidateUser(username, password);
}
}
If you need roles implement role provider System.Web.Security.RoleProvider
public class RoleProvider : System.Web.Security.RoleProvider
{
...
public override string[] GetRolesForUser(string username)
{
var user = dependencyResolver.Current.GetService<IUserManager>().GetUserBy(username);
return user.Roles.Select(r => r.Name).ToArray();
}
}
All other methods can be left unimplemented for basic functionality
In the web config do
<membership defaultProvider="MyProvider" userIsOnlineTimeWindow="20">
<providers>
<remove name="AspNetSqlProvider" />
<add name="MyProvider" type="MyApp.Web.Common.Membership.MembershipProvider" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" passwordFormat="Hashed" applicationName="/" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="MyRoleProvider">
<providers>
<clear />
<add name="MyRoleProvider" applicationName="/" type="MyApp.Web.Common.Membership.RoleProvider" />
</providers>
</roleManager>
You can then login like Forms auth was enabled for example
[HttpPost]
public bool Login([FromBody]CredentialsViewModel credentials)
{
if (Membership.ValidateUser(credentials.Username, credentials.Password))
{
FormsAuthentication.SetAuthCookie(credentials.Username, credentials.Remember);
return true;
}
return false;
}
In MVC4 application I pointed Simple Membership provider to MongoDB Connection. But it is throwing error with connection string.
Here is my code
Web.config
<add name="DefaultConnection" connectionString="server=127.0.0.1;database=user" />
<membership defaultProvider="DefaultMembershipProvider">
<providers>
<add name="DefaultMembershipProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData" connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="DefaultRoleProvider">
<providers>
<add name="DefaultRoleProvider" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData" connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</roleManager>
Global.asax
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "Users", "Id", "Username", autoCreateTables: true);
SimpleMembershipProvider
public class SimpleMongoMembershipProvider : SimpleMembershipProvider
{
public override string CreateAccount(string userName, string password)
{
WebSecurity.CreateUserAndAccount(userName,password, new { Gender = "Mal", DOB = DateTime.Now.AddYears(-1), Email = "mymy#trtr.com" });
return base.CreateAccount(userName, password);
}
}
Account Controller
public class AccountController : Controller
{
public ActionResult Index()
{
var db = new SimpleMongoMembershipProvider();
db.CreateAccount("admin", "admin");
return View();
}
}
Any ideas? Any other step needs to be followed to point MongoDB as Connection
You don't appear to be authenticating or passing credentials to Mongo DB, you need to authenticate to the Mongo DB database, there are several different ways to do this depending on your usage, use the instructions outlined here:
http://docs.mongodb.org/ecosystem/tutorial/authenticate-with-csharp-driver/
I'm using the AD Membership provider to validate user names and am having issues getting anything other than user#upnDomain.com to work.
Is it possible to get the other username formats to work?
Code
MembershipProvider domainProvider;
domainProvider = Membership.Providers["MyADMembershipProvider"];
if (domainProvider.ValidateUser("zzTest123", "pass"))
{
}
if (domainProvider.ValidateUser(#"PARTNERSGROUP\zzTest123", "pass"))
{
}
if (domainProvider.ValidateUser("zzTest123#company.com", "pass"))
{
}
if (domainProvider.ValidateUser("zzTest123#testfirm.com", "pass"))
{
// this is the UPN and the only one that works.
}
Web.config
<authentication mode="Forms">
<forms loginUrl="~/Account/Login.aspx" name=".ADAuthCookie" timeout="10" />
</authentication>
<membership>
<providers>
<add name="MyADMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="TestDomain1ConnectionString" />
</providers>
</membership>
Based on my testing the Membership provider only works with the UPN. To implement support for other types, override ActiveDirectoryMembershipProvider's ValidateUser function and add some variation of the following:
//
// Will validate UPN, shortname only, or domain prefixed (domain\user)
public bool IsAuthenticated( string usr, string pwd)
{
bool authenticated = false;
DirectorySearcher dseSearcher=null;
DirectoryEntry entry = null;
try
{
dseSearcher = new DirectorySearcher();
string rootDSE = dseSearcher.SearchRoot.Path;
entry = new DirectoryEntry(rootDSE, usr, pwd);
object nativeObject = entry.NativeObject;
authenticated = true;
}
catch (DirectoryServicesCOMException cex)
{
//not authenticated; reason why is in cex
}
catch (Exception ex)
{
//not authenticated due to some other exception [this is optional]
}
finally
{
dseSearcher.Dispose();
entry.Dispose();
}
return authenticated;
}
Be aware that the System.DirectoryServices.AccountManagement namespace will only validate the shortname, the UPN, but doesn't appear to validate DOMAIN\Username accounts.
The following code will throw an exception if a username is passed in DOMAIN\Username format
"LdapException: A local error occurred."
var ctx = new PrincipalContext(ContextType.Domain);
if (ctx.ValidateCredentials(username,password , ContextOptions.Negotiate))
{
}
Please help me for this issue.
I have used asp .net membership. while creating new user using asp .net membership using below code. i am getting membership provoder error. can anyone tell me the solution for
this.
MembershipCreateStatus status;
//MembershipUser u = Membership.CreateUser(username, password, email, question,
// answer, true, out status);
MembershipUser u = Membership.CreateUser(username, password, email, question,
answer, true, out status);
if (u == null)
{
throw new MembershipCreateUserException(GetErrorMessage(status));
}
return u;
i have properly set web.config file. please tell me if i am missing anything. here is my web.config file membeship tag. and my database is mysql :
add name="MySQLMembershipProvider"
enablePasswordRetrieval="true"
autogenerateschema="false"
type="MySql.Web.Security.MySQLMembershipProvider, MySql.Web, Version=6.3.5.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"
connectionStringName="LocalMySqlServer"
applicationName="/"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
requiresUniqueEmail="true"
passwordFormat="Clear"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="7"
minRequiredNonalphanumericCharacters="1"
passwordAttemptWindow="10"
passwordStrengthRegularExpression=""
writeExceptionsToEventLog="false"
This is my error :MembershipCreateStatus.ProviderError
MembershipCreateStatus status;
Membership.CreateUser(username, password, email, question,
answer, true, out status);
if (status == MembershipCreateStatus.Success)
{
FormsAuthentication.SetAuthCookie(username, false);
// Redirect to page
}
else
{
//get the error message here
return ErrorCodeToString(createStatus);
}
// if you get to here, throw an exception!
private static string ErrorCodeToString(MembershipCreateStatus createStatus)
{
// See http://go.microsoft.com/fwlink/?LinkID=177550 for
// a full list of status codes.
switch (createStatus)
{
case MembershipCreateStatus.DuplicateUserName:
return "User name already exists. Please enter a different user name.";
//add the rest of the error codes here....
I created a custom membership provider and am getting the following error trying to create a new "MembershipUser".
Could not load type 'MyTestApp.Membership.TestMembershipProvider' from assembly 'System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
I am running this from a Unit Test project, so I'm not sure if that's causing the issue, but I did include System.Web, System.Web.ApplicationServices as well as a reference to MyApp.Membership and MyApp.DataModels (Entity objects).
The error happens inside my "GetUser" function which is below, my configuration is also below.
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
{
try
{
AccountEntities db = new AccountEntities();
if ((providerUserKey is Guid) == false)
{
return null;
}
User user = (from u in db.Users
where u.UserId == (Guid)providerUserKey
&& u.Application.LoweredApplicationName == this.ApplicationName.ToLower()
select u).FirstOrDefault();
if (user != null)
{ // ERROR: Starts here, user object is correct, data is all there.
return new MembershipUser(this.ProviderName, user.UserName, (object)user.UserId, user.Email, user.PasswordQuestion, user.Comment, user.IsApproved, user.IsLockedOut, user.CreateDate, user.LastLoginDate, user.LastActivityDate, user.LastPasswordChangedDate, user.LastLockoutDate);
}
else
return null;
}
catch (Exception ex)
{
this.WriteToEventLog(ex, "Unable to get user from object '{" + ((Guid)providerUserKey).ToString() + "}'.", "Get User");
return null;
}
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="AccountEntities" connectionString="metadata=res://*/Account.AccountDataModel.csdl|res://*/Account.AccountDataModel.ssdl|res://*/Account.AccountDataModel.msl;provider=System.Data.SqlClient;provider connection string='Data Source="EDITED";Initial Catalog=CustomAuthentication;Persist Security Info=True;User ID=EDITED;Password=EDITED;MultipleActiveResultSets=True'" providerName="System.Data.EntityClient" />
</connectionStrings>
<system.web>
<membership defaultProvider="TestMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
<clear/>
<add name="TestMembershipProvider" type="MyTestApp.Membership.TestMembershipProvider"
applicationName="/"
description="Membership Test"
enablePasswordReset="true"
enablePasswordRetrieval="true"
maxInvalidPasswordAttempts="3"
minRequiredNonAlphanumericCharacters="8"
minRequiredPasswordLength="8"
passwordAttemptWindow="30"
requiresQuestionAndAnswer="true"
requiresUniqueEmail="true" />
</providers>
</membership>
</system.web>
</configuration>
I just noticed I missed the below part in the configuration
type="MyTestApp.Membership.TestMembershipProvider, MyTestApp.Membership"
Works now!