I am using mySQL as ny db and have all the asp membership configuration in place.
I have set additional profile proerties in my web.comfig file as shown below;
<profile defaultProvider="MySQLProfileProvider">
<providers>
<add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
<remove name="MySQLProfileProvider" />
<add name="MySQLProfileProvider" type="MySql.Web.Profile.MySQLProfileProvider, MySql.Web, Version=6.6.3.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" applicationName="/" description="" connectionStringName="LocalMySqlServer" writeExceptionsToEventLog="False" autogenerateschema="True" enableExpireCallback="False" />
</providers>
<properties>
<add name="AccountConfirmationId" type="System.String" />
<add name="FullName" type="System.String" />
<add name="CompanyName" type="System.String" />
<add name="CompanyLocationName" type="System.String" />
</properties>
</profile>
My first question is where are the profile values actually stored? There is no additional columns created in my membership profile table.
Secondly, I am using the method outlined below to store the entered values in the registration process into the profile, from the "Next" button click event.
Protected Sub RegisterUser_NextButtonClick(sender As Object, e As WizardNavigationEventArgs) Handles RegisterUser.NextButtonClick
'set Profile object and give it its property values
Dim userProfile As ProfileCommon = TryCast(ProfileCommon.Create(RegisterUser.UserName), ProfileCommon)
userProfile.AccountConfirmationId = Guid.NewGuid().ToString()
userProfile.SetPropertyValue("FullName", FullName.Text)
userProfile.SetPropertyValue("FullName", CompanyName.Text)
userProfile.SetPropertyValue("FullName", CompanyLocationName.Text)
userProfile.Save()
Session("rolerequest") = ddlRegisterAs.SelectedItem.ToString()
Session("acctconfid") = userProfile.AccountConfirmationId
Session("completename") = FullName.Text
Session("compname") = CompanyName.Text
Session("compnamelocation") = CompanyLocationName.Text
End Sub
I try to retrieve the profile values on my admin user management page with the following method ( triggered by username selection from a dropdownlist)
Protected Sub ddlSiteUsers_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ddlSiteUsers.SelectedIndexChanged
Try
Dim userProfile As ProfileCommon = Profile.GetProfile(ddlSiteUsers.SelectedItem.ToString())
tbProfileUserFullname.Text = userProfile.GetPropertyValue("FullName").ToString()
tbProfileCompany.Text = userProfile.GetPropertyValue("CompanyName").ToString()
tbProfileCompLoc.Text = userProfile.GetPropertyValue("CompanyLocationName").ToString()
Catch ex As Exception
lblSiteUserErrMessage.Text = "User profile not found... " & ex.Message.ToString()
lblSiteUserErrMessage.Visible = True
End Try
End Sub
All values come up as empty strings. Any help appreciated.
I am using a website project not a web application.
To answer your first question, the property names and values are serialized and stored in the existing table columns. See this blog post for more details:
How ASP.NET Profile Properties are serialized in the database using Sql Profile Provider
These are the (auto-generated) columns in the profile table for my web app:
[UserId] [uniqueidentifier] NOT NULL,
[PropertyNames] [nvarchar](4000) NOT NULL,
[PropertyValueStrings] [nvarchar](4000) NOT NULL,
[PropertyValueBinary] [image] NOT NULL,
[LastUpdatedDate] [datetime] NOT NULL,
In short, the profile properties are not directly accessible for querying outside of the Profile provider. For that reason I have seen several recommendations to not use the default Profile provider and instead store User details in a separate UserDetails table. I ended up adding columns directly to the Users table, which has so far worked fine for me, but may not be the best choice for some applications.
Related
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"/>
]
I have a simple create user wizard and custom membership provider which was taken from here
Now I am following this tutorial by scott Mitchell and creating new user using wizard and able to send email by setting Disable create property user to "False" so that whenever user recieves the activation link he needs to click that and verifies his account.
Now the problem is when he creates new user it is working fine and when he tried to login immediately he gets message that he needs to ativate the link first in order to login.
And after registration he gets email and when he clicks the link it gives me error that there is no user in the database.
As you can see below that user gets activation link
When the user tried to click it he gets that he is not found in the database
And if i check in the administration tool If I check the user is available without a tick beside it.
Here is my web.config:
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="HDIConnectionString"
connectionString="Data Source=.\SQLExpress;Integrated Security=True;User Instance=True;AttachDBFilename=|DataDirectory|HDIMembershipProvider.mdf"/>
</connectionStrings>
<system.web>
<roleManager defaultProvider="CustomProvider">
<providers>
<add connectionStringName="HDIConnectionString" name="CustomProvider"
type="System.Web.Security.SqlRoleProvider" />
</providers>
</roleManager>
<membership defaultProvider="HDIMembershipProvider">
<providers>
<clear/>
<add name="HDIMembershipProvider" type="HDI.AspNet.Membership.HDIMembershipProvider" connectionStringName="HDIConnectionString" enablePasswordRetrieval="true" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" passwordFormat="Clear"/>
</providers>
</membership>
<machineKey validationKey="C50B3C89CB21F4F1422FF158A5B42D0E8DB8CB5CDA1742572A487D9401E3400267682B202B746511891C1BAF47F8D25C07F6C39A104696DB51F17C529AD3CABE" decryptionKey="8A9BE8FD67AF6979E7D20198CFEA50DD3D3799C77AF2B72F" validation="SHA1"/>
<authentication mode="Forms">
<forms name=".ASPXFORMSAUTH" loginUrl="Login.aspx" />
</authentication>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
<add assembly="System.Web.Extensions.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
</assemblies>
</compilation>
</system.web>
<appSettings>
<add key="adminEmail" value="noreply#xyz.com"/>
</appSettings>
<system.net>
<mailSettings>
<smtp from="xyz#gmail.com">
<network host="smtp.gmail.com" password="password" port="587" userName="xyz#gmail.com"/>
</smtp>
</mailSettings>
</system.net>
</configuration>
And code behind for createuser.aspx:
Protected Sub CreateUserWizard1_SendingMail(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.MailMessageEventArgs) Handles CreateUserWizard1.SendingMail
Dim userInfo As MembershipUser = Membership.GetUser(CreateUserWizard1.UserName)
'Construct the verification URL
Dim verifyUrl As String = Request.Url.GetLeftPart(UriPartial.Authority) & Page.ResolveUrl("~/Verify.aspx?ID=" & userInfo.ProviderUserKey.ToString())
'Replace <%VerifyUrl%> placeholder with verifyUrl value
e.Message.Body = e.Message.Body.Replace("<%VerifyUrl%>", verifyUrl)
End Sub
Verify Page_Load:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'Make sure that a valid querystring value was passed through
If String.IsNullOrEmpty(Request.QueryString("ID")) OrElse Not Regex.IsMatch(Request.QueryString("ID"), "[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}") Then
InformationLabel.Text = "An invalid ID value was passed in through the querystring."
Else
'ID exists and is kosher, see if this user is already approved
'Get the ID sent in the querystring
Dim userId As Guid = New Guid(Request.QueryString("ID"))
'Get information about the user
Dim userInfo As MembershipUser = Membership.GetUser(userId)
If userInfo Is Nothing Then
'Could not find user!
InformationLabel.Text = "The user account could not be found in the membership database."
Else
'User is valid, approve them
userInfo.IsApproved = True
Membership.UpdateUser(userInfo)
'Display a message
InformationLabel.Text = "Your account has been verified and you can now log into the site."
End If
End If
And here is the database screenshot:
#Tim and Baldy-I have finally got working but not with UserID.I don't know what's wrong with the GUID and I tried it with username and it's working perfectly.
So if any modifications with the GUID please let me know.
You are passing a guid type to the GetUser method of the Membership class.
UPDATE Have tested this now. Passing a GUID does call the correct overload - GetUser(object providerUserKey). So this answer is not relevant.
How can you be sure that this is being inferred to the correct overload at runtime?
GetUser has both string and object single parameter overloads, therefore it would make sense to pass the guid in as an object so you are explicitly stating which overload you want to call.
The framework may be calling ToString() on your guid, which would invoke the overload that looks up the username rather than the provider key.
Not at a computer right now, but it should go like this...
Dim key as new object()
'put the guid in the object type
key = Userid
Dim user = Membership.GetUser(key)
I'm trying to create a routine in my asp.net's main page that will see if the current user is a member of a Windows domain group. The site is hosted in IIS and is visible through our intranet.
GlenFerrieLive listed this code (which I'd like to use) in an earlier post:
UserName = System.Environment.UserName
If Roles.IsUserInRole(UserName, "MyDomain\MyGroup") Then
Dim UserExists As Boolean = True
End If
When trying that code, I got the above-mentioned error. So I plugged in the roleManager tag in my Web.config like so:
<roleManager enabled="true" cacheRolesInCookie="true" defaultProvider="ActiveDirectoryMembershipProvider" cookieName=".ASPXROLES" cookiePath="/" cookieTimeout="480" cookieRequireSSL="false" cookieSlidingExpiration="true" createPersistentCookie="false" cookieProtection="All" />
Problem is, now I'm getting the configuration error 'Default Role Provider could not be found'.
How can I get around this? I just need to see if the current user exists in a specific domain group.
Any help would be greatly appreciated.
Thanks,
Jason
Look into this page:http://msdn.microsoft.com/en-us/library/ff648345.aspx
You need something like this in your webconfig specifying where the default role provider points to
<connectionStrings>
<add name="ADConnectionString"
connectionString=
"LDAP://domain.testing.com/CN=Users,DC=domain,DC=testing,DC=com" />
</connectionStrings>
<system.web>
...
<membership defaultProvider="MembershipADProvider">
<providers>
<add
name="MembershipADProvider"
type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="ADConnectionString"
connectionUsername="<domainName>\administrator"
connectionPassword="password"/>
</providers>
</membership>
...
</system.web>
I ended up using this:
Private Function ValidateActiveDirectoryLogin(ByVal Domain As String, ByVal Username As String, ByVal Password As String) As Boolean
Dim Success As Boolean = False
Dim Entry As New System.DirectoryServices.DirectoryEntry("LDAP://" & Domain, Username, Password)
Dim Searcher As New System.DirectoryServices.DirectorySearcher(Entry)
Searcher.SearchScope = DirectoryServices.SearchScope.OneLevel
Try
Dim Results As System.DirectoryServices.SearchResult = Searcher.FindOne
Success = Not (Results Is Nothing)
Catch
Success = False
End Try
Return Success
End Function
Worked like a charm when this was in my web.config:
<authentication mode="Windows"/>
<roleManager enabled="true" cacheRolesInCookie="true" defaultProvider="AspNetWindowsTokenRoleProvider" cookieName=".ASPXROLES" cookiePath="/" cookieTimeout="480" cookieRequireSSL="false" cookieSlidingExpiration="true" createPersistentCookie="false" cookieProtection="All" />
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>
hai ,
I have added some profile properties to my web.config:
<profile automaticSaveEnabled ="true">
<properties>
<add name="NumVisits" type="System.Int32"/>
<add name="UserName" type="System.String"/>
<add name="Gender" type="bool"/>
<add name="Birthday" type="System.DateTime"/>
</properties>
</profile>
However when I try to access the property in a code behind it does not
exist. The following code does not work (says firstname is not a property):
Profile.Gender
And In the Asp.net Configuration 'Profile tab ' Is not showing.
I have rebuilt the solution. I am using VB.NET(3.5)
Another way to retrieve Profile properties value is like below.
object obj = HttpContext.Current.Profile["PropertyName"]; (C# code).