Custom Member MembershipProvider apparently not possible
I am migrating an old web-site to an umbraco 7.2.4 installation. Part of this migration caused some pain which I would like to share - hopefully it will lead to new insights for me and others.
I use CMSImport to import my existing member base into the new installation along with custom fields containing existing password and password hashes.
To provide a smooth transfer for the members I wanted to create my own Member-MembershipProvider, based on the one supplied by Umbraco. The reason being that I need to do custom validation of the password the first time the user logs in and custom validation of password retrieval answer, the first time it is used.
into a new "MyMembershipProvider" class, still with all the required interfaces etc. I register it within the web.config and it works on the public facing side.
Pain points
My problems start when I go into the backoffice.
First problem is that if the provider name is not "UmbracoMembershipProvider" the backoffice crashes with an InvalidOperationException.
Why not name it "DoNotChangeMyName .... Provider" ?
Changing the name back to "UmbracoMembershipProvider" it refuses to load the "Member Types" node. The reason apparently being a check in the class "umbraco.loadMemberTypes" that my custom membership provider does not inherit from "UmbracoMembershipProviderBase".
Creating my own version of "umbraco.loadMemberTypes" is apparently not possible either since properties in the umbraco supplied class XmlTreeNode are "internal" properties.
Trying to inherit from the existing "MembershipProviderBase" is not an option either, since the very method "EncryptOrHashPassword" which I need to change, although it is protected, is also marked as "internal".
Why this heavy use of "internal"?
Conclusion
Creating your own Member-MembershipProvider is simply not possible. There are simply too many built-in assumption in the code, and the heavy use of "internal" makes it impossible to implement your own, unless you also change the umbraco.dll, which I dont want to.
Moreover, a class-hierarchy of no less that four classes on top of the existing MembershipProvider makes for a code-base that is almost impossible to understand. Two of these classes contain 800+ and 400+ lines of code.
I am beginning to realize that maybe this part of Umbraco was never intended for custom-implementations, but I hope my experience will help others. :-)
Not much help - just wanted to say I got stuck on custom membership in 7.2.4 aswell - tried to move a custom membership provider from v6 to 7 but I cant get it to work in the new version.
Hi Jonas - I have given up on creating a custom membership provider in Umbraco 7.
Instead I have implemented my own surface controller, where I do the custom part of my authentication. After that I delegate to the Umbraco membership system.
Hi, sorry that you are having troubles with this. I'll try to answer all your questions below:
Heavy use of Internal? = if we make everything public, then we cannot progress the codebase of Umbraco because everything is a breaking change. This has been discussed on several occasions and although it would seem great if we simply made everything public, it would mean that we cannot progress the core of Umbraco without breaking everyone's website on every release. We try to maintain a balance between public APIs and internal APIs so that the codebase can be progressed and changed without people having to rebuild and fix breaking changes on each release. If you want things exposed publicly, it's a simple matter of asking by either raising an issue on the issue tracker or discussing it on the mail list
Class hierarchy? = ASP.Net membership providers are a mess to begin with. We are also dealing with the very slow migration of legacy Umbraco Core code to new core code and maintaining backwards compatibility... it's not pretty to do such a thing, it's something that we need to live with.
Changing the provider name = you can't. This is by design so that Umbraco doesn't get in the way of other web code. The alternative is to make you specify the Umbraco membership provider to be the default... and that will surely anger someone else. So the answer is simply to make sure that the Umbraco membership provider name is "UmbracoMembershipProvider" - there shouldn't be any issues with that. The Exception thrown is fairly clear : "No membership provider found with name UmbracoMembershipProvider" though I guess we could make it more specific. I don't think changing the name to "DoNotChangeMyName .... Provider" is a real pretty solution ;)
EncryptOrHashPassword as internal? = sure, we can make this public. The alternative for now is to override ValidateUser and re-implement the logic found there. I realize it's not the best solution but it will work until things you might require are public. It would be a matter of copy and pasting some code from our source. The best way forward would be to create an issue on the tracker and let us know what you would like to be public/protected/overridable.
Creating your own Member-MembershipProvider is simply not possible? = it is possible, but I realize it's not perfect. Sounds like if you override ValidateUser and copy/paste the logic in there that you need until things are public, you will be fine.
My complaint about the provider name came after spending hours of work, only to discover that the name could not be changed. :-)
I have solved the issue by explicitly handling a conversion when users log in the first time. That way, I can avoid dealing with the complexities of the internal working of the ASP.NET providers.
Maybe with time we could have a simplified provider for membership that does not have all the historic bagage and thus would be easier to customize.
It's also worth noting that 7.3 is being shipped with ASP.Net Identity in place. MembershipProvider stuff is still supported/used as well but if you wanted to change the whole auth procedure, this is fully possible in 7.3 by customizing the Identity implementation
We did get ours up and running after a while, not completely implemented - but we do have what we need including the possibility to choose member groups for permissions in the backend content tree.
I am trying to inherit the Umbraco.Web.Security.Providers.MembersMembershipProvider but I don't find the Umbraco.Web.dll in the binaries which I downloaded.
For now, I am struck with the umbraco source code compilation. Where can I download the Umbraco.Web.dll
Custom Member MembershipProvider apparently not possible
I am migrating an old web-site to an umbraco 7.2.4 installation. Part of this migration caused some pain which I would like to share - hopefully it will lead to new insights for me and others.
I use CMSImport to import my existing member base into the new installation along with custom fields containing existing password and password hashes.
To provide a smooth transfer for the members I wanted to create my own Member-MembershipProvider, based on the one supplied by Umbraco. The reason being that I need to do custom validation of the password the first time the user logs in and custom validation of password retrieval answer, the first time it is used.
I have gathered the code from the class hierarhy
into a new "MyMembershipProvider" class, still with all the required interfaces etc. I register it within the web.config and it works on the public facing side.
Pain points
My problems start when I go into the backoffice.
First problem is that if the provider name is not "UmbracoMembershipProvider" the backoffice crashes with an InvalidOperationException.
Why not name it "DoNotChangeMyName .... Provider" ?
Changing the name back to "UmbracoMembershipProvider" it refuses to load the "Member Types" node. The reason apparently being a check in the class "umbraco.loadMemberTypes" that my custom membership provider does not inherit from "UmbracoMembershipProviderBase".
Creating my own version of "umbraco.loadMemberTypes" is apparently not possible either since properties in the umbraco supplied class XmlTreeNode are "internal" properties.
Trying to inherit from the existing "MembershipProviderBase" is not an option either, since the very method "EncryptOrHashPassword" which I need to change, although it is protected, is also marked as "internal".
Why this heavy use of "internal"?
Conclusion
Creating your own Member-MembershipProvider is simply not possible. There are simply too many built-in assumption in the code, and the heavy use of "internal" makes it impossible to implement your own, unless you also change the umbraco.dll, which I dont want to.
Moreover, a class-hierarchy of no less that four classes on top of the existing MembershipProvider makes for a code-base that is almost impossible to understand. Two of these classes contain 800+ and 400+ lines of code.
I am beginning to realize that maybe this part of Umbraco was never intended for custom-implementations, but I hope my experience will help others. :-)
Kind regards
Thomas
Not much help - just wanted to say I got stuck on custom membership in 7.2.4 aswell - tried to move a custom membership provider from v6 to 7 but I cant get it to work in the new version.
Hi Jonas - I have given up on creating a custom membership provider in Umbraco 7.
Instead I have implemented my own surface controller, where I do the custom part of my authentication. After that I delegate to the Umbraco membership system.
Thomas
Hi, sorry that you are having troubles with this. I'll try to answer all your questions below:
Heavy use of Internal? = if we make everything public, then we cannot progress the codebase of Umbraco because everything is a breaking change. This has been discussed on several occasions and although it would seem great if we simply made everything public, it would mean that we cannot progress the core of Umbraco without breaking everyone's website on every release. We try to maintain a balance between public APIs and internal APIs so that the codebase can be progressed and changed without people having to rebuild and fix breaking changes on each release. If you want things exposed publicly, it's a simple matter of asking by either raising an issue on the issue tracker or discussing it on the mail list
Class hierarchy? = ASP.Net membership providers are a mess to begin with. We are also dealing with the very slow migration of legacy Umbraco Core code to new core code and maintaining backwards compatibility... it's not pretty to do such a thing, it's something that we need to live with.
Changing the provider name = you can't. This is by design so that Umbraco doesn't get in the way of other web code. The alternative is to make you specify the Umbraco membership provider to be the default... and that will surely anger someone else. So the answer is simply to make sure that the Umbraco membership provider name is "UmbracoMembershipProvider" - there shouldn't be any issues with that. The Exception thrown is fairly clear : "No membership provider found with name UmbracoMembershipProvider" though I guess we could make it more specific. I don't think changing the name to "DoNotChangeMyName .... Provider" is a real pretty solution ;)
EncryptOrHashPassword as internal? = sure, we can make this public. The alternative for now is to override ValidateUser and re-implement the logic found there. I realize it's not the best solution but it will work until things you might require are public. It would be a matter of copy and pasting some code from our source. The best way forward would be to create an issue on the tracker and let us know what you would like to be public/protected/overridable.
Creating your own Member-MembershipProvider is simply not possible? = it is possible, but I realize it's not perfect. Sounds like if you override ValidateUser and copy/paste the logic in there that you need until things are public, you will be fine.
Hi Shannon - thank you for your reply.
My complaint about the provider name came after spending hours of work, only to discover that the name could not be changed. :-)
I have solved the issue by explicitly handling a conversion when users log in the first time. That way, I can avoid dealing with the complexities of the internal working of the ASP.NET providers.
Maybe with time we could have a simplified provider for membership that does not have all the historic bagage and thus would be easier to customize.
Regards Thomas
Viva v8 :) The plan for v8 is to remove all the baggage... finally !
It's also worth noting that 7.3 is being shipped with ASP.Net Identity in place. MembershipProvider stuff is still supported/used as well but if you wanted to change the whole auth procedure, this is fully possible in 7.3 by customizing the Identity implementation
We did get ours up and running after a while, not completely implemented - but we do have what we need including the possibility to choose member groups for permissions in the backend content tree.
We inherited from
Umbraco.Web.Security.Providers.RoleProvider
and
Umbraco.Web.Security.Providers.MembersMembershipProvider
and used the name UmbracoMembershipProvider.
In webconfig membership
and rolemanager
and overriding most methods, for example:
I got the final clues I needed from looking at the source + the name thing. I should've gotten back abt this earlier, sorry for the delay.
Thank you Shannon for the update and for moving the membership provider forward !
Hi,
I am trying to inherit the Umbraco.Web.Security.Providers.MembersMembershipProvider but I don't find the Umbraco.Web.dll in the binaries which I downloaded.
For now, I am struck with the umbraco source code compilation. Where can I download the Umbraco.Web.dll
-- Vijay
is working on a reply...