Custom MembershipProvider With Web Interface And DAL?
Jan 7, 2010
I'm working on an ASP.NET solution with 2 projects. One is the web interface and the other contains my business logic. I'm using LINQ to SQL for my data access in the second project.
Apart of my database, I have a table called Users which holds user information.
I've started to implement a MembershipProvider. I notice that MembershipUser is coupled with MembershipProvider. What is the most correct way of getting my BLL/DAL to talk about Users?
Should I minimally implement MembershipUser and whenever a user calls a method, it will call for eg. GetUserInfo() in my BLL/DAL, to get complete information about the user?
Or should I make the MembershipUser class methods call my custom "Users" class methods (like a wrapper) in the BLL/DAL (this custom users class is not related to linq)?
Or can I somehow extend the Linq to sql class "CFUsers" to extend MembershipUser.
I've recently started tinkering with ASP.NET MVC, but this question should apply to classic ASP.NET as well. For what it's worth, I don't know very much about forms authentication and membership providers either.
I'm trying to write my own MembershipProvider which will be connected to my own custom user table in my database. My user table contains all of the basic user information such as usernames, passwords, password salts, e-mail addresses and so on, but also information such as first name, last name and country of residence.
As far as I understand, the standard way of doing this in ASP.NET is to create a user table without the extra information and then a "profile" table with the extra information. However, this doesn't sound very good to me, because whenever I need to access that extra information I would have to make one extra database query to get it.
I read in the book "Pro ASP.NET 3.5 in C# 2008" that having a separate table for the profiles is not a very good idea if you need to access the profile table a lot and have many different pages in your website.
Now for the problem at hand... As I said, I'm writing my own custom MembershipProvider subclass and it's going pretty well so far, but now I've come to realize that the CreateUser doesn't allow me to create users in the way I'd like. The method only takes a fixed number of arguments and first name, last name and country of residence are not part of them.
So how would I create an entry for the new user in my custom table without this information at hand in CreateUser of my MembershipProvider?
I'm building an n-tier application, with the web client and the class library separate. I'm also using the factory pattern of development, using interfaces to act as containers for different objects they are associated with. The problem I'm expreriencing is that I declared a public interface class in the class library and I can create an instance of it in in my aspx pages but whenever I declare it in my custom control code-side, i get an error, like so:
Error 20 The type or namespace name 'IContentMaker' could not be found (are you missing a using directive or an assembly reference?)
notge that I have inherited the class library namespace using the 'using' keyword just in case you are wondering. My code is like so:
using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq; using TQO_Classes ; //importing the class library project public partial class PageContentMgr : System.Web.UI.UserControl { private IContentMaker _data; //this line throws the error, it works fine on aspx pages
I try to implement a Custom MembershipPriver with a Custom MemberShipUser in my own database (with a specifics Users Table Model) : This is ly diffent files:
iTwitterMembershipProvider.cs using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Security; using System.Collections.Specialized; using iTwitter.Models; public class iTwitterMembershipProvider : MembershipProvider { public override string ApplicationName { get { return _ApplicationName; } set { _ApplicationName = value; } } public override bool ChangePassword(string username, string oldPassword, string newPassword) { throw new NotImplementedException(); } public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer) { return false; } public override iTwitterMembershipUser CreateUser(string login, string password, string email, string tokenKey, string tokenSecret, string twitterUserId, object providerUserKey, out MembershipCreateStatus status) { ValidatePasswordEventArgs args = new ValidatePasswordEventArgs(login, password, true);
I have created a custom MembershipProvider and RoleProvider which communications with some existing business logic. The issue I have is that the user login in my business logic requires 3 arguments (group id, user id, and password) and the MembershipProvider and RoleProvider I implemented just use 1 or 2 arguments (username, password). Right now I append my group id and user id together and pass it as the username then parse it in the implemented methods. Is there a better way to do this?
Note, I can handle the login fine because I can call my own ValidateUser method. The main issue is when the implemented methods are called from other things like the RoleProvider.GetRolesForUser(username) method when I use the AuthorizeAttribute.
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.
I want to save some info in the Session when the users successfully logins with my custom MembershipProvider, but I have no access to the Session in the provider's ValidateUser method.
public class CustomMembershipProvider : MembershipProvider { /* Override other methods and properties here */ public override bool ValidateUser(string username, string password) { /* do something to validate the username and password * and set the validUser variable */ if (validUser) { /* want to store some info in the Session here, but I can't access * it here, because this is not a Page */ } return validUser; } }
I have written an assembly (DLL) containing two classes, MyMembershipProvider and MyRoleProvider, which are derived from MembershipProvider and RoleProvider, respectively. I have implemented most but not all of the abstract methods; the remaining ones all throw a NotImplementedException. I have signed the assembly and added a reference to it in my web-site project, where the relevant web.config sections look like this:
[Code]....
When I fire up the site, however, I get the following error:
Configuration Error
Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.
Parser Error Message: Exception has been thrown by the target of an invocation.
The error message points to the <add /> tag in the <roleManager /> section: if I take that out, however (enabled="false"), it comes back again as soon as I try to log-in to the site (this time pointing to the membership section). I have verified that is recognising the classes by changing the name in the "type" attribute (to something that doesn't exist), at which point it throws a different error. Therefore I'm presuming there's a problem with my assembly code somewhere; but how can I find out where? I have debug=true in the web.config and also compiled the assembly with Debug options, but no clues.
I have a C# custom ASP.Net MembershipProvider. When the user attempts to navigate to another part of the site after IIS is restarted, it doesn't navigate to the login page to collect credentials, but instead attempts to authenticate with empty credentials.
what I have to do to identify that the new authentication needs to take place and that new creds need to be gathered?
I have a complementary custom IHttpModule implementation that allows me to intercept events like BeginRequest and AuthenticateRequest, if that helps.
We have developed a custom framework using ASP.Net, Entity Framework 4 and the likes to enable launching our custom business applications. The framework uses WCF service bindings so the interfaces could be exposed as ordinary services (API) or webservices.
As for the front end we are currently using MVC3, but it really is a problem because the business users want a very configurable/customizable UI so they can change the look and feel of the apps dynamically.
I have been thinking of exploring the option of using a readymade CMS tool such as DNN or Umbraco or something similar. Using these tools with a custom framework? How do I build the CMS so it can use my framework services to pull/push data?
I'm facing very odd problem with my application. I've been developing my own custom memberhip provider (derived from MembershipProvider, of course) and everything was working smoothly, until something odd happened. In my config file, I register my provider with such code:
[Code]....
When I deploy my site, I get this error message:
Configuration Error
Description:
An error occurred during the processing of a configuration file required to service this request. review the specific error details below and modify your configuration file appropriately.
Parser Error Message: Input string was not in a correct format.
Source Error:
Line 62: <clear/> Line 63: <add name="CustomSqlMembershipProvider" Line 64: type="My_Membership.CustomSqlMembershipProvider" Line 65: applicationName="My Application" Line 66: enablePasswordRetrieval="false"
I'm trying to unit test the MembershipProvider, however I cant figure out how or whether there is any need for unit testing of it...
My business layer:
public interface IAccountService { MembershipCreateStatus CreateUser(string userName, string password, string email); } public class AccountService : IAccountService { private readonly MembershipProvider provider; public AccountService() : this(null) { } public AccountService(MembershipProvider providera) { this.provider = providera ?? Membership.Provider; } public MembershipCreateStatus CreateUser(string userName, string password, string email) { if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", userName); if (String.IsNullOrEmpty(password)) throw new ArgumentException("Value cannot be null or empty.", password); if (String.IsNullOrEmpty(email)) throw new ArgumentException("Value cannot be null or empty.", email); MembershipCreateStatus status; provider.CreateUser(userName, password, email, null, null, true, null, out status); return status; } }
The only examples I've found so far requires a "MockMembershipProvider" with a local database setup... seems quite odd to me.
The problem I'm running into is that when people reset their passwords, it seems the ResetPassword() method returns a password that is longer than I want and has characters that can be confusing (l,1,i,I,0,O). Furthermore, I'm sending my users an email with a plain-text message and an HTML message (I'm using MailMessage with AlternateViews). If the password has unsafe HTML characters in it, when the email clients render the HTML text the password might be different (e.g. the %, &, and < aren't exactly HTML safe).
I've looked over the "add" element that belongs in the web.config, but I don't see any extra configuration properties to only include certain characters in the ResetPassword() method and to limit the password length.
Can I configure the ResetPassword() method to limit the password length and limit the character set it is choosing from?
Right now I have a workaround: I call ResetPassword() to make sure the supplied answer is correct, and then I use a RandomPassword generator I downloaded off the internet to generate a password that I like (without ambiguous characters, HTML safe, and only 8 characters long) and then I call ChangePassword() to change the user's password after I've already reset it.
We are converting an ASP site (using DotNetNuke) to a new PHP site. The only thing we have right now is a full export of the existing database. One of the tables is called "aspnet_Membership" and contains the following fields:
Password (looks like base64) PasswordFormat (always value 2) PasswordSalt (looks like base64) PasswordQuestion (always empty) PasswordAnswer (always empty)
We would like to decode these passwords and hash them to fit our own framework. From what I understand from the .NET documentation these kind of passwords can be decrypted. Is there an algorithm available that can do this or is it more complicated than that? Will it be possible if we create an ASP script on the current server?
Within a controller action, how do I get a reference to the current MembershipProvider? That would be the one specified in web.config as the default provider. I newed up an AccountMembershipService object, but it does not expose the _provider within it.I am not entirely clear on what I want. I want to create a site user in code and then store the UserId as a foreign key in the vendor master of my application. To do that I am thinking I can add a method to my custom membership provider that creates a user and returns the ID of that new user. What I need is be able to get a reference to the custom membership provider in the controller action method.
I would like to validate a password field for creating / updating users in asp.net (.net 3.5). The password will be used for a MembershipProvider.What is the best way to implement this so that the validation will use the configuration settings of the membership provider? Of course I can just write the code, but this seems like something so fundamental that there must be a drop-in way to do it.[edit] clarified that this is a password field for new users or for changing passwords, so ValidateUser doesn't help.
I need to give a user the ability to change the email of any other user listed in the aspnetdb. I can easily change their password, but I can't get the email to change. I thought that usr.email = [URL] would work, but it doesn't. It doesn't error, but it also doesn't change anything.
This is the basic code:
Dim usr As MembershipUser = Membership.GetUser(userName) usr.Email = txtEmail.Text
I'm working with the default asp.net membershipprovider. Now, by default, that requires that all members registere have all unique email-addresses.However, I'd like to override that because, in a code behind of a certain webpage, I do not need emails to be unique.
I've been wondering how i go about writing a MembershipProvider that authenticates using a WCF Provider. At the moment i have a wcf service that will authenticate a username and password.
I can write my own Membership provider that will authenticate using WCF calls, thats no problem. What i want is to have the WCF as the actually provider.
Meaning in the web.config file i just put the WCF service as the MembershipProvider. Or is this not possible or not the way this is to be done.
I have registered a custom MembershipProvider class in my Web.Config file. I'm using Inversion Of Control using Castle Windsor and I have registered my custom MembershipProvider class as transient (because it's using a service that's transient as well).
This means that I want the Membership provider instance recreated on every web request. Currently, it is created only once per application domain so when it tries to access the service it depends on, that service instance is reused while it is not supposed to.
Now I need to find a way of having Windsor control the lifetime of my custom MembershipProvider but I don't know how. I expected a factory sitting around somewhere in the .NET Framework, allowing me to override the instance creation and rerouting it to Windsor but I can't find anything alike.
By the way, I'm using .NET 4.0.
UPDATE: Here's some of my code so you can see what I'm doing exactly:
I was wondering if it is possible to use a WCF Dataservice as the MemberShipProvider for a forms auth application. I have written code for a provider (below), but I do not know what to do as far as a connection string, or any other web.config properties.
Here is the code for my provider, anytime it says Odbc that is because I based this off of the custom Odbc provider on the msdn site. The only ACTUAL references to any odbc connection are in the comments:
I trying to understand how a server farm would use MembershipProvider / RoleProvider. If I have a million users, I do not want to have multiple copies of the MembershipProvider / RoleProvider database. I would like to have one set of machines used for login but then redirect users to other machines in the server farm depending applications the users decide to use. However, once they are redirected to the new machine, I do not want the user to have to relogin. I want the credentials and role information to be available.
Does anyone know how MembershipProvider / RoleProvider is configured for this type architecture?