I had this kind of situation - I inherited a site with a roll-your-own user database and login system. I wanted to implement the new version of YAF with the .NET membership provider. Originally I wanted to integrate YAF into my website, but my site is written in VB and I didn't want to rewrite all the App_Code files. So I had to tack on YAF as a separate application. In my case YAF lives in a subfolder of the main website, but it's set as its own IIS application.
The code found in the Wiki and some other postings for integrating with YAF logins won't work with the new YAF version. Those postings say to call yaf.DB.user_register or the like, but they don't work with the new YAF.
Here's a rundown on what I did. I won't claim this is the ideal method, but it's working for me so far. Some of this is a little foggy on the early details - sorry, it's been a several-weeks process. This isn't easy and I wouldn't recommend it unless you're somewhat experienced with .NET.
1. Extracted the YAF files into a subfolder (here called Forum2) of my website. I'm using the .NET 3.5 version, though the 2.0 version should be similar.
2. Copied Forum2/webconfigs/recommended-web.config to Forum2/web.config, overwriting the existing one.
3. (I think this was next) Modified the Forum2/db.config to add the connection string to my SQL Server. In my case I'm using an existing database, so the installer adds the YAF tables to it with the yaf prefix.
4. Used IIS Manager to create the Forum2 folder as an application.
5. Ran the YAF installer (Forum2/install/default.aspx) and went through the wizard for initial settings.
Now comes the tricky part - getting YAF and main website to talk.
6. In Visual Studio, I added the Forum2 website to my Visual Studio project along with the main website - so I have a VS solution with 2 websites. Then, right-clicked on the main website and clicked Add Reference..., browsed to the YAF bin directory, and added all the DLLs there. Note that includes the AjaxControlToolkit.dll - if you're already using that or a different version, you might run into version conflicts that require some web.config settings I won't describe here.
7. Copied the and elements from the Forum2/web.config into my main site's web.config. Now that I think about, probably only is really needed unless you need to coordinate permissions by roles with your own site. 8. I see I also copied the settings from the Forum2/app.config to my main web.config's section, though not sure that's essential. I seemed to have need at least YAF.DatabaseObjectQualifier and YAF.DatabaseOwner.9. Added a section to both web.config's with the same values. This allows the main website to create an encrypted session key for the login that the YAF site can decrypt. Put this within the section. Change the keys to a random 48-hex-character value of your own (I used RoboForm to generate my keys).<machineKey validationKey="DBAEF98E532D4161826F8351C794DFD27C0F814262FD6986"
decryptionKey="DBAEF98E532D4161826F8351C794DFD27C0F814262FD6986"
validation="SHA1" decryption="AES" />
10. Added a forms authentication section to each web.config, with the same values for name, path and protection. I set the loginUrl to the location of my main website's login page, which is "MemberLogin.aspx" in the main web.config and "../MemberLogin.aspx" in the Forum2 web.config. The "/" path allows the authentication cookie to be used by any application from the root of the web server.
<authentication mode="Forms">
<forms name=".YAFNET_Authentication" protection="All" timeout="120" cookieless="UseCookies"
loginUrl="../MemberLogin.aspx" path="/" />
</authentication>
Now to the code changes...
11. In the YAF code, in App_Code/YAF/Forum.cs, modified the Forum_Load method to redirect the user when they click the login or logout links to my main website's login/logout. This goes immediately after the if/else statement where the _page variable is set. The query string parameters are used to redirect the user back to the forum on login/logout.
// Redirect to main login or logout page
if (_page == ForumPages.login)
Response.Redirect("../MemberLogin.aspx?ReturnForum=1", true);
else if (_page == ForumPages.logout)
Response.Redirect("../MemberLogout.aspx?path=Forum2/Default.aspx", true);
12. In my main site's login page (MemberLogin.aspx), add a handler for the login authentication event. My site originally had a custom login form. I changed this to use a standard ASP.NET Login control, though it may not have been necessary. I then created the stub for the authenticate method by selecting the Login control in design mode, and in the Properties area, switched to the Events (lightning bolt icon), and double-clicked on the Authenticate line. This can also just be added to the code-behind file.
Note the code below is mostly my own, old website's authentication code, including creating my custom Member class object and calling a separate method (GetMember) to authenticate the user against my main website's database. Your site will have different code but the same principle.
Protected Sub Login1_Authenticate(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.AuthenticateEventArgs)
Handles Login1.Authenticate
Dim userName As String = Login1.UserName
Dim pwd As String = Login1.Password
If String.IsNullOrEmpty(userName) OrElse String.IsNullOrEmpty(pwd) Then
lblInstructions.Text = "Please enter both email and password to continue."
Return
End If
' Get the member object (custom method to authenticate against my custom user database)
Dim theMember As Member = GetMember(userName, pwd)
If theMember IsNot Nothing Then
' Set ASP.NET forms authentication, which is used in YAF forum
e.Authenticated = True
' Call a custom method to check the user agains the YAF membership provider (see below)
theMember.MembershipAuthenticate()
Dim redir As String
' Redirect to Forum if from there
If Request.QueryString("ReturnForum") IsNot Nothing Then
redir = "Forum2/Default.aspx"
Else
redir = Request.QueryString("ReturnPath")
End If
Response.Redirect(redir)
Else
lblInstructions.Text = "Invalid E-mail address or password, or system error. Please try again or contact
membership support."
End If
End Sub
The above method calls a method on the Member class that validates the user against the YAF provider and also sets the authentication cookie that YAF will use to recognize the user. I could have put this code in the method above, but I needed to reuse it when members are created, so I added it separately. Note that if the member isn't in the YAF provider, I go ahead and add it. I didn't want to have to recreate all my members from my main membership database up front in the YAF provider, so this adds them as they log into the site.
Public Class Member
...
Public Sub MembershipAuthenticate()
' Check the YAF membership provider - add if not yet present
If Not Membership.ValidateUser(Me.userName, Me.password) Then
Membership.CreateUser(Me.primaryEmail, Me.password, Me.primaryEmail)
End If
' Create forms authentication cookie for YAF forum
Dim ticket As New FormsAuthenticationTicket( _
1, Me.userName, DateTime.Now, DateTime.Now.AddMinutes(30), _
False, "", "/")
Dim encTicket As String = FormsAuthentication.Encrypt(ticket)
Dim authCookie As New HttpCookie(".YAFNET_Authentication", encTicket)
authCookie.Path = "/"
HttpContext.Current.Response.Cookies.Add(authCookie)
End Sub
...
End Class
Make sure you set the username correctly in the FormsAuthenticationTicket constructor (in my case it's a property of the member, Me.userName). I had originally used the User.Identity.Name, but of course that's empty at this point, so the login wasn't recognized by the forum until I got the username right.
13. Added code to create the user in the YAF provider when they are created in the main database. The add-member code already created the Member object, so I just called the CreateUser membership method, and then called the Member.MembershipAuthenticate method to ensure the new member is able to immediately visit the forum.
' Insert member into YAF provider database and authenticate for YAF forum
Membership.CreateUser(myMember.userName, myMember.password, myMember.email)
myMember.MembershipAuthenticate()
14. Added code to logout the user from either the forum or the main site. In my case, the main site used a user control to handle the logout, so I added code to its logout event to also remove the forms authentication, which is simply:
' remove authentication for YAF forum
FormsAuthentication.SignOut()
Since the Forum site can't send users to the user control directly, I created a separate page (MemberLogout.aspx) and in its Page_Init event, I duplicated the code to log the user out of both systems and redirect back to the forum. This probably could be done more elegantly, but it works.
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
Dim returnPath As String = Request.QueryString("path")
' Remove main site member
Session("Member") = Nothing
' Remove YAF authentication
FormsAuthentication.SignOut()
' Send user to page specified in query string
Response.Redirect(returnPath, True)
End Sub
I think that's it. Now the forum redirects to the main website for the login, and once the users are logged in, they can navigate between sites. Of course I also had to do work to link the sites, by adding a banner with hyperlinks to the forum so users think they're in the original website, and then link to the forum from the main site.
If I think of more details later on I'll repost with them.
Edited by user
15 years ago |
Reason: Not specified