Pergunta

History

We have an elaborate system which ties into DNN on multiple levels for custom user information. Our users are governed under a completely different database than DNN. Because of this, we have special requirements and have created our own membership provider to our database and registration form for our specific needs.

The Problem

In the past, we have used our membership provider and registration form with no problems. Recently, we have encountered a strange situation where the username is mangled after someone attempts to register a new account. It is mangled in such a way that the username becomes the user's Region followed by a hyphen, followed by the user's email address in full. As an example, if a user fills out the form with the following:

username:  user
region:    CA
email:     me@example.com

Before UserController.CreateUser(user) is called, the userInfo.Username equals "user". However, after the call completes, it will be "CA-me@example.com" and the created record in the User table will reflect this change.

Using my custom membership provider (which calls the default AspNetMembershipProvider) verifies that the issue seems to be with AspNetMembershipProvider's CreateUser(ref userInfo); Before this call, the username is "user", but after this call completes it becomes "CA-me@example.com". The result of the call is Success and the user is created in the database. So it doesn't appear to be a failure that is causing the issue.

Settings

I'm not sure if there are settings on DNN which may cause this problem. In my development environment, this entire thing is a non-issue. It only occurs in the live and a secondary internal test environment. Since I'm not able to reproduce this bug in my debug environment, I've considered this might be a site configuration issue. The only option I've found on Site Settings is to make the username the same as the email address, but this is disabled.

I'm going to post my membeship provider code for updating the DNN record, and I'll post the code which creates the user in my register module. I don't know if anyone might need additional code, but I'm willing to provide more where necessary.

Membership Provider

    /// <summary>
    /// Updates the user in the DNN database.
    /// </summary>
    /// <param name="userInfo"></param>
    private void UpdateDnn(UserInfo userInfo)
    {
        // _defaultProvider is an instance of AspNetMembershipProvider
        if (_defaultProvider.GetUser(userInfo.PortalID, userInfo.UserID) != null)
            _defaultProvider.UpdateUser(userInfo);
        else
            _defaultProvider.CreateUser(ref userInfo);
    }

Register Module

    public DotNetNuke.Security.Membership.UserCreateStatus Register(Inputs.RegistrationInput input)
    {
        var userInfo = new UserInfo();
        input.Fill(portalId, userInfo);  // This copies the user input into the userInfo object.
        return UserController.CreateUser(ref userInfo);
    }

RegistrationInput.Fill()

    public void Fill(int portalId, UserInfo userInfo)
    {
        if (userInfo == null) throw new ArgumentNullException("userInfo");
        userInfo.PortalID = portalId;
        userInfo.FirstName = FirstName;
        userInfo.LastName = LastName;
        userInfo.Username = UserName;
        userInfo.DisplayName = DisplayName;
        userInfo.Email = Email;
        userInfo.Username = UserName;
        userInfo.Membership.Password = Password;
        userInfo.Profile.Street = Street;
        userInfo.Profile.Unit = SuiteApt;
        userInfo.Profile.Region = State;
        userInfo.Profile.City = City;
        userInfo.Profile.PostalCode = Zip;
        userInfo.Profile.Telephone = PrimaryPhone;
    }

Update

I was digging around in DDN's core for a work around and stumbled upon this (AspNetMembershipProvider.cs:870):

                // Check that the OAuth service currently being used for login is the same as was previously used (this should always be true if user authenticated to userid)
                if (authUser == null || authUser.AuthenticationType.Equals(service, StringComparison.OrdinalIgnoreCase))
                {
                    isOAuthUser = true;
                    //DNN-4133 Change username to email address to ensure multiple users with the same email prefix, but different email domains can authenticate
                    user.Username = service + "-" + user.Email;
                }
                else
                {
                    createStatus = UserCreateStatus.DuplicateEmail;
                }

The line user.Username = service + "-" + user.Email is in the exact format of the username that I am receiving after I call UserController.CreateUser(). The question now is: is this an error in my code or their code? I'm going to keep digging into this, and if nobody answers, I'll try to post an answer to this problem after I understand what is happening here. Furthermore, if I find this to be a bug in their code, I'll post a bug report on DNN's bug tracker and link back to the bug page here.

Foi útil?

Solução

I finally found the problem. It turns out that the issue is with a line of code above the posted code in the membership provider in the same function:

        string service = HttpContext.Current.Request.Params["state"];

The problem with this line is that I pass state via POST as the user's state of residency. DNN seems to consider it the service state. The solution to this is to change the POST input parameter name from state to something else - preferably region as DNN recognizes states as regions. An easy fix, all-in-all, but it took me quite a while to find it. I think DNN should have allowed this parameter to be changed via the state of the membership object or parameter rather than grabbing it directly from the request, but there's not much that can be done on our end in that regard (modifying the core source is strongly discouraged).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top