DNN Blog

Aug 26

Posted by: Michael Washington
8/26/2007  RssIcon

DotNetNuke is an ideal place to to use as a starting point for all of your users. Frequently users need to access external applications and they are required to log into those applications again after logging into DotNetNuke. A more desired solution would be to have the users automatically logged into the external application after logging into DotNetNuke. This is known as "Single Sign On".

But how to achieve this? One solution is to use shared forms authentication. This works but has it's limitations. This article explains the various ways it can be used.  The main limitation is that a complex structure of shared cookies and redirects is required when the DotNetNuke site and the external application are located in different domains.

The goal of this exercise is to create a "Single Sign On" solution that works with any domain configuration, any web browser and is secure and reliable.

The Single Sign On Solution

The solution is outlined in these steps:

  1. The user logs onto the DotNetNuke site.

  2. The DotNetNuke site makes a web service call to the external application and instructs the external application to create a temporary password for the user in it's database. The DotNetNuke site then creates a link to the external application with the username and temporary password as parameters.

  3. The user clicks on the link navigating to the external application. The external application receives the call, and after verifying the temporary password, creates an authentication token and automatically logs the user in. The external application then replaces the temporary password in it's database with a new random one. 

 

Create the External Application

In Visual Studio 2005 or Visual Web Developer Express create a web application that uses Forms Authentication.

If the website is a file based website, in Visual Studio, you can select Website then ASP.NET Configuration to configure a directory that is not accessible by unauthenticated users. Otherwise, you can edit the web.config file manually (see the code at the end of this article).

 

In this example the directory Secure is configured to not allow unauthenticated users. 

 

Next, a table is created that holds the temporary username and password:

 

(This table cannot be the table that is used to store the normal username and password for the application.)

Next a web service is created that will allow the DotNetNuke site to create a temporary password for a user:

public bool SetAuthendication(string tmpMasterPassword, String username, string password)
{
bool isSuccess = false;
string MasterPassword;
string strSQL = "";
MasterPassword = WebConfigurationManager.AppSettings["MasterPassword"];
 
if (tmpMasterPassword == MasterPassword)
{
bool boolUserExists = UserExists(username);
 
if (boolUserExists)
{
strSQL = "Update SingleSignOnUsers set password = @password where username = @username";
}
else
{
strSQL = "Insert into SingleSignOnUsers ([username],[password]) 
values (@username, @password) ";
}
 
SqlCommand cmd = new SqlCommand(strSQL, new SqlConnection(GetConnectionString()));
cmd.CommandType = CommandType.Text;
 
cmd.Parameters.Add(new SqlParameter("@password", password));
cmd.Parameters.Add(new SqlParameter("@username", username));
 
cmd.Connection.Open();
cmd.ExecuteNonQuery();
cmd.Connection.Close();
 
isSuccess = true;
}
 
return isSuccess;
}

(For added security the web service method should be called using SSL (secure socket layer))

Next, a page is created that will receive a username and password. If it finds the user in the table, it will log the user in:

protected void Page_Load(object sender, EventArgs e)
{
string username = Request.QueryString["username"].ToString();
string password = Request.QueryString["password"].ToString();
 
 
if (ISAuthendicated(username, password))
{
lblStatus.Text = "Authendication Success";
FormsAuthenticationTicket fat =
new FormsAuthenticationTicket(1, username, DateTime.Now, DateTime.Now.AddYears(1), true, "");
HttpCookie cookie = new HttpCookie(".SingleSignOn");
cookie.Value = FormsAuthentication.Encrypt(fat);
cookie.Expires = fat.Expiration;
HttpContext.Current.Response.Cookies.Add(cookie);
}
else
{
hlLoggedin.Visible = false;
lblStatus.Text = "Authendication Failed";
}
 
//Reset the password
//Even a failed attempt will cause a new password to be created
//A hacker would be chasing a moving target
DeletePassword(username);
 
}
 
private bool ISAuthendicated(string username, string password)
{
string tmpPassword = "";
string strSQL = "Select password from SingleSignOnUsers where [username] = @username";
 
SqlCommand cmd = new SqlCommand(strSQL, new SqlConnection(GetConnectionString()));
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add(new SqlParameter("username", username));
cmd.Connection.Open();
 
SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
while (dr.Read())
{
tmpPassword = Convert.ToString(dr["password"]);
}
 
dr.Close();
 
return (tmpPassword == password & password != "");
}
 
private void DeletePassword(String username)
{
Random rnd = new Random();
string tmpPassword = username + rnd.Next(1000, 99999).ToString();
 
string strSQL = "Update SingleSignOnUsers set password =
 @password where username = @username";
SqlCommand cmd = new SqlCommand(strSQL, new SqlConnection(GetConnectionString()));
cmd.CommandType = CommandType.Text;
 
cmd.Parameters.Add(new SqlParameter("@password", tmpPassword));
cmd.Parameters.Add(new SqlParameter("@username", username));
 
cmd.Connection.Open();
cmd.ExecuteNonQuery();
cmd.Connection.Close();
}
 
private static string GetConnectionString()
{
return ConfigurationManager.ConnectionStrings["SingleSignOnDB"].ConnectionString;
}

(For added security the page should be called using SSL (secure socket layer))

Create The DotNetNuke Application

In the DotNetNuke website, create a web reference to the web service created in the external application:

 

Next, create a custom module that calls the web service and creates the temporary password and a link to the external application, passing the username and temporary password as parameters:

protected void lnkSingleSignOn_Click(object sender, EventArgs e)
{
Random rnd = new Random();
string tmpPassword = txtUsername.Text + rnd.Next(1000, 99999).ToString();
 
wsSingleSignOn.WebService wsSingleSignOn = new wsSingleSignOn.WebService();
bool boolResponse =
wsSingleSignOn.SetAuthendication(txtPassword.Text, txtUsername.Text, tmpPassword);
 
Response.Redirect(String.Format("http://localhost/singleSignOn/
SingleSignOn.aspx?username={0}&password={1}", txtUsername.Text, tmpPassword));
}

In Conclusion

The solution described provides these benefits:

  • The solution provides single sign on for any domain configuration. and is able to cross any firewall.

  • The users real password is never transmitted over the network.

  • Once a temporary password has been used it is immediately changed. If a hacker attempts to guess temporary passwords, the password is changed each time so the hacker will be chasing a "moving target". 

Complete source code

Due to the permissions issues in configuring the SQL Express database when it is moved from it's original location and that the DotNetNuke module code needs the web service link configured manually before it will compile, the download code is provided only as a reference.

DotNetNuke Module

External Application

 

 

 

Please note: It is impossible to assist all those who would have difficulty configuring this. Please us the forums for assistance. Also, if you have any technical difficulties do not post to the blog please post to the forums.

The following companies have indicated that they have the ability to implement this solution:

http://dnnmasters.com
http://www.venexus.com

Tags:
Categories:

9 comment(s) so far...


Re: DotNetNuke : A Single Sign on Solution (C#)

great Job, Michael!

By leupold on   8/26/2007

Re: DotNetNuke : A Single Sign on Solution (C#)

Very nice Michael

I wonder if you could write up a solution for creating single sign-on solution within the DNN framework. For example, imageine an installation at a company with one portla for each department. I would like to be able to enable it so that once the user is registered at any one portal, their username/password works at every portal.

The current solution kind of handles this, except that it requires that the user go through the registration process again for each child portal before adding them to the PortalUsers table for that particular portal.

By mathisjay on   8/26/2007

Re: DotNetNuke : A Single Sign on Solution (C#)

A single sign-on solution within the DNN framework is an entirely different beast. However if each sub portal has it's own domain name this solution should work. The problem is that "mydomain.com/portal1" and "mydomain.com/portal2" are the same domain. The extensibility of DotNetNuke is what makes a SSO solution so complex. I doubt that I will personally have time to tackle it, however I am sure someone else will. I hope they share their solution.

By AdefWebserver on   8/26/2007

Re: DotNetNuke : A Single Sign on Solution (C#)

currently i'm using Forms authentication for my web application. my application has several pages and many users. in an effort to Ajaxify my application i need secure web services preventing hackers from modifying user data. can i do this with this single sign on design?

By afromobile on   8/26/2007

Re: DotNetNuke : A Single Sign on Solution (C#)

for secure web services see:
http://iweb.adefwebserver.com/

By AdefWebserver on   8/26/2007

Re: DotNetNuke : A Single Sign on Solution (C#)

Michael,

Just to clarify, when you say Single Sign on are you referring to authenticating a user once and then automatically authenticating the user to 1 or more DNN sites or portals (or both)? Just trying to understand the scope of single sign-on.

Regards,

By hkenuam on   9/5/2007

Re: DotNetNuke : A Single Sign on Solution (C#)

Authendication?

By christoc on   7/11/2008

Re: DotNetNuke : A Single Sign on Solution (C#)

Our DNN site and our other web applications are integrated with single sign on -- if you sign in to any of the web app or DNN, you are automatically signed on to all other web apps, and they share the same data store for membership and profile. I implemented it by using custom providers and web services.

By bryanlu on   9/16/2008
Gravatar

Re: DotNetNuke : A Single Sign on Solution (C#)

There are some useful tips for SSO of Google Apps. Hope This help.

prasadmaduranga.blogspot.com/2010/01/saml-single-sign-on-for-google-apps-in.html

By Y Ma on   1/16/2010
Attend A Webinar
Try An Online Demo
Download DotNetNuke Professional Edition Trial
Have Someone Contact Me

Like Us on Facebook Join our Network on LinkedIn Follow DNN Corporate on Twitter Follow DNN on Twitter

Advertisers

Sponsors

DotNetNuke Corporation

DotNetNuke Corp. is the steward of the DotNetNuke open source project, the most widely adopted Web Content Management Platform for building web sites and web applications on Microsoft .NET. Organizations use DotNetNuke to quickly develop and deploy interactive and dynamic web sites, intranets, extranets and web applications. The DotNetNuke platform is available in a free Community and subscription-based Professional and Enterprise Editions with an Elite Support option. DotNetNuke Corp. also operates Snowcovered.com where users purchase third party apps for the platform.