Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • xrisdoc 53 posts 101 karma points
    Jul 10, 2013 @ 16:28
    xrisdoc
    0

    Implement the UmbracoMembershipProvider

    Hello,

    I am trying to implement the UmbracoMembershipProvider within a separate MVC application, using the dll files from Umbraco 6.1.1.

    I have succesfully done this before with older versions of Umbarco dll files.

    However, using version 6.1.1, I seem to get an error when Calling Membership.ValidateUser(username, password).

    The error is "NullReferenceException: Object reference not set to an instance of an object" and according to the stack trace the error occurs in umbraco.cms.businesslogic.member.Member.Save().

    The error will only occur if a valid username and password is provided. If the wrong username and password are supplied, then it will return false, as it should.

    Thanks,

  • Charles Afford 1163 posts 1709 karma points
    Jul 10, 2013 @ 22:20
    Charles Afford
    0

    Hi, 

    How are you creating the member?

    Are you using the ASP.net membership provider or the Umbraco membership provider?

    Charlie :).

  • xrisdoc 53 posts 101 karma points
    Jul 10, 2013 @ 22:53
    xrisdoc
    0

    Hello,

    At the moment, I am just trying to login using a member that has already been created through the Umbraco Back Office.

    I am using the Umbraco membership provider. The fact that the error occurs in umbraco.cms.businesslogic.member.Member.Save() when I call Membership.ValidateUser(username, password), suggests to me that it is definetly using the Umbraco membership provider.

    Thanks

  • Charles Afford 1163 posts 1709 karma points
    Jul 10, 2013 @ 23:05
    Charles Afford
    0

    Yea thats your problem i think.  You need to access using the ASP.NET membership provider rather than the umbraco API (i think its been phased out now).  See 

    http://charlesafford.com/umbraco-membership-provider.aspx

    That will explain all about it :) 

    Let me know if this helps.  Charlie

  • xrisdoc 53 posts 101 karma points
    Jul 11, 2013 @ 00:00
    xrisdoc
    0

    Hi,

    Sorry, I am a bit confused as to what you mean here. I thought that in order to use the Umbraco membership, I had to use the UmbracoMembershipProvider. Otherwise, how will it know to use the Umbraco database etc to authenticate the member against that?

    Below is an example of my Web.config using the UmbracoMembershipProvider:

    <membership defaultProvider="UmbracoMembershipProvider">
      <providers>
        <clear />
        <add name="UmbracoMembershipProvider" type="umbraco.providers.members.UmbracoMembershipProvider" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" defaultMemberTypeAlias="XrisMember" passwordFormat="Hashed" />
      </providers>
    </membership>

    And to authenticate the user I would do the folowing:

    if (Membership.ValidateUser(username, password)) // Error occurs when Membership.ValidateUser() is called
    { MembershipUser m = Membership.GetUser(username); if (m != null && m.IsApproved) { FormsAuthentication.SetAuthCookie(m.UserName, false); } }

    Is this not correct? What should I be doing Instead?

    I do have a previous application that is working, using older versions of umbraco dlls (4.8.0), that uses the same implementation as to what I have described.

    In the new application, using umbraco 6.1.1 dlls, the only difference is that when Membership.ValidateUser(username, password) is called, I get the following error: "NullReferenceException: Object reference not set to an instance of an object" and according to the stack trace the error occurs in umbraco.cms.businesslogic.member.Member.Save().

    Thanks

  • Charles Afford 1163 posts 1709 karma points
    Jul 11, 2013 @ 00:13
    Charles Afford
    0

    Hi, Try using:

    Membership.provider.ValidateUser

    NOT Membership.ValidateUser

    I am using Membership.provider.ValidateUser and it works fine :).

    Let me now if this helps :). Charlie


  • Charles Afford 1163 posts 1709 karma points
    Jul 11, 2013 @ 00:16
    Charles Afford
    0

    sorry when i mean using ASP.net rather than the umbraco provider i mean using the .net means of authenticatiob and management of information rather than the built in Umbraco API like member.GetMember() ect :)

  • xrisdoc 53 posts 101 karma points
    Jul 11, 2013 @ 00:35
    xrisdoc
    0

    Hi,

    Thanks for your suggestion. Unfortunately the same error still occurs.

    Thanks,

  • Charles Afford 1163 posts 1709 karma points
    Jul 11, 2013 @ 00:42
    Charles Afford
    0

    In that case i would put it in a try catch and debug and see what execption was thrown.  That might shed some light?

    Aslo check that

    XrisMember

    Is a valid member type alais.  This could throw a object not found error.


  • Charles Afford 1163 posts 1709 karma points
    Jul 11, 2013 @ 00:46
    Charles Afford
    0

    Alos i think you might have trouble with

    IsApproved

    I dont know how this is working pre 6.0 for your solution but i used a custom property on the member.

     

    Charlie :)


  • xrisdoc 53 posts 101 karma points
    Jul 11, 2013 @ 01:10
    xrisdoc
    0

    Hello,

    The member type alias seems to be fine. 

    Sorry my mistake, the IsApproved check isn't in my older implementation.

    I have tried the try catch while debugging, but this just provides the same error information I have previously described, which was that the error occured in umbraco.cms.businesslogic.member.Member.Save().

    I see in the umbraco source code that the ValidateUser() method does call Member.Save() (https://github.com/umbraco/Umbraco-CMS/blob/6.1.1/src/umbraco.providers/members/MembersMembershipProvider.cs line 804) and that certain properties are updated before Member.Save() is called. Am I right in assuming that these property updates could be causing this to fail? Am I missing something for these properties?

    Thanks,
    Chris 

  • Charles Afford 1163 posts 1709 karma points
    Jul 11, 2013 @ 21:41
    Charles Afford
    0

    Right, so what is your code create creating a new instance of a member?,  Is the user within the context of the application?  If you try an create a new member and then see if the object is null, (Asp member, cannot remember syntax, Member = new member?)

    Then if that object is null the problem is you dont have a member in the context of the application?  Are you using MVC?

    Charlie :) 

  • Charles Afford 1163 posts 1709 karma points
    Jul 11, 2013 @ 21:41
    Charles Afford
    0

    I dont think it will be anything to do with properties and what version of umbraco are you using? Did you look at my blog post?  That implimentation will work :)

  • xrisdoc 53 posts 101 karma points
    Jul 11, 2013 @ 23:39
    xrisdoc
    0

    Yes, I am using MVC. It is a separate MVC application from my umbraco website. I am using Umbraco 6.1.1 and have also installed the nuget Umbraco Core Binaries 6.1.1 package within my spearate MVC application.

    At the moment I am just trying to do a simple login and I am not creating the member prgramatically. However, I have just tested the creation of a member using

     Membership.CreateUser("xrisdoc", "password", "xrisdoc@domain.com") 

    and I do infact get the error "Object reference not set to an instance of an object". So does this suggest that the member is not in the context of the application, as you said? If so, how do I make it part of the context?

    I am, however, able to obtain an existing member using:

    Membership.GetUser(username)

    I did read your blog, but that seemed more related the UmbracoProfileProvider and member properties etc. I don't have any additional member properties on my member type at the moment, so I didn't think that it was relevant in this case, when all I am trying to do is authenticate the user and log them in.

    Thanks,

  • Charles Afford 1163 posts 1709 karma points
    Jul 11, 2013 @ 23:50
    Charles Afford
    0

    the problem you have with Member.CreateUser is becuase you dont have the right paramter list,  You need to specify a secret question and answer.  That return a string result i think.  So you can do something like 

    string result = Membership.CreateUser("xrisdoc","password","xrisdoc@domain.com")

    This will tell you you need to privde a secret question and answer :).


  • Charles Afford 1163 posts 1709 karma points
    Jul 11, 2013 @ 23:53
    Charles Afford
    0

    What happens when you get the current user?  Membership.GetCurrent()?

    Do you get an object returned and are you able to pass the password and username on this object in to the validateuser() method?

  • xrisdoc 53 posts 101 karma points
    Jul 12, 2013 @ 00:11
    xrisdoc
    0

    Should it not return an instance of MembershipUser? From what I can see, the list of parameters is valid as this is for one of the overload methods?

    I have also tried supplying the question and answer etc, but still throws the same error.

    So far the only method that seems to be working is Membership.GetUser(username). 

    Membership.CreateUser and Membership.ValidateUser both throw errors as described previously.

    Thanks

  • xrisdoc 53 posts 101 karma points
    Jul 12, 2013 @ 00:18
    xrisdoc
    0

    the Membership.GetCurrent() doesnt seem to be a method that is available to me.  Do you mean Membership.GetUser()? because this does work when I have tested it, but cant really use that untill I have validated the member and logged them in.

    Thanks,

  • Charles Afford 1163 posts 1709 karma points
    Jul 12, 2013 @ 00:18
    Charles Afford
    0

    Sorry it should yes, i was having a moment.

    I meant as an out parameter so something like

     MembershipCreateStatus  status;

    Membership.CreateUser(EmailAddress, Password, EmailAddress, "Question", "Answer", false, out status);

    the status will now give you the result :).

    What username and passwor are you passing in?  and 

    In my surface controller i am using 

    Membership.Provider.ValidateUser(username, password)  // does the username and password have a value?

     

  • xrisdoc 53 posts 101 karma points
    Jul 12, 2013 @ 00:28
    xrisdoc
    0

    I have also tested it with the out parameter, but it doesn't even get to the point where it returns a value to that out parameter as it throws the "Object reference not set to an instance of an object."

    the stack trace indicates that this error occurs in umbraco.BusinessLogic.User.GetUser(Int32 id)

    [NullReferenceException: Object reference not set to an instance of an object.]
       umbraco.BusinessLogic.User.GetUser(Int32 id) +31
       umbraco.providers.members.UmbracoMembershipProvider.CreateUser(String username, String password, String email, String passwordQuestion, String passwordAnswer, Boolean isApproved, Object providerUserKey, MembershipCreateStatus& status) +85
       System.Web.Security.Membership.CreateUser(String username, String password, String email, String passwordQuestion, String passwordAnswer, Boolean isApproved, Object providerUserKey, MembershipCreateStatus& status) +207
       System.Web.Security.Membership.CreateUser(String username, String password, String email, String passwordQuestion, String passwordAnswer, Boolean isApproved, MembershipCreateStatus& status) +26

    When calling Membership.ValidateUser(username, password) or Membership.Provider.ValidateUser(username, password), username and password definitely have values.

    Thanks

  • Charles Afford 1163 posts 1709 karma points
    Jul 12, 2013 @ 00:34
    Charles Afford
    0

    Ok :).  I would post this problem and your enviroment (external MVC ect ect) in a new topic.  Might be worth hasing umbraco about it on twitter #umbraco, someone useally will pick that up :).  I have will have a look tomorrow and see if i can shed any light.  but thats the problem, it would seem you are not able to access the underlying membershp provider for some reason?  Charlie :)

  • xrisdoc 53 posts 101 karma points
    Jul 12, 2013 @ 00:36
    xrisdoc
    0

    No problem, I'll do that. 

    Thanks for your help anyway :-)

  • xrisdoc 53 posts 101 karma points
    Jul 12, 2013 @ 12:56
    xrisdoc
    0

    Hello,

    I havent got round to reposting this yet as you suggested, but have done some more debugging on this.

    I have managed to debug this using the Umbraco source code, in order to see where in umbraco.cms.businesslogic.member.Member.Save() the error is occuring.

    I have found that error occurs on line 568 https://github.com/umbraco/Umbraco-CMS/blob/6.1.1/src/umbraco.cms/businesslogic/member/Member.cs#L568.

    The error is because ApplicationContext.Current seems to be null. Is there anything I can do to make sure that it is set correctly?

    Thanks,

  • Charles Afford 1163 posts 1709 karma points
    Jul 12, 2013 @ 21:31
    Charles Afford
    0

    Yea thought it might be the context :). ummmm with out seeing your code and knowing what are you are doing, its gonna be tough.  Where is this code called?  In a controller or class or view/partial?

  • xrisdoc 53 posts 101 karma points
    Jul 12, 2013 @ 21:55
    xrisdoc
    0

    Hello,

    The Membership.ValidateUser(username, password) is being called within a method in my view-model. 

    The code for my Controller and view-model are at https://gist.github.com/xrisdoc/55786c825542777d96ac#file-loginformmodel-cs-L44

    Thanks,

  • Charles Afford 1163 posts 1709 karma points
    Jul 14, 2013 @ 20:35
    Charles Afford
    0

    Just taking a look :)

  • Charles Afford 1163 posts 1709 karma points
    Jul 14, 2013 @ 20:41
    Charles Afford
    0

    Just had a look, first thing i notice is that your controller is inherting from controller and not surfacecontroller so you will have no context.  This might be the problem

  • Charles Afford 1163 posts 1709 karma points
    Jul 14, 2013 @ 21:01
    Charles Afford
    0

    Const string should be UPPERCASE (i believe thats the naming convention)

    Can i ask why you are using RedirectToAction and setting a ReturnUrl? Just intrested. Charlie :).

    Fairly sure the problem is becuase you are not using surface controllers thus no context. See http://our.umbraco.org/documentation/Reference/Mvc/surface-controllers

    DO NOT NEED TO USE UMBRACO.BEGINFORM and CurrentUmbracoPage

    you can just use the way you are doing with HTTP and AJAX

  • xrisdoc 53 posts 101 karma points
    Jul 16, 2013 @ 12:51
    xrisdoc
    0

    I have tried as you suggested, to inherit from Umbraco.Web.Mvc.SurfaceController. But still seem to have an issue with the context as I now get the following error:

    [ArgumentNullException: Value cannot be null.
    Parameter name: umbracoContext]
       Umbraco.Web.Mvc.PluginController..ctor(UmbracoContext umbracoContext) +219
       Umbraco.Web.Mvc.SurfaceController..ctor(UmbracoContext umbracoContext) +5
       CPS.UI.WebApp.Controllers.LoginSurfaceController..ctor()

    I have also tried to pass UmbracoContext.Current to the SurfaceController base class using a parameterless public constructor as follows:

    public LoginSurfaceController()
        : base(UmbracoContext.Current)
    {            
    }

    But, UmbracoContext.Current is also null at this point.

    To answer your question about why I am using RedirectToAction and and setting a ReturnUrl is that I want to return the member to the URL set in ReturnUrl after they have succesfuly logged in and using RedirectToAction to redirect them to the homepage of the MVC application if no ReturnUrl is set.

    Thanks,

  • Charles Afford 1163 posts 1709 karma points
    Jul 16, 2013 @ 13:29
    Charles Afford
    0

    If you debug and put a break point on your Index [GET] are you hitting that at all?

    Do you have a template called Index?

    Are you hitting any of your server side code?  Or just client side?

    Have you got System.Web.Mvc.dll in the bin?

    Have you upgraded?

  • xrisdoc 53 posts 101 karma points
    Jul 16, 2013 @ 14:14
    xrisdoc
    0

    Hello,

    When debugging, it is not hitting Index [HttpGet]. However, when I tried using a parameterless public constructor, as mentioned previously, this was definitely getting hit, but also threw the error.

    I have a view for Index. But, when you say "template" are you referring to the templates defined in the back-office? because that is not what I am working with.

    The application is a separate MVC application with the Umbraco.Core 6.1.1 binaries installed through nuget. It is not an umbraco website. I just want to make use of the UmbracoMembershipProvider within a normal MVC application using the database for an existing Umbraco website, in order to authnticate the members against.

    Thanks

     

  • Charles Afford 1163 posts 1709 karma points
    Jul 16, 2013 @ 14:30
    Charles Afford
    0

    Ah ok, that makes sense, hence you dont have an umbraco context.  You would need that to use it in the way you are using it. It maybe worth taking to a member of the core team or #umbraco on twitter.

    I am thinking of the top of my head, that you could just get the data manually using a stored proc against your database and then do any work with the result that you get back. This would get you around the context problem.

  • Charles Afford 1163 posts 1709 karma points
    Jul 16, 2013 @ 14:34
  • xrisdoc 53 posts 101 karma points
    Jul 16, 2013 @ 22:35
    xrisdoc
    0

    I'll get something on twitter to see if any of the core team can provide any help with this.

    In the meantime, I have managed to get a workaround working for the time being.

    I have implemented a custom membership provider, using UmbracoMembershipProvider as a base and overridden the ValidateUser() method as shown below

    public class CPSUmbracoMembershipProvider : umbraco.providers.members.UmbracoMembershipProvider
    {
        public override bool ValidateUser(string username, string password)
        {
            Member m = Member.GetMemberFromLoginAndEncodedPassword(username, EncodePassword(password));
            return (m != null);
        }
    }

    I also updated the Web.config to use the Custom Membership Provider by default.

    <membership defaultProvider="CPSUmbracoMembershipProvider">
        <providers>
        <clear /> 
    <add name="CPSUmbracoMembershipProvider" type="CPS.UI.WebApp.Membership.CPSUmbracoMembershipProvider" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" defaultMemberTypeAlias="CPSMember" passwordFormat="Hashed" />         <add name="UmbracoMembershipProvider" type="umbraco.providers.members.UmbracoMembershipProvider" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" defaultMemberTypeAlias="CPSMember" passwordFormat="Hashed" />       </providers>
    </membership>

    It's not ideal, but It will do for the time being, until I figure out how to get it working properly with the UmbracoMembershipProvider and get the context issue sorted.

    Thanks again for your help.

  • Charles Afford 1163 posts 1709 karma points
    Jul 16, 2013 @ 22:45
    Charles Afford
    0

    That sounds like the correct solution to me, i am stuggleing to see how you would get the context with out actually running an Umbraco Site.

    Let me know the outcome and no problem :).  Charlie :)

Please Sign in or register to post replies

Write your reply to:

Draft