I have a solution which includes a website and WCF web service. Within the website I need to get the current logged on user and access a property value in their profile which specifies the username of another user (used for web service). I then need to get a property from the web service user profile (not the logged on web site user!).
So far I have this :
if (HttpContext.Current != null)
{
if (!string.IsNullOrEmpty(HttpContext.Current.Profile.UserName))
{
serviceUsername = HttpContext.Current.Profile.GetPropertyValue("WSUserName").ToString();
if (!string.IsNullOrEmpty(serviceUsername))
{
ProfileBase profile = ProfileBase.Create(serviceUsername);
var siteId = profile.GetPropertyValue("SiteID");
}
}
}
Which almost works, I can get the web service user profile by name but I can see the {ProfileCommon} is showing the properties of the web application instead of the web service so I am unable to see the value I need.
Any advice on how I might be able to achieve this?
OK I managed to get this working by adding additional membership and profile providers to my web.config, including an additional web service property with additional provider attribute :
<membership>
<providers>
<!--(website provider here)-->
<!--additional web service provider-->
<add name="WebServiceMembershipProvider"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="ApplicationServices"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
requiresUniqueEmail="true"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="6"
minRequiredNonalphanumericCharacters="0"
passwordAttemptWindow="10"
applicationName="MyWebService" />
</providers>
</membership>
<profile>
<providers>
<add name="WebServiceMembershipProvider"
type="System.Web.Profile.SqlProfileProvider"
connectionStringName="ApplicationServices"
applicationName="MyWebService"/>
</providers>
<properties>
<!-- example website property -->
<add name="website_property1"
type="string"/>
<!-- example web service property with additional provider attribute-->
<add name="webservice_property1"
type="string"
provider ="WebServiceMembershipProvider"/>
</properties>
</profile>
<roleManager enabled="true">
<providers>
<!-- (website provider here) -->
<!-- web service provider-->
<add connectionStringName="ApplicationServices"
applicationName="MyWebService"
name="WSAspNetSqlRoleProvider"
type="System.Web.Security.SqlRoleProvider" />
</providers>
</roleManager>
Then in codebehind :
Membership.ApplicationName = "MyWebService";
MembershipUser user = Membership.Providers["WebServiceMembershipProvider"].GetUser(serviceUsername, false);
profile = ProfileBase.Create(serviceUsername);
profile.Initialize(user.UserName, true);
var myProperty = profile.GetPropertyValue("webservice_property1");
hope this helps someone else!
I am going to use the default built in membership provider in my app. If the first provider does not validate the user then I want to try to validate the user against another provider.
I have my secondary provider set up in my web.config like this:
<membership>
<providers>
<add name="SecondaryMemberShipProvider"
type="System.Web.Security.ActiveDirectoryMembershipProvider,System.Web, Version 4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
enableSearchMethods="true"
connectionUserName="MyDoman\user"
connectionPassword ="password"
connectionStringName ="ADConnectionString" />
</providers>
</membership>
I added a class "SecondaryMemberShipProvider" that inherits from MembershipProvider. I am unsure of how I code the ValidateUser method on my new class.
I want to know how to set a password using mvc4 providers without knowing the old password ?
I want to make a forgot password function, where the user receives a secure link via email and then clicks the link, gets directed to the my application and then has to fill in only the new password, no security questions needed.
It was easy to do this with the membership providers that came with mvc3. I'm now using the simple membership providers that come with mvc4 and I'm having trouble getting it working.
the code so far looks as simple as:
MembershipUser user = Membership.GetUser( cust.Email );
String pass = user.GetPassword();
Boolean success = WebSecurity.ChangePassword( cust.Email, pass, model.Password );
It currently gives error on the above line that calls GetPassword() with the error :
Specified method is not supported.
I'll show the relevant section in the web.config also here :
<system.web>
<roleManager enabled="true" defaultProvider="SimpleRoleProvider">
<providers>
<clear/>
<add name="SimpleRoleProvider" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData"/>
</providers>
</roleManager>
<membership defaultProvider="SimpleMembershipProvider">
<providers>
<clear/>
<add name="SimpleMembershipProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData"
enablePasswordRetrieval="true" enablePasswordReset="true" passwordFormat="Encrypted" requiresQuestionAndAnswer="false"
requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="5" minRequiredNonalphanumericCharacters="0"
passwordAttemptWindow="10" />
</providers>
</membership>
Above I tried to add the attributes you use for the providers in mvc3 but it doesn't seem to be applicable here.
WebSecurity.GeneratePasswordResetToken generates and returns a unique string.
WebSecurity.ResetPassword uses that token to change the password.
Give the user a link to an action with the token as a parameter, then give them a simple form to change their password.
following some example from Microsoft I created my custom MembershipProvider in my MVC application as
if (MembershipService == null) { MembershipService = new AccountMembershipService(new FcMembershipProvider()); }
and the web.config is configured as
<membership defaultProvider="FcMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
<clear />
<add
name="FcMembershipProvider"
type="Fc.Web.WebAppMVC.Models.FcMembershipProvider"
connectionStringName="ApplicationServices"
enablePasswordRetrieval="true"
enablePasswordReset="true"
applicationName="FcWebMVC"
requiresQuestionAndAnswer="true"
writeExceptionsToEventLog="false" />
</providers>
</membership>
Problem is the Initialize method is not automatically called. any hint?
Thx
I think you need to get hold of your membership provider using the static Membership.Provider like so:
if (MembershipService == null) { MembershipService = new AccountMembershipService((FcMembershipProvider)Membership.Provider); }
(I put a cast in there which you may not need depending on what AccoundMembershipService is expecting.) This way ASP .NET's membership system should initialize it for you.
what is the class that implements "MembershipProvider" class ? beacause in your config file it's "FcMembershipProvider" and in the code it's AccountMembershipService.
I created a custom membership provider, I only implemented the "MembershipProvider" class, and added the config like you've done, I think you dont have to add code.
Got the following ProviderException :
The Role Manager feature has not been enabled.
So far so good.
Is there somewhere a method that can be called to check if the Role Manager has been enabled or not?
You can do this by reading from the boolean property at:
System.Web.Security.Roles.Enabled
This is a direct read from the enabled attribute of the roleManager element in the web.config:
<configuration>
<system.web>
<roleManager enabled="true" />
</system.web>
</configuration>
Update:
For more information, check out this MSDN sample: https://msdn.microsoft.com/en-us/library/aa354509(v=vs.110).aspx
If you got here because you're using the new ASP.NET Identity UserManager, what you're actually looking for is the RoleManager:
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(new ApplicationDbContext()));
roleManager will give you access to see if the role exists, create, etc, plus it is created for the UserManager
I found 2 suggestions elsewhere via Google that suggested a) making sure your db connectionstring (the one that Roles is using) is correct and that the key to it is spelled correctly, and b) that the Enabled flag on RoleManager is set to true. Hope one of those helps. It did for me.
Did you try checking Roles.Enabled? Also, you can check Roles.Providers to see how many providers are available and you can check the Roles.Provider for the default provider. If it is null then there isn't one.
I found this question due the exception mentioned in it. My Web.Config didn't have any <roleManager> tag. I realized that even if I added it (as Infotekka suggested), it ended up in a Database exception. After following the suggestions in the other answers in here, none fully solved the problem.
Since these Web.Config tags can be automatically generated, it felt wrong to solve it by manually adding them. If you are in a similar case, undo all the changes you made to Web.Config and in Visual Studio:
Press Ctrl+Q, type nuget and click on "Manage NuGet Packages";
Press Ctrl+E, type providers and in the list it should show up "Microsoft ASP.NET Universal Providers Core Libraries" and "Microsoft ASP.NET Universal Providers for LocalDB" (both created by Microsoft);
Click on the Install button in both of them and close the NuGet window;
Check your Web.config and now you should have at least one <providers> tag inside Profile, Membership, SessionState tags and also inside the new RoleManager tag, like this:
<roleManager defaultProvider="DefaultRoleProvider">
<providers>
<add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=NUMBER" connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</roleManager>
Add enabled="true" like so:
<roleManager defaultProvider="DefaultRoleProvider" enabled="true">
Press F6 to Build and now it should be OK to proceed to a database update without having that exception:
Press Ctrl+Q, type manager, click on "Package Manager Console";
Type update-database -verbose and the Seed method will run just fine (if you haven't messed elsewhere) and create a few tables in your Database;
Press Ctrl+W+L to open the Server Explorer and you should be able to check in Data Connections > DefaultConnection > Tables the Roles and UsersInRoles tables among the newly created tables!
If you are using ASP.NET Identity UserManager you can get it like this as well:
var userManager = Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
var roles = userManager.GetRoles(User.Identity.GetUserId());
If you have changed key for user from Guid to Int for example use this code:
var roles = userManager.GetRoles(User.Identity.GetUserId<int>());
<roleManager
enabled="true"
cacheRolesInCookie="false"
cookieName=".ASPXROLES"
cookieTimeout="30"
cookiePath="/"
cookieRequireSSL="false"
cookieSlidingExpiration="true"
cookieProtection="All"
defaultProvider="AspNetSqlRoleProvider"
createPersistentCookie="false"
maxCachedResults="25">
<providers>
<clear />
<add
connectionStringName="MembershipConnection"
applicationName="Mvc3"
name="AspNetSqlRoleProvider"
type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<add
applicationName="Mvc3"
name="AspNetWindowsTokenRoleProvider"
type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</roleManager>
Here is the code that you need to put in your Account Controller in MVC5 and later
to get the list of roles of a user:
csharp
public async Task<ActionResult> RoleAdd(string UserID)
{
return View(await
UserManager.GetRolesAsync(UserID)).OrderBy(s => s).ToList());
}
There is no need to use Roles.GetRolesForUser() and enable the Role Manager Feature.