I am developing a Web Application using ASP.NET MVC 4 and I create a couple of custom MembershipProvider and RoleProvider like bellow:
# Custom MembershipProviders
<membership defaultProvider="myMembershipProvider">
<providers>
<clear />
<add name="myMembershipProvider" type="WebApp1.Business.Auth.MyMembershipProvider" />
<add name="adminMembershipProvider" type="WebApp1.Business.Auth.AdminMembershipProvider" />
</providers>
</membership>
# Custom RoleProviders
<roleManager enabled="true" defaultProvider="MyRoleProvider">
<providers>
<clear />
<add name="MyRoleProvider" type="WebApp1.Business.Auth.MyRoleProvider" />
<add name="AdminRoleProvider" type="WebApp1.Business.Auth.AdminRoleProvider" />
</providers>
</roleManager>
My intention is to create a custom AuthorizeAttribute called Logon that will use the "myMembershipProvider" and "MyRoleProvider"; and create another one called AdminLogon that will use "adminMembershipProvider" and "AdminRoleProvider".
The reason I am creating two custom AuthorizeAttributes is because I want to separate some methods that get the permissons of each role.
The question is, how can I set dynamically the default MembershipProvider and RoleProviders
inside both custom AuthorizeAttribute.
For example:
// Set the default MembershipProvider as adminMembershipProvider
// Set the default RoleProvidersas as AdminRoleProvider
[AdminLogon(Roles = "Administrador")]
public ActionResult Funcionarios()
{
return View();
}
// Set the default MembershipProvider as myMembershipProvider
// Set the default RoleProvidersas as MyRoleProvider
[Logon(Roles = "Administrador")]
public ActionResult Funcionarios()
{
return View();
}
Related
I am working on an asp.net mvc web application, and I have added the following provider to my asp.net web.config:
<system.web>
<membership>
<providers>
<add name="TestDomain1ADMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider,System.Web, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a,Version=4.0.0.0" connectionStringName="TestDomain1ConnectionString" connectionUsername="ad-domainA.intra\it360ad.user" connectionPassword="$$$$$3" />
</providers>
</membership>
&
<add name="TestDomain1ConnectionString"
connectionString="LDAP://10.211.12.30.ad-domainA.intra/CN=Users,DC=ad-domainA,DC=intra" />
but when the users try to access the application and they enter username and password , this will raise the following exception :
Unable to establish secure connection with the server
So what might be the problem? and also is it right to include my server IP address inside the connection string as I am doing ?
EDIT
I changed my setting to be:
<system.web>
<trust level="Full" originUrl="" />
<membership>
<providers>
<add name="TestDomain1ADMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider,System.Web, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a,Version=4.0.0.0" connectionStringName="TestDomain1ConnectionString" connectionUsername="it360ad.user" connectionPassword="$$$$$" />
</providers>
</membership>
&
<add name="TestDomain1ConnectionString"
connectionString="LDAP://ad-domainA.intra/OU=TM,DC=ad-doaminA,DC=intra" />
but currently the following check
if(domainProvider.ValidateUser(model.UserName, model.Password)
inside the Account controller action method will return
The user name or password provided is incorrect
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
MembershipProvider domainProvider;
domainProvider = Membership.Providers["TestDomain1ADMembershipProvider"];
// Validate the user with the membership system.
if (domainProvider.ValidateUser(model.UserName, model.Password))
{
//code goes here
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(model);
}
Can you advice why the validation will always fail ?
Thanks
Try using this connectionString="LDAP://10.211.12.30:389 />. I had the same problem and I found that I had to remove anything else after :389in the connection string.
I dont know why that is but it worked for me..... Hope this helps
When I try this code it's give this error message
This property cannot be set for anonymous users.
protected void CreateUserWizard1_CreatedUser(object sender, EventArgs e)
{
Roles.AddUserToRole((sender as CreateUserWizard).UserName, "Admin");
Control ctrl = CreateUserWizard1.CreateUserStep.ContentTemplateContainer;
TextBox txtAdminAddress= (TextBox)ctrl.FindControl("txtAdminAddress");
TextBox txtAdminCountry= (TextBox)ctrl.FindControl("txtAdminCountry");
TextBox txtAdminCity= (TextBox)ctrl.FindControl("txtAdminCity");
HttpContext.Current.Profile.GetProfileGroup("AdminGroup").SetPropertyValue("AdminAddress", txtAdminAddress.Text);
HttpContext.Current.Profile.GetProfileGroup("AdminGroup").SetPropertyValue("AdminCountry", txtAdminCountry.Text);
HttpContext.Current.Profile.GetProfileGroup("AdminGroup").SetPropertyValue("AdminCity", txtAdminCity.Text);
HttpContext.Current.Profile.Save();
}
Config:
<profile defaultProvider="AspNetSqlProfileProvider">
<properties>
<group name="AdminGroup">
<add name="AdminAddress" type="System.String"/>
<add name="AdminCountry" type="System.String"/>
<add name="AdminCity" type="System.String"/>
</group>
</properties>
<providers>
<clear/>
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="MyConnectionString" applicationName="/"/>
</providers>
</profile>
After creating the User, You need to fetch the profile of recently created user to start updating values. Since No profile is Loaded, it won't allow to set these values for anonymous users.
string strUsername = (sender as CreateUserWizard).UserName;
ProfileCommon p = Profile.GetProfile(strUsername);
//update the field and save
p.AdminAddress= txtAdminAddress.Text;
p.Save();
The ProfileBase object (provided by the Page.Profile property) includes a useful GetProfile() function that retrieves, by user name, the profile information for a specific user.
GetProfile() returns a ProfileCommon object.
[ Note: The profile properties set in Config file doesn't allow setting values for Anonymous users. If you want to allow this for anonymous users also use:
<add name="AdminAddress" type="System.String" allowAnonymous="true"/>
]
When i created a profile and when i add items it always says not declared in the code behind!!
I tried to change the Framework of the project from Framework 4.0 to Framework 3.5 and it still didn't work.
It says FirstNamep , LastNamep are not declared .
And in the Web.config :
<profile defaultProvider="CustomProfileProvider" enabled="true">
<providers>
</providers>
<!-- Define the properties for Profile... -->
<properties>
<add name="FirstNamep" type="String" />
<add name="LastNamep" type="String" />
</properties>
</profile>
Behind the Code:
Profile.FirstNamep = FirstNameTextBox.Text
Profile.LastNamep = LastNameTextBox.Text
The properties are dynamically generated at runtime, which means you can't access them from code-behind. What you can do is access them from your .ASPX pages using a script block (if that works for you). Like this.
<%# Page Language="C#" %>
<script runat="server">
public void Page_Init()
{
Profile.FirstNamep = "some dood";
}
</script>
<div>Your name is <%= Profile.FirstNamep %></div>
It seems to be sort of "by design" that the Profile is available to .aspx pages, but not to the code behind.
If you've defined the default provider as CustomProfileProvider, then that has to be a class that inherits System.Web.Profile.ProfileProvider. Otherwise, you should use the default SQL profile provider.
<connectionStrings>
<add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient" />
</connectionStrings>
<membership>
<providers>
<clear/>
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/" />
</providers>
How do I access the default SqlProvider in a DAL? I've only ever done this before from webforms.
With the following
using System.Web.Security;
....
SqlRoleProvider roleProvider = new SqlRoleProvider();
string[] roles = roleProvider.GetAllRoles(); //for example to get all role names
EDIT
To configure your application to use the SqlRoleProvider you'll need to add the following under the <system.web> section of your web.config file.
<roleManager enabled="true" defaultProvider="SqlRoleManager">
<providers>
<add name="SqlRoleManager"
type="System.Web.Security.SqlRoleProvider"
connectionStringName="MyConnectionStringName" //change this to the name of your connection string
applicationName="MyApplication" />
</providers>
</roleManager>
I would like to know how I can verify a user's credential against an existing asp.net membership database. The short story is that we want provide single sign on access.
So what I've done is to connect directly to the membership database and tried to run a sql query against the aspnet_Membership table:
private bool CanLogin(string userName, string password)
{
// Check DB to see if the credential is correct
try
{
string passwordHash = FormsAuthentication.HashPasswordForStoringInConfigFile(password, "SHA1");
string sql = string.Format("select 1 from aspnet_Users a inner join aspnet_Membership b on a.UserId = b.UserId and a.applicationid = b.applicationid where a.username = '{0}' and b.password='{1}'", userName.ToLowerInvariant(), passwordHash);
using (SqlConnection sqlConn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString))
using (SqlCommand sqlCmd = new SqlCommand(sql, sqlConn))
{
sqlConn.Open();
int count = sqlCmd.ExecuteNonQuery();
return count == 1;
}
}
catch (Exception ex)
{
return false;
}
}
The problem is the password value, does anyone know how the password it is hashed?
if you have two asp.net apps on the same IIS server, you can do SSO like this. I asked this question and answered it myself.
here
Once you have both apps pointing at your asp_membership database by placing the following in the system.web section of your web config
<authentication mode="Forms" />
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="membership"
applicationName="/"
/>
</providers>
</membership>
<roleManager enabled="true" />
make sure both have the same applicationname property set.
I was using IIS 6 so I configured it to autogenerate a machine key for both applications. Because both of these applications live on the same machine the key would be identical, this is the critical part to making the SSO work. After setting up IIS the following was added to my web.config
<machineKey decryptionKey="AutoGenerate" validation="SHA1" validationKey="AutoGenerate" />
That was all there was to it. Once that was done I could log into app1 and then browse to app2 and keep my security credentials.
The problem is the password value,
does anyone know how the password it
is hashed?
Yes - you do! Check your web.config file for something like this:
<membership defaultProvider="MembershipSqlProvider"
userIsOnlineTimeWindow="15">
<providers>
<add name="MembershipSqlProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web,
Version=1.2.3400.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
PasswordFormat="Hashed" />
</providers>
</membership>
The PasswordFormat is what you are looking for. It can have the following three values:
Clear
Encrypted
Hashed
And, Microsoft sets the default value to Hashed for PasswordFormat.
Why don't check it automatically via System.Web.Security.Membership.ValidateUser() ?
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<membership defaultProvider="MyMembershipProvider">
<providers>
<clear />
<add name="MyMembershipProvider" type="MyApplication.MyMembershipProvider" connectionStringName="MyConnString" />
</providers>
</membership>
</system.web>
</configuration>