summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNetIDme <willem.muller@gmail.com>2007-03-29 12:37:18 +0000
committerNetIDme <willem.muller@gmail.com>2007-03-29 12:37:18 +0000
commita2f947b161985efd84906dca77df63270ed1dbe8 (patch)
treef1c6d389270243d78e70ca2969bf99389ff73546
parent8d397af614f098e9b38e0cf4e5d2375c2751cfc1 (diff)
downloadDotNetOpenAuth-a2f947b161985efd84906dca77df63270ed1dbe8.zip
DotNetOpenAuth-a2f947b161985efd84906dca77df63270ed1dbe8.tar.gz
DotNetOpenAuth-a2f947b161985efd84906dca77df63270ed1dbe8.tar.bz2
- Created 2 web projects to demo openid end - end
- Several bug fixes to core Code - created a usefull readme.txt git-svn-id: https://dotnetopenid.googlecode.com/svn/trunk@43 01efa1a6-402a-0410-b0ae-47b76eba00f0
-rw-r--r--source/JanRain.OpenID.ConsumerPortal/App_Code/State.cs34
-rw-r--r--source/JanRain.OpenID.ConsumerPortal/Default.aspx92
-rw-r--r--source/JanRain.OpenID.ConsumerPortal/Default.aspx.cs20
-rw-r--r--source/JanRain.OpenID.ConsumerPortal/Global.asax11
-rw-r--r--source/JanRain.OpenID.ConsumerPortal/StyleSheet.css8
-rw-r--r--source/JanRain.OpenID.ConsumerPortal/Web.config23
-rw-r--r--source/JanRain.OpenID.ConsumerPortal/login.aspx22
-rw-r--r--source/JanRain.OpenID.ConsumerPortal/login.aspx.cs40
-rw-r--r--source/JanRain.OpenID.ServerPortal/App_Code/State.cs68
-rw-r--r--source/JanRain.OpenID.ServerPortal/App_Code/URLRewriter.cs55
-rw-r--r--source/JanRain.OpenID.ServerPortal/App_Code/Util.cs89
-rw-r--r--source/JanRain.OpenID.ServerPortal/Default.aspx16
-rw-r--r--source/JanRain.OpenID.ServerPortal/Default.aspx.cs20
-rw-r--r--source/JanRain.OpenID.ServerPortal/Global.asax17
-rw-r--r--source/JanRain.OpenID.ServerPortal/ProfileFields.ascx1028
-rw-r--r--source/JanRain.OpenID.ServerPortal/ProfileFields.ascx.cs110
-rw-r--r--source/JanRain.OpenID.ServerPortal/Web.config121
-rw-r--r--source/JanRain.OpenID.ServerPortal/decide.aspx39
-rw-r--r--source/JanRain.OpenID.ServerPortal/decide.aspx.cs55
-rw-r--r--source/JanRain.OpenID.ServerPortal/login.aspx16
-rw-r--r--source/JanRain.OpenID.ServerPortal/login.aspx.cs36
-rw-r--r--source/JanRain.OpenID.ServerPortal/server.aspx18
-rw-r--r--source/JanRain.OpenID.ServerPortal/server.aspx.cs96
-rw-r--r--source/JanRain.OpenID.ServerPortal/user.aspx9
-rw-r--r--source/JanRain.OpenID.ServerPortal/user.aspx.cs68
-rw-r--r--source/JanRain.OpenID.ServerPortal/xrds.aspx13
-rw-r--r--source/JanRain.OpenID.ServerPortal/xrds.aspx.cs42
-rw-r--r--source/Janrain.OpenId.sln76
-rw-r--r--source/Janrain.OpenId/Association.cs1
-rw-r--r--source/Janrain.OpenId/Consumer/Fetcher.cs55
-rw-r--r--source/Janrain.OpenId/Consumer/OpenIdLogin.cs16
-rw-r--r--source/Janrain.OpenId/Consumer/OpenIdTextBox.cs127
-rw-r--r--source/Janrain.OpenId/Consumer/Util.cs41
-rw-r--r--source/Janrain.OpenId/Janrain.OpenId.csproj4
-rw-r--r--source/Janrain.OpenId/RegistrationExtension/Gender.cs8
-rw-r--r--source/Janrain.OpenId/RegistrationExtension/OpenIdProfileFields.cs83
-rw-r--r--source/Janrain.OpenId/RegistrationExtension/ProfileRequest.cs9
-rw-r--r--source/Janrain.OpenId/Server/CheckIdRequest.cs241
-rw-r--r--source/Janrain.OpenId/Server/Codec.cs6
-rw-r--r--source/Janrain.OpenId/Server/Response.cs2
-rw-r--r--source/Janrain.OpenId/Server/Server.cs11
-rw-r--r--source/Janrain.OpenId/Server/ServerSession.cs15
-rw-r--r--source/README.txt141
43 files changed, 2849 insertions, 153 deletions
diff --git a/source/JanRain.OpenID.ConsumerPortal/App_Code/State.cs b/source/JanRain.OpenID.ConsumerPortal/App_Code/State.cs
new file mode 100644
index 0000000..43bb19b
--- /dev/null
+++ b/source/JanRain.OpenID.ConsumerPortal/App_Code/State.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Data;
+using System.Configuration;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using Janrain.OpenId.RegistrationExtension;
+
+/// <summary>
+/// Summary description for State
+/// </summary>
+public class State
+{
+ public State()
+ {
+ }
+
+ public static OpenIdProfileFields ProfileFields
+ {
+ get
+ {
+ if (HttpContext.Current .Session["ProfileFields"] == null)
+ {
+ HttpContext.Current .Session["ProfileFields"] = new OpenIdProfileFields();
+ }
+ return (OpenIdProfileFields)HttpContext.Current .Session["ProfileFields"];
+ }
+ set { HttpContext.Current .Session["ProfileFields"] = value; }
+ }
+
+}
diff --git a/source/JanRain.OpenID.ConsumerPortal/Default.aspx b/source/JanRain.OpenID.ConsumerPortal/Default.aspx
new file mode 100644
index 0000000..9a0a020
--- /dev/null
+++ b/source/JanRain.OpenID.ConsumerPortal/Default.aspx
@@ -0,0 +1,92 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title>Open-ID Consumer</title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <div>
+ Welcome: <b>
+ <%=User.Identity.Name %>
+ </b>to this open-id consumer<br />
+ <br />
+ <table id="profileFieldsTable" runat="server">
+ <tr>
+ <td style="width: 131px; height: 26px">
+ Nickname
+ </td>
+ <td style="width: 300px; height: 26px">
+ <%=State.ProfileFields.Nickname %>
+ </td>
+ </tr>
+ <tr>
+ <td style="width: 131px">
+ Email
+ </td>
+ <td style="width: 300px">
+ <%=State.ProfileFields.Email%>
+ </td>
+ </tr>
+ <tr>
+ <td style="width: 131px">
+ Fullname
+ </td>
+ <td style="width: 300px">
+ <%=State.ProfileFields.Fullname%>
+ </td>
+ </tr>
+ <tr>
+ <td style="width: 131px; height: 24px">
+ Date of Birth
+ </td>
+ <td style="width: 300px; height: 24px">
+ <%=State.ProfileFields.Birthdate.ToString()%>
+ </td>
+ </tr>
+ <tr>
+ <td style="width: 131px; height: 24px">
+ Gender
+ </td>
+ <td style="width: 300px; height: 24px">
+ <%=State.ProfileFields.Gender.ToString()%>
+ </td>
+ </tr>
+ <tr>
+ <td style="width: 131px; height: 26px">
+ Post Code
+ </td>
+ <td style="width: 300px; height: 26px">
+ <%=State.ProfileFields.PostalCode%>
+ &nbsp;</td>
+ </tr>
+ <tr>
+ <td style="width: 131px">
+ Country
+ </td>
+ <td style="width: 300px">
+ <%=State.ProfileFields.Country%>
+ </td>
+ </tr>
+ <tr>
+ <td style="width: 131px">
+ Language
+ </td>
+ <td style="width: 300px">
+ <%=State.ProfileFields.Language%>
+ </td>
+ </tr>
+ <tr>
+ <td style="width: 131px">
+ Timezone&nbsp;
+ </td>
+ <td style="width: 300px">
+ <%=State.ProfileFields.TimeZone%>
+ </td>
+ </tr>
+ </table>
+ </div>
+ </form>
+</body>
+</html>
diff --git a/source/JanRain.OpenID.ConsumerPortal/Default.aspx.cs b/source/JanRain.OpenID.ConsumerPortal/Default.aspx.cs
new file mode 100644
index 0000000..19d966c
--- /dev/null
+++ b/source/JanRain.OpenID.ConsumerPortal/Default.aspx.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Data;
+using System.Configuration;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+
+/// <summary>
+/// This page is protected by Forms Auth. It displays some profile information about the user collected from the identity provider.
+/// </summary>
+public partial class _Default : System.Web.UI.Page
+{
+ protected void Page_Load(object sender, EventArgs e)
+ {
+ // http://wiillemmuller.myopenid.com
+ }
+}
diff --git a/source/JanRain.OpenID.ConsumerPortal/Global.asax b/source/JanRain.OpenID.ConsumerPortal/Global.asax
new file mode 100644
index 0000000..13f79dc
--- /dev/null
+++ b/source/JanRain.OpenID.ConsumerPortal/Global.asax
@@ -0,0 +1,11 @@
+<%@ Application Language="C#" %>
+
+<script runat="server">
+
+ protected void Application_BeginRequest(Object sender, EventArgs e)
+ {
+ //System.Diagnostics.Debugger.Launch();
+
+ }
+
+</script>
diff --git a/source/JanRain.OpenID.ConsumerPortal/StyleSheet.css b/source/JanRain.OpenID.ConsumerPortal/StyleSheet.css
new file mode 100644
index 0000000..64f40d1
--- /dev/null
+++ b/source/JanRain.OpenID.ConsumerPortal/StyleSheet.css
@@ -0,0 +1,8 @@
+input.openid_login
+{
+ background: url(http://openid.net/login-bg.gif) no-repeat;
+ background-color: #fff;
+ background-position: 0 50%;
+ color: #000;
+ padding-left: 18px;
+}
diff --git a/source/JanRain.OpenID.ConsumerPortal/Web.config b/source/JanRain.OpenID.ConsumerPortal/Web.config
new file mode 100644
index 0000000..b97df8c
--- /dev/null
+++ b/source/JanRain.OpenID.ConsumerPortal/Web.config
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<configuration>
+ <system.web>
+ <compilation debug="true">
+ </compilation>
+ <authorization>
+ <!-- This means access to ALL pages requires authentication. Pages can be given explicit authentication further below. -->
+ <deny users="?"/>
+ </authorization>
+ <authentication mode="Forms">
+ <forms name="OpenIdExampleConsumer" loginUrl="login.aspx"/>
+ </authentication>
+ <customErrors mode="Off">
+ </customErrors>
+ </system.web>
+ <location path="login.aspx">
+ <system.web>
+ <authorization>
+ <allow users="*"/>
+ </authorization>
+ </system.web>
+ </location>
+</configuration>
diff --git a/source/JanRain.OpenID.ConsumerPortal/login.aspx b/source/JanRain.OpenID.ConsumerPortal/login.aspx
new file mode 100644
index 0000000..cfa860a
--- /dev/null
+++ b/source/JanRain.OpenID.ConsumerPortal/login.aspx
@@ -0,0 +1,22 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="login.aspx.cs" Inherits="login" %>
+
+<%@ Register Assembly="Janrain.OpenId" Namespace="NerdBank.OpenId.Consumer" TagPrefix="cc1" %>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+<head>
+ <title>Login</title>
+ <link href="StyleSheet.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+ <form id="Form1" runat="server">
+
+ <h2>Login Page</h2>
+ <cc1:OpenIdLogin ID="OpenIdLogin1" runat="server" CssClass="openid_login" OnLoggedIn="OpenIdLogin1_LoggedIn" RequestCountry="Request" RequestEmail="Request" RequestGender="Require" RequestPostalCode="Require" RequestTimeZone="Require" />
+ &nbsp;&nbsp;<br />
+
+ <br/>
+ &nbsp;
+ </form>
+</body>
+</html>
diff --git a/source/JanRain.OpenID.ConsumerPortal/login.aspx.cs b/source/JanRain.OpenID.ConsumerPortal/login.aspx.cs
new file mode 100644
index 0000000..02e8089
--- /dev/null
+++ b/source/JanRain.OpenID.ConsumerPortal/login.aspx.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Specialized;
+using System.Data;
+using System.Configuration;
+using System.Collections;
+using System.Web;
+using System.Web.Security;
+using System.Web.SessionState;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using Janrain.OpenId.Consumer;
+using Janrain.OpenId.RegistrationExtension;
+
+public partial class login : System.Web.UI.Page
+{
+
+
+ /// <summary>
+ /// Handles the Load event of the Page control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
+ protected void Page_Load(object sender, EventArgs e)
+ {
+
+ }
+
+ /// <summary>
+ /// Fired upon login.
+ /// Note, that straight after login, forms auth will redirect the user to their original page. So this page may never be rendererd.
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ protected void OpenIdLogin1_LoggedIn(object sender, NerdBank.OpenId.Consumer.OpenIdTextBox.OpenIdEventArgs e)
+ {
+ State.ProfileFields = e.ProfileFields;
+ }
+}
diff --git a/source/JanRain.OpenID.ServerPortal/App_Code/State.cs b/source/JanRain.OpenID.ServerPortal/App_Code/State.cs
new file mode 100644
index 0000000..81281eb
--- /dev/null
+++ b/source/JanRain.OpenID.ServerPortal/App_Code/State.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Data;
+using System.Configuration;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using Janrain.OpenId.Server;
+
+/// <summary>
+/// Summary description for State
+/// </summary>
+public class State
+{
+ public State()
+ {
+ }
+
+ public static SessionState Session
+ {
+ get
+ {
+ if (HttpContext.Current.Session["SessionState"] == null) { HttpContext.Current.Session["SessionState"] = new SessionState(); }
+ return HttpContext.Current.Session["SessionState"] as SessionState;
+ }
+ }
+
+ public static Uri ServerUri
+ {
+ get
+ {
+ UriBuilder builder = new UriBuilder(HttpContext.Current.Request.Url);
+ builder.Path = HttpContext.Current.Response.ApplyAppPathModifier("~/server.aspx");
+ builder.Query = null;
+ builder.Fragment = null;
+ return new Uri(builder.ToString(), true);
+ }
+ }
+
+ [Serializable()]
+ public class SessionState
+ {
+ private CheckIdRequest lastRequest;
+
+ public CheckIdRequest LastRequest
+ {
+ get { return lastRequest; }
+ set { lastRequest = value; }
+ }
+
+ public void CheckExpectedSateIsAvailable()
+ {
+ if (LastRequest == null)
+ {
+ throw new ApplicationException("The CheckIdRequest has not been set. This usually means that Http Session is not available and the OpenID request needs to be restarted.");
+ }
+ }
+
+ public void Reset()
+ {
+ lastRequest = null;
+ }
+ }
+
+
+}
diff --git a/source/JanRain.OpenID.ServerPortal/App_Code/URLRewriter.cs b/source/JanRain.OpenID.ServerPortal/App_Code/URLRewriter.cs
new file mode 100644
index 0000000..bd7d978
--- /dev/null
+++ b/source/JanRain.OpenID.ServerPortal/App_Code/URLRewriter.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Web;
+using System.Xml;
+using System.Xml.XPath;
+using System.Configuration;
+using System.Collections.Specialized;
+using System.Text.RegularExpressions;
+using System.Xml.Xsl;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// nicked from http://www.codeproject.com/aspnet/URLRewriter.asp
+namespace Janrain.OpenId.ServerPortal {
+
+ public class URLRewriter : IConfigurationSectionHandler {
+ protected XmlNode _oRules=null;
+
+ protected URLRewriter() { }
+
+ public string GetSubstitution(string zPath) {
+ Regex oReg;
+
+ foreach(XmlNode oNode in _oRules.SelectNodes("rule")) {
+ oReg=new Regex(oNode.SelectSingleNode("url/text()").Value,RegexOptions.IgnoreCase);
+ Match oMatch=oReg.Match(zPath);
+
+ if(oMatch.Success) {
+ return oReg.Replace(zPath,oNode.SelectSingleNode("rewrite/text()").Value);
+ }
+ }
+
+ return zPath;
+ }
+
+ public static void Process() {
+ URLRewriter oRewriter = (URLRewriter)System.Configuration.ConfigurationManager.GetSection("system.web/urlrewrites");
+
+ string zSubst=oRewriter.GetSubstitution(HttpContext.Current.Request.Path);
+
+ if(zSubst.Length>0) {
+ HttpContext.Current.RewritePath(zSubst);
+ }
+ }
+
+ #region Implementation of IConfigurationSectionHandler
+ public object Create(object parent, object configContext, XmlNode section) {
+ _oRules=section;
+
+ // TODO: Compile all Regular Expressions
+
+ return this;
+ }
+ #endregion
+ }
+}
diff --git a/source/JanRain.OpenID.ServerPortal/App_Code/Util.cs b/source/JanRain.OpenID.ServerPortal/App_Code/Util.cs
new file mode 100644
index 0000000..0bf71af
--- /dev/null
+++ b/source/JanRain.OpenID.ServerPortal/App_Code/Util.cs
@@ -0,0 +1,89 @@
+using System;
+using System.Web;
+using Janrain.OpenId.Server;
+
+/// <summary>
+/// Summary description for Util
+/// </summary>
+public class Util
+{
+ public Util()
+ {
+ }
+
+ public static string ExtractUserName(Uri url)
+ {
+ return url.Segments[url.Segments.Length - 1];
+ }
+
+ public static void GenerateHttpResponse(IEncodable response)
+ {
+ State.Session.Reset();
+ Janrain.OpenId.Server.WebResponse webresponse = null;
+ Janrain.OpenId.Server.Server server;
+ try
+ {
+ server = new Janrain.OpenId.Server.Server(Janrain.OpenId.Store.MemoryStore.GetInstance());
+ webresponse = server.EncodeResponse(response);
+ }
+ catch (Janrain.OpenId.Server.EncodingException e)
+ {
+ string text = System.Text.Encoding.UTF8.GetString(
+ e.Response.EncodeToKVForm());
+ string error = @"
+ <html><head><title>Error Processing Request</title></head><body>
+ <p><pre>{0}</pre></p>
+ <!--
+
+ This is a large comment. It exists to make this page larger.
+ That is unfortunately necessary because of the 'smart'
+ handling of pages returned with an error code in IE.
+
+ *************************************************************
+ *************************************************************
+ *************************************************************
+ *************************************************************
+ *************************************************************
+ *************************************************************
+ *************************************************************
+ *************************************************************
+ *************************************************************
+ *************************************************************
+ *************************************************************
+ *************************************************************
+ *************************************************************
+ *************************************************************
+ *************************************************************
+ *************************************************************
+ *************************************************************
+ *************************************************************
+ *************************************************************
+ *************************************************************
+ *************************************************************
+ *************************************************************
+ *************************************************************
+
+ --></body></html>";
+ error = String.Format(error, HttpContext.Current.Server.HtmlEncode(text));
+ HttpContext.Current.Response.StatusCode = 400;
+ HttpContext.Current.Response.Write(error);
+ HttpContext.Current.Response.Close();
+ }
+
+ if (((int)webresponse.Code) == 302)
+ {
+ HttpContext.Current.Response.Redirect(webresponse.Headers["Location"]);
+ return;
+ }
+ HttpContext.Current.Response.StatusCode = (int)webresponse.Code;
+ foreach (string key in webresponse.Headers)
+ HttpContext.Current.Response.AddHeader(key, webresponse.Headers[key]);
+
+ if (webresponse.Body != null)
+ HttpContext.Current.Response.Write(System.Text.Encoding.UTF8.GetString(
+ webresponse.Body));
+ HttpContext.Current.Response.Flush();
+ HttpContext.Current.Response.Close();
+ }
+
+}
diff --git a/source/JanRain.OpenID.ServerPortal/Default.aspx b/source/JanRain.OpenID.ServerPortal/Default.aspx
new file mode 100644
index 0000000..c7962d9
--- /dev/null
+++ b/source/JanRain.OpenID.ServerPortal/Default.aspx
@@ -0,0 +1,16 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" Debug="true" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" >
+<head runat="server">
+ <title>OpenID Server</title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <div>
+ Welcome to the ASP.Net Open-ID Server
+ </div>
+ </form>
+</body>
+</html>
diff --git a/source/JanRain.OpenID.ServerPortal/Default.aspx.cs b/source/JanRain.OpenID.ServerPortal/Default.aspx.cs
new file mode 100644
index 0000000..b2f5805
--- /dev/null
+++ b/source/JanRain.OpenID.ServerPortal/Default.aspx.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Data;
+using System.Configuration;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+
+/// <summary>
+/// This page is protected with FormsAuth. Only authenticated users can see it.
+/// </summary>
+public partial class _Default : System.Web.UI.Page
+{
+ protected void Page_Load(object sender, EventArgs e)
+ {
+ //
+ }
+}
diff --git a/source/JanRain.OpenID.ServerPortal/Global.asax b/source/JanRain.OpenID.ServerPortal/Global.asax
new file mode 100644
index 0000000..c33de8a
--- /dev/null
+++ b/source/JanRain.OpenID.ServerPortal/Global.asax
@@ -0,0 +1,17 @@
+<%@ Application Language="C#" %>
+
+<script runat="server">
+
+ protected void Application_BeginRequest(Object sender, EventArgs e)
+ {
+ /*
+ * The URLRewriter was taken from http://www.codeproject.com/aspnet/URLRewriter.asp and modified slightly.
+ * It will read the config section called 'urlrewrites' from web.config and process each rule
+ * The rules are set of url transformations defined using regular expressions with support for substitutions (the ability to extract regex-matched portions of a string).
+ * There is only one rule currenty defined. It rewrites urls like: user/john ->user.aspx?username=john
+ */
+ //System.Diagnostics.Debugger.Launch();
+ Janrain.OpenId.ServerPortal.URLRewriter.Process();
+ }
+
+</script>
diff --git a/source/JanRain.OpenID.ServerPortal/ProfileFields.ascx b/source/JanRain.OpenID.ServerPortal/ProfileFields.ascx
new file mode 100644
index 0000000..2d4dd38
--- /dev/null
+++ b/source/JanRain.OpenID.ServerPortal/ProfileFields.ascx
@@ -0,0 +1,1028 @@
+<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ProfileFields.ascx.cs" Inherits="ProfileFields" %>
+This consumer has requested the following fields from you<br />
+<table>
+ <tr>
+ <td style="width: 131px">
+ </td>
+ <td style="width: 300px">
+ </td>
+ <td style="width: 220px">
+ </td>
+ </tr>
+ <tr runat="server" id="nicknameRow">
+ <td style="width: 131px; height: 26px;">
+ Nickname
+ <asp:Label ID="nicknameRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label></td>
+ <td style="width: 300px; height: 26px;">
+ <asp:TextBox ID="nicknameTextBox" runat="server"></asp:TextBox>
+ </td>
+ <td style="width: 220px; height: 26px;">
+ &nbsp;</td>
+ </tr>
+ <tr runat="server" id="emailRow">
+ <td style="width: 131px">
+ Email
+ <asp:Label ID="emailRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label></td>
+ <td style="width: 300px">
+ <asp:TextBox ID="emailTextBox" runat="server"></asp:TextBox>
+ </td>
+ <td style="width: 220px">
+ &nbsp;</td>
+ </tr>
+ <tr runat="server" id="fullnameRow">
+ <td style="width: 131px">
+ Fullname
+ <asp:Label ID="fullnameRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label></td>
+ <td style="width: 300px">
+ <asp:TextBox ID="fullnameTextBox" runat="server"></asp:TextBox>
+ </td>
+ <td style="width: 220px">
+ &nbsp;</td>
+ </tr>
+ <tr runat="server" id="dateOfBirthRow">
+ <td style="width: 131px; height: 24px;">
+ Date of Birth
+ <asp:Label ID="dobRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label></td>
+ <td style="width: 300px; height: 24px;">
+ <asp:DropDownList ID="dobDayDropdownlist" runat="server">
+ <asp:ListItem></asp:ListItem>
+ <asp:ListItem>1</asp:ListItem>
+ <asp:ListItem>2</asp:ListItem>
+ <asp:ListItem>3</asp:ListItem>
+ <asp:ListItem>4</asp:ListItem>
+ <asp:ListItem>5</asp:ListItem>
+ <asp:ListItem>6</asp:ListItem>
+ <asp:ListItem>7</asp:ListItem>
+ <asp:ListItem>8</asp:ListItem>
+ <asp:ListItem>9</asp:ListItem>
+ <asp:ListItem>10</asp:ListItem>
+ <asp:ListItem>11</asp:ListItem>
+ <asp:ListItem>12</asp:ListItem>
+ <asp:ListItem>13</asp:ListItem>
+ <asp:ListItem>14</asp:ListItem>
+ <asp:ListItem>15</asp:ListItem>
+ <asp:ListItem>16</asp:ListItem>
+ <asp:ListItem>17</asp:ListItem>
+ <asp:ListItem>18</asp:ListItem>
+ <asp:ListItem>19</asp:ListItem>
+ <asp:ListItem>20</asp:ListItem>
+ <asp:ListItem>21</asp:ListItem>
+ <asp:ListItem>22</asp:ListItem>
+ <asp:ListItem>23</asp:ListItem>
+ <asp:ListItem>24</asp:ListItem>
+ <asp:ListItem>25</asp:ListItem>
+ <asp:ListItem>26</asp:ListItem>
+ <asp:ListItem>27</asp:ListItem>
+ <asp:ListItem>28</asp:ListItem>
+ <asp:ListItem>29</asp:ListItem>
+ <asp:ListItem>30</asp:ListItem>
+ <asp:ListItem>31</asp:ListItem>
+ </asp:DropDownList>&nbsp;<asp:DropDownList ID="dobMonthDropdownlist" runat="server">
+ <asp:ListItem></asp:ListItem>
+ <asp:ListItem Value="1">January</asp:ListItem>
+ <asp:ListItem Value="2">February</asp:ListItem>
+ <asp:ListItem Value="3">March</asp:ListItem>
+ <asp:ListItem Value="4">April</asp:ListItem>
+ <asp:ListItem Value="5">May</asp:ListItem>
+ <asp:ListItem Value="6">June</asp:ListItem>
+ <asp:ListItem Value="7">July</asp:ListItem>
+ <asp:ListItem Value="8">August</asp:ListItem>
+ <asp:ListItem Value="9">September</asp:ListItem>
+ <asp:ListItem Value="10">October</asp:ListItem>
+ <asp:ListItem Value="11">November</asp:ListItem>
+ <asp:ListItem Value="12">December</asp:ListItem>
+ </asp:DropDownList>&nbsp;
+ <asp:DropDownList ID="dobYearDropdownlist" runat="server">
+ <asp:ListItem></asp:ListItem>
+ <asp:ListItem>2009</asp:ListItem>
+ <asp:ListItem>2008</asp:ListItem>
+ <asp:ListItem>2007</asp:ListItem>
+ <asp:ListItem>2006</asp:ListItem>
+ <asp:ListItem>2005</asp:ListItem>
+ <asp:ListItem>2004</asp:ListItem>
+ <asp:ListItem>2003</asp:ListItem>
+ <asp:ListItem>2002</asp:ListItem>
+ <asp:ListItem>2001</asp:ListItem>
+ <asp:ListItem>2000</asp:ListItem>
+ <asp:ListItem>1999</asp:ListItem>
+ <asp:ListItem>1998</asp:ListItem>
+ <asp:ListItem>1997</asp:ListItem>
+ <asp:ListItem>1996</asp:ListItem>
+ <asp:ListItem>1995</asp:ListItem>
+ <asp:ListItem>1994</asp:ListItem>
+ <asp:ListItem>1993</asp:ListItem>
+ <asp:ListItem>1992</asp:ListItem>
+ <asp:ListItem>1991</asp:ListItem>
+ <asp:ListItem>1990</asp:ListItem>
+ <asp:ListItem>1989</asp:ListItem>
+ <asp:ListItem>1988</asp:ListItem>
+ <asp:ListItem>1987</asp:ListItem>
+ <asp:ListItem>1986</asp:ListItem>
+ <asp:ListItem>1985</asp:ListItem>
+ <asp:ListItem>1984</asp:ListItem>
+ <asp:ListItem>1983</asp:ListItem>
+ <asp:ListItem>1982</asp:ListItem>
+ <asp:ListItem>1981</asp:ListItem>
+ <asp:ListItem>1980</asp:ListItem>
+ <asp:ListItem>1979</asp:ListItem>
+ <asp:ListItem>1978</asp:ListItem>
+ <asp:ListItem>1977</asp:ListItem>
+ <asp:ListItem>1976</asp:ListItem>
+ <asp:ListItem>1975</asp:ListItem>
+ <asp:ListItem>1974</asp:ListItem>
+ <asp:ListItem>1973</asp:ListItem>
+ <asp:ListItem>1972</asp:ListItem>
+ <asp:ListItem>1971</asp:ListItem>
+ <asp:ListItem>1970</asp:ListItem>
+ <asp:ListItem>1969</asp:ListItem>
+ <asp:ListItem>1968</asp:ListItem>
+ <asp:ListItem>1967</asp:ListItem>
+ <asp:ListItem>1966</asp:ListItem>
+ <asp:ListItem>1965</asp:ListItem>
+ <asp:ListItem>1964</asp:ListItem>
+ <asp:ListItem>1963</asp:ListItem>
+ <asp:ListItem>1962</asp:ListItem>
+ <asp:ListItem>1961</asp:ListItem>
+ <asp:ListItem>1960</asp:ListItem>
+ <asp:ListItem>1959</asp:ListItem>
+ <asp:ListItem>1958</asp:ListItem>
+ <asp:ListItem>1957</asp:ListItem>
+ <asp:ListItem>1956</asp:ListItem>
+ <asp:ListItem>1955</asp:ListItem>
+ <asp:ListItem>1954</asp:ListItem>
+ <asp:ListItem>1953</asp:ListItem>
+ <asp:ListItem>1952</asp:ListItem>
+ <asp:ListItem>1951</asp:ListItem>
+ <asp:ListItem>1950</asp:ListItem>
+ <asp:ListItem>1949</asp:ListItem>
+ <asp:ListItem>1948</asp:ListItem>
+ <asp:ListItem>1947</asp:ListItem>
+ <asp:ListItem>1946</asp:ListItem>
+ <asp:ListItem>1945</asp:ListItem>
+ <asp:ListItem>1944</asp:ListItem>
+ <asp:ListItem>1943</asp:ListItem>
+ <asp:ListItem>1942</asp:ListItem>
+ <asp:ListItem>1941</asp:ListItem>
+ <asp:ListItem>1940</asp:ListItem>
+ <asp:ListItem>1939</asp:ListItem>
+ <asp:ListItem>1938</asp:ListItem>
+ <asp:ListItem>1937</asp:ListItem>
+ <asp:ListItem>1936</asp:ListItem>
+ <asp:ListItem>1935</asp:ListItem>
+ <asp:ListItem>1934</asp:ListItem>
+ <asp:ListItem>1933</asp:ListItem>
+ <asp:ListItem>1932</asp:ListItem>
+ <asp:ListItem>1931</asp:ListItem>
+ <asp:ListItem>1930</asp:ListItem>
+ <asp:ListItem>1929</asp:ListItem>
+ <asp:ListItem>1928</asp:ListItem>
+ <asp:ListItem>1927</asp:ListItem>
+ <asp:ListItem>1926</asp:ListItem>
+ <asp:ListItem>1925</asp:ListItem>
+ <asp:ListItem>1924</asp:ListItem>
+ <asp:ListItem>1923</asp:ListItem>
+ <asp:ListItem>1922</asp:ListItem>
+ <asp:ListItem>1921</asp:ListItem>
+ <asp:ListItem>1920</asp:ListItem>
+ </asp:DropDownList></td>
+ <td style="width: 220px; height: 24px;">
+ &nbsp;</td>
+ </tr>
+ <tr runat="server" id="genderRow">
+ <td style="width: 131px; height: 24px;">
+ Gender
+ <asp:Label ID="genderRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label></td>
+ <td style="width: 300px; height: 24px;">
+ <asp:DropDownList ID="DropDownList1" runat="server">
+ <asp:ListItem Selected="True"></asp:ListItem>
+ <asp:ListItem>Male</asp:ListItem>
+ <asp:ListItem>Female</asp:ListItem>
+ </asp:DropDownList></td>
+ <td style="width: 220px; height: 24px;">
+ &nbsp;</td>
+ </tr>
+ <tr runat="server" id="postcodeRow">
+ <td style="width: 131px; height: 26px;">
+ Post Code
+ <asp:Label ID="postcodeRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label></td>
+ <td style="width: 300px; height: 26px;">
+ <asp:TextBox ID="postcodeTextBox" runat="server"></asp:TextBox>
+ </td>
+ <td style="width: 220px; height: 26px;">
+ &nbsp;</td>
+ </tr>
+ <tr runat="server" id="countryRow">
+ <td style="width: 131px">
+ Country
+ <asp:Label ID="countryRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label></td>
+ <td style="width: 300px">
+ <asp:DropDownList ID="countryDropdownList" runat="server">
+ <asp:ListItem Value=""> </asp:ListItem>
+ <asp:ListItem Value="AF">AFGHANISTAN </asp:ListItem>
+ <asp:ListItem Value="AX">ÅLAND ISLANDS</asp:ListItem>
+ <asp:ListItem Value="AL">ALBANIA</asp:ListItem>
+ <asp:ListItem Value="DZ">ALGERIA</asp:ListItem>
+ <asp:ListItem Value="AS">AMERICAN SAMOA</asp:ListItem>
+ <asp:ListItem Value="AD">ANDORRA</asp:ListItem>
+ <asp:ListItem Value="AO">ANGOLA</asp:ListItem>
+ <asp:ListItem Value="AI">ANGUILLA</asp:ListItem>
+ <asp:ListItem Value="AQ">ANTARCTICA</asp:ListItem>
+ <asp:ListItem Value="AG">ANTIGUA AND BARBUDA</asp:ListItem>
+ <asp:ListItem Value="AR">ARGENTINA</asp:ListItem>
+ <asp:ListItem Value="AM">ARMENIA</asp:ListItem>
+ <asp:ListItem Value="AW">ARUBA</asp:ListItem>
+ <asp:ListItem Value="AU">AUSTRALIA</asp:ListItem>
+ <asp:ListItem Value="AT">AUSTRIA</asp:ListItem>
+ <asp:ListItem Value="AZ">AZERBAIJAN</asp:ListItem>
+ <asp:ListItem Value="BS">BAHAMAS</asp:ListItem>
+ <asp:ListItem Value="BH">BAHRAIN</asp:ListItem>
+ <asp:ListItem Value="BD">BANGLADESH</asp:ListItem>
+ <asp:ListItem Value="BB">BARBADOS</asp:ListItem>
+ <asp:ListItem Value="BY">BELARUS</asp:ListItem>
+ <asp:ListItem Value="BE">BELGIUM</asp:ListItem>
+ <asp:ListItem Value="BZ">BELIZE</asp:ListItem>
+ <asp:ListItem Value="BJ">BENIN</asp:ListItem>
+ <asp:ListItem Value="BM">BERMUDA</asp:ListItem>
+ <asp:ListItem Value="BT">BHUTAN</asp:ListItem>
+ <asp:ListItem Value="BO">BOLIVIA</asp:ListItem>
+ <asp:ListItem Value="BA">BOSNIA AND HERZEGOVINA</asp:ListItem>
+ <asp:ListItem Value="BW">BOTSWANA</asp:ListItem>
+ <asp:ListItem Value="BV">BOUVET ISLAND</asp:ListItem>
+ <asp:ListItem Value="BR">BRAZIL</asp:ListItem>
+ <asp:ListItem Value="IO">BRITISH INDIAN OCEAN TERRITORY</asp:ListItem>
+ <asp:ListItem Value="BN">BRUNEI DARUSSALAM</asp:ListItem>
+ <asp:ListItem Value="BG">BULGARIA</asp:ListItem>
+ <asp:ListItem Value="BF">BURKINA FASO</asp:ListItem>
+ <asp:ListItem Value="BI">BURUNDI</asp:ListItem>
+ <asp:ListItem Value="KH">CAMBODIA</asp:ListItem>
+ <asp:ListItem Value="CM">CAMEROON</asp:ListItem>
+ <asp:ListItem Value="CA">CANADA</asp:ListItem>
+ <asp:ListItem Value="CV">CAPE VERDE</asp:ListItem>
+ <asp:ListItem Value="KY">CAYMAN ISLANDS</asp:ListItem>
+ <asp:ListItem Value="CF">CENTRAL AFRICAN REPUBLIC</asp:ListItem>
+ <asp:ListItem Value="TD">CHAD</asp:ListItem>
+ <asp:ListItem Value="CL">CHILE</asp:ListItem>
+ <asp:ListItem Value="CN">CHINA</asp:ListItem>
+ <asp:ListItem Value="CX">CHRISTMAS ISLAND</asp:ListItem>
+ <asp:ListItem Value="CC">COCOS (KEELING) ISLANDS</asp:ListItem>
+ <asp:ListItem Value="CO">COLOMBIA</asp:ListItem>
+ <asp:ListItem Value="KM">COMOROS</asp:ListItem>
+ <asp:ListItem Value="CG">CONGO</asp:ListItem>
+ <asp:ListItem Value="CD">CONGO, THE DEMOCRATIC REPUBLIC OF THE</asp:ListItem>
+ <asp:ListItem Value="CK">COOK ISLANDS</asp:ListItem>
+ <asp:ListItem Value="CR">COSTA RICA</asp:ListItem>
+ <asp:ListItem Value="CI">CÔTE D'IVOIRE</asp:ListItem>
+ <asp:ListItem Value="HR">CROATIA</asp:ListItem>
+ <asp:ListItem Value="CU">CUBA</asp:ListItem>
+ <asp:ListItem Value="CY">CYPRUS</asp:ListItem>
+ <asp:ListItem Value="CZ">CZECH REPUBLIC</asp:ListItem>
+ <asp:ListItem Value="DK">DENMARK</asp:ListItem>
+ <asp:ListItem Value="DJ">DJIBOUTI</asp:ListItem>
+ <asp:ListItem Value="DM">DOMINICA</asp:ListItem>
+ <asp:ListItem Value="DO">DOMINICAN REPUBLIC</asp:ListItem>
+ <asp:ListItem Value="EC">ECUADOR</asp:ListItem>
+ <asp:ListItem Value="EG">EGYPT</asp:ListItem>
+ <asp:ListItem Value="SV">EL SALVADOR</asp:ListItem>
+ <asp:ListItem Value="GQ">EQUATORIAL GUINEA</asp:ListItem>
+ <asp:ListItem Value="ER">ERITREA</asp:ListItem>
+ <asp:ListItem Value="EE">ESTONIA</asp:ListItem>
+ <asp:ListItem Value="ET">ETHIOPIA</asp:ListItem>
+ <asp:ListItem Value="FK">FALKLAND ISLANDS (MALVINAS)</asp:ListItem>
+ <asp:ListItem Value="FO">FAROE ISLANDS</asp:ListItem>
+ <asp:ListItem Value="FJ">FIJI</asp:ListItem>
+ <asp:ListItem Value="FI">FINLAND</asp:ListItem>
+ <asp:ListItem Value="FR">FRANCE</asp:ListItem>
+ <asp:ListItem Value="GF">FRENCH GUIANA</asp:ListItem>
+ <asp:ListItem Value="PF">FRENCH POLYNESIA</asp:ListItem>
+ <asp:ListItem Value="TF">FRENCH SOUTHERN TERRITORIES</asp:ListItem>
+ <asp:ListItem Value="GA">GABON </asp:ListItem>
+ <asp:ListItem Value="GM">GAMBIA</asp:ListItem>
+ <asp:ListItem Value="GE">GEORGIA</asp:ListItem>
+ <asp:ListItem Value="DE">GERMANY</asp:ListItem>
+ <asp:ListItem Value="GH">GHANA</asp:ListItem>
+ <asp:ListItem Value="GI">GIBRALTAR</asp:ListItem>
+ <asp:ListItem Value="GR">GREECE</asp:ListItem>
+ <asp:ListItem Value="GL">GREENLAND</asp:ListItem>
+ <asp:ListItem Value="GD">GRENADA</asp:ListItem>
+ <asp:ListItem Value="GP">GUADELOUPE</asp:ListItem>
+ <asp:ListItem Value="GU">GUAM </asp:ListItem>
+ <asp:ListItem Value="GT">GUATEMALA</asp:ListItem>
+ <asp:ListItem Value="GG">GUERNSEY</asp:ListItem>
+ <asp:ListItem Value="GN">GUINEA</asp:ListItem>
+ <asp:ListItem Value="GW">GUINEA-BISSAU</asp:ListItem>
+ <asp:ListItem Value="GY">GUYANA</asp:ListItem>
+ <asp:ListItem Value="HT">HAITI</asp:ListItem>
+ <asp:ListItem Value="HM">HEARD ISLAND AND MCDONALD ISLANDS</asp:ListItem>
+ <asp:ListItem Value="VA">HOLY SEE (VATICAN CITY STATE)</asp:ListItem>
+ <asp:ListItem Value="HN">HONDURAS</asp:ListItem>
+ <asp:ListItem Value="HK">HONG KONG</asp:ListItem>
+ <asp:ListItem Value="HU">HUNGARY</asp:ListItem>
+ <asp:ListItem Value="IS">ICELAND</asp:ListItem>
+ <asp:ListItem Value="IN">INDIA</asp:ListItem>
+ <asp:ListItem Value="ID">INDONESIA</asp:ListItem>
+ <asp:ListItem Value="IR">IRAN, ISLAMIC REPUBLIC OF</asp:ListItem>
+ <asp:ListItem Value="IQ">IRAQ</asp:ListItem>
+ <asp:ListItem Value="IE">IRELAND</asp:ListItem>
+ <asp:ListItem Value="IM">ISLE OF MAN</asp:ListItem>
+ <asp:ListItem Value="IL">ISRAEL</asp:ListItem>
+ <asp:ListItem Value="IT">ITALY</asp:ListItem>
+ <asp:ListItem Value="JM">JAMAICA</asp:ListItem>
+ <asp:ListItem Value="JP">JAPAN</asp:ListItem>
+ <asp:ListItem Value="JE">JERSEY</asp:ListItem>
+ <asp:ListItem Value="JO">JORDAN</asp:ListItem>
+ <asp:ListItem Value="KZ">KAZAKHSTAN</asp:ListItem>
+ <asp:ListItem Value="KE">KENYA</asp:ListItem>
+ <asp:ListItem Value="KI">KIRIBATI</asp:ListItem>
+ <asp:ListItem Value="KP">KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF</asp:ListItem>
+ <asp:ListItem Value="KR">KOREA, REPUBLIC OF</asp:ListItem>
+ <asp:ListItem Value="KW">KUWAIT</asp:ListItem>
+ <asp:ListItem Value="KG">KYRGYZSTAN</asp:ListItem>
+ <asp:ListItem Value="LA">LAO PEOPLE'S DEMOCRATIC REPUBLIC </asp:ListItem>
+ <asp:ListItem Value="LV">LATVIA</asp:ListItem>
+ <asp:ListItem Value="LB">LEBANON</asp:ListItem>
+ <asp:ListItem Value="LS">LESOTHO</asp:ListItem>
+ <asp:ListItem Value="LR">LIBERIA</asp:ListItem>
+ <asp:ListItem Value="LY">LIBYAN ARAB JAMAHIRIYA</asp:ListItem>
+ <asp:ListItem Value="LI">LIECHTENSTEIN</asp:ListItem>
+ <asp:ListItem Value="LT">LITHUANIA</asp:ListItem>
+ <asp:ListItem Value="LU">LUXEMBOURG</asp:ListItem>
+ <asp:ListItem Value="MO">MACAO</asp:ListItem>
+ <asp:ListItem Value="MK">MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF</asp:ListItem>
+ <asp:ListItem Value="MG">MADAGASCAR</asp:ListItem>
+ <asp:ListItem Value="MW">MALAWI</asp:ListItem>
+ <asp:ListItem Value="MY">MALAYSIA</asp:ListItem>
+ <asp:ListItem Value="MV">MALDIVES</asp:ListItem>
+ <asp:ListItem Value="ML">MALI</asp:ListItem>
+ <asp:ListItem Value="MT">MALTA</asp:ListItem>
+ <asp:ListItem Value="MH">MARSHALL ISLANDS</asp:ListItem>
+ <asp:ListItem Value="MQ">MARTINIQUE</asp:ListItem>
+ <asp:ListItem Value="MR">MAURITANIA</asp:ListItem>
+ <asp:ListItem Value="MU">MAURITIUS</asp:ListItem>
+ <asp:ListItem Value="YT">MAYOTTE</asp:ListItem>
+ <asp:ListItem Value="MX">MEXICO</asp:ListItem>
+ <asp:ListItem Value="FM">MICRONESIA, FEDERATED STATES OF</asp:ListItem>
+ <asp:ListItem Value="MD">MOLDOVA, REPUBLIC OF</asp:ListItem>
+ <asp:ListItem Value="MC">MONACO</asp:ListItem>
+ <asp:ListItem Value="MN">MONGOLIA</asp:ListItem>
+ <asp:ListItem Value="ME">MONTENEGRO</asp:ListItem>
+ <asp:ListItem Value="MS">MONTSERRAT</asp:ListItem>
+ <asp:ListItem Value="MA">MOROCCO</asp:ListItem>
+ <asp:ListItem Value="MZ">MOZAMBIQUE</asp:ListItem>
+ <asp:ListItem Value="MM">MYANMAR</asp:ListItem>
+ <asp:ListItem Value="NA">NAMIBIA</asp:ListItem>
+ <asp:ListItem Value="NR">NAURU</asp:ListItem>
+ <asp:ListItem Value="NP">NEPAL</asp:ListItem>
+ <asp:ListItem Value="NL">NETHERLANDS</asp:ListItem>
+ <asp:ListItem Value="AN">NETHERLANDS ANTILLES</asp:ListItem>
+ <asp:ListItem Value="NC">NEW CALEDONIA</asp:ListItem>
+ <asp:ListItem Value="NZ">NEW ZEALAND</asp:ListItem>
+ <asp:ListItem Value="NI">NICARAGUA</asp:ListItem>
+ <asp:ListItem Value="NE">NIGER</asp:ListItem>
+ <asp:ListItem Value="NG">NIGERIA</asp:ListItem>
+ <asp:ListItem Value="NU">NIUE</asp:ListItem>
+ <asp:ListItem Value="NF">NORFOLK ISLAND</asp:ListItem>
+ <asp:ListItem Value="MP">NORTHERN MARIANA ISLANDS</asp:ListItem>
+ <asp:ListItem Value="NO">NORWAY</asp:ListItem>
+ <asp:ListItem Value="OM">OMAN</asp:ListItem>
+ <asp:ListItem Value="PK">PAKISTAN</asp:ListItem>
+ <asp:ListItem Value="PW">PALAU</asp:ListItem>
+ <asp:ListItem Value="PS">PALESTINIAN TERRITORY, OCCUPIED</asp:ListItem>
+ <asp:ListItem Value="PA">PANAMA</asp:ListItem>
+ <asp:ListItem Value="PG">PAPUA NEW GUINEA</asp:ListItem>
+ <asp:ListItem Value="PY">PARAGUAY</asp:ListItem>
+ <asp:ListItem Value="PE">PERU</asp:ListItem>
+ <asp:ListItem Value="PH">PHILIPPINES</asp:ListItem>
+ <asp:ListItem Value="PN">PITCAIRN</asp:ListItem>
+ <asp:ListItem Value="PL">POLAND</asp:ListItem>
+ <asp:ListItem Value="PT">PORTUGAL</asp:ListItem>
+ <asp:ListItem Value="PR">PUERTO RICO</asp:ListItem>
+ <asp:ListItem Value="QA">QATAR</asp:ListItem>
+ <asp:ListItem Value="RE">RÉUNION</asp:ListItem>
+ <asp:ListItem Value="RO">ROMANIA</asp:ListItem>
+ <asp:ListItem Value="RU">RUSSIAN FEDERATION</asp:ListItem>
+ <asp:ListItem Value="RW">RWANDA</asp:ListItem>
+ <asp:ListItem Value="SH">SAINT HELENA </asp:ListItem>
+ <asp:ListItem Value="KN">SAINT KITTS AND NEVIS</asp:ListItem>
+ <asp:ListItem Value="LC">SAINT LUCIA</asp:ListItem>
+ <asp:ListItem Value="PM">SAINT PIERRE AND MIQUELON</asp:ListItem>
+ <asp:ListItem Value="VC">SAINT VINCENT AND THE GRENADINES</asp:ListItem>
+ <asp:ListItem Value="WS">SAMOA</asp:ListItem>
+ <asp:ListItem Value="SM">SAN MARINO</asp:ListItem>
+ <asp:ListItem Value="ST">SAO TOME AND PRINCIPE</asp:ListItem>
+ <asp:ListItem Value="SA">SAUDI ARABIA</asp:ListItem>
+ <asp:ListItem Value="SN">SENEGAL</asp:ListItem>
+ <asp:ListItem Value="RS">SERBIA</asp:ListItem>
+ <asp:ListItem Value="SC">SEYCHELLES</asp:ListItem>
+ <asp:ListItem Value="SL">SIERRA LEONE</asp:ListItem>
+ <asp:ListItem Value="SG">SINGAPORE</asp:ListItem>
+ <asp:ListItem Value="SK">SLOVAKIA</asp:ListItem>
+ <asp:ListItem Value="SI">SLOVENIA</asp:ListItem>
+ <asp:ListItem Value="SB">SOLOMON ISLANDS</asp:ListItem>
+ <asp:ListItem Value="SO">SOMALIA</asp:ListItem>
+ <asp:ListItem Value="ZA">SOUTH AFRICA</asp:ListItem>
+ <asp:ListItem Value="GS">SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS</asp:ListItem>
+ <asp:ListItem Value="ES">SPAIN</asp:ListItem>
+ <asp:ListItem Value="LK">SRI LANKA</asp:ListItem>
+ <asp:ListItem Value="SD">SUDAN</asp:ListItem>
+ <asp:ListItem Value="SR">SURINAME</asp:ListItem>
+ <asp:ListItem Value="SJ">SVALBARD AND JAN MAYEN</asp:ListItem>
+ <asp:ListItem Value="SZ">SWAZILAND</asp:ListItem>
+ <asp:ListItem Value="SE">SWEDEN</asp:ListItem>
+ <asp:ListItem Value="CH">SWITZERLAND</asp:ListItem>
+ <asp:ListItem Value="SY">SYRIAN ARAB REPUBLIC</asp:ListItem>
+ <asp:ListItem Value="TW">TAIWAN, PROVINCE OF CHINA</asp:ListItem>
+ <asp:ListItem Value="TJ">TAJIKISTAN</asp:ListItem>
+ <asp:ListItem Value="TZ">TANZANIA, UNITED REPUBLIC OF</asp:ListItem>
+ <asp:ListItem Value="TH">THAILAND</asp:ListItem>
+ <asp:ListItem Value="TL">TIMOR-LESTE</asp:ListItem>
+ <asp:ListItem Value="TG">TOGO</asp:ListItem>
+ <asp:ListItem Value="TK">TOKELAU</asp:ListItem>
+ <asp:ListItem Value="TO">TONGA</asp:ListItem>
+ <asp:ListItem Value="TT">TRINIDAD AND TOBAGO</asp:ListItem>
+ <asp:ListItem Value="TN">TUNISIA</asp:ListItem>
+ <asp:ListItem Value="TR">TURKEY</asp:ListItem>
+ <asp:ListItem Value="TM">TURKMENISTAN</asp:ListItem>
+ <asp:ListItem Value="TC">TURKS AND CAICOS ISLANDS</asp:ListItem>
+ <asp:ListItem Value="TV">TUVALU</asp:ListItem>
+ <asp:ListItem Value="UG">UGANDA</asp:ListItem>
+ <asp:ListItem Value="UA">UKRAINE</asp:ListItem>
+ <asp:ListItem Value="AE">UNITED ARAB EMIRATES</asp:ListItem>
+ <asp:ListItem Value="GB">UNITED KINGDOM</asp:ListItem>
+ <asp:ListItem Value="US">UNITED STATES</asp:ListItem>
+ <asp:ListItem Value="UM">UNITED STATES MINOR OUTLYING ISLANDS</asp:ListItem>
+ <asp:ListItem Value="UY">URUGUAY</asp:ListItem>
+ <asp:ListItem Value="UZ">UZBEKISTAN</asp:ListItem>
+ <asp:ListItem Value="VU">VANUATU</asp:ListItem>
+ <asp:ListItem Value="VE">VENEZUELA</asp:ListItem>
+ <asp:ListItem Value="VN">VIET NAM</asp:ListItem>
+ <asp:ListItem Value="VG">VIRGIN ISLANDS, BRITISH</asp:ListItem>
+ <asp:ListItem Value="VI">VIRGIN ISLANDS, U.S.</asp:ListItem>
+ <asp:ListItem Value="WF">WALLIS AND FUTUNA</asp:ListItem>
+ <asp:ListItem Value="EH">WESTERN SAHARA</asp:ListItem>
+ <asp:ListItem Value="YE">YEMEN</asp:ListItem>
+ <asp:ListItem Value="ZM">ZAMBIA</asp:ListItem>
+ <asp:ListItem Value="ZW">ZIMBABWE</asp:ListItem>
+ </asp:DropDownList></td>
+ <td style="width: 220px">
+ &nbsp;</td>
+ </tr>
+ <tr runat="server" id="languageRow">
+ <td style="width: 131px">
+ Language
+ <asp:Label ID="languageRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label></td>
+ <td style="width: 300px">
+ <asp:DropDownList ID="languageDropdownList" runat="server">
+ <asp:ListItem Value=""></asp:ListItem>
+ <asp:ListItem Value="EN">English</asp:ListItem>
+ <asp:ListItem Value="AB">Abkhazian</asp:ListItem>
+ <asp:ListItem Value="AA">Afar</asp:ListItem>
+ <asp:ListItem Value="AF">Afrikaans</asp:ListItem>
+ <asp:ListItem Value="SQ">Albanian</asp:ListItem>
+ <asp:ListItem Value="AM">Amharic</asp:ListItem>
+ <asp:ListItem Value="AR">Arabic</asp:ListItem>
+ <asp:ListItem Value="HY">Armenian</asp:ListItem>
+ <asp:ListItem Value="AS">Assamese</asp:ListItem>
+ <asp:ListItem Value="AY">Aymara</asp:ListItem>
+ <asp:ListItem Value="AZ">Azerbaijani</asp:ListItem>
+ <asp:ListItem Value="BA">Bashkir</asp:ListItem>
+ <asp:ListItem Value="EU">Basque</asp:ListItem>
+ <asp:ListItem Value="BN">Bengali</asp:ListItem>
+ <asp:ListItem Value="DZ">Bhutani</asp:ListItem>
+ <asp:ListItem Value="BH">Bihari</asp:ListItem>
+ <asp:ListItem Value="BI">Bislama</asp:ListItem>
+ <asp:ListItem Value="BR">Breton</asp:ListItem>
+ <asp:ListItem Value="BG">Bulgarian</asp:ListItem>
+ <asp:ListItem Value="MY">Burmese</asp:ListItem>
+ <asp:ListItem Value="BE">Byelorussian</asp:ListItem>
+ <asp:ListItem Value="KM">Cambodian</asp:ListItem>
+ <asp:ListItem Value="CA">Catalan</asp:ListItem>
+ <asp:ListItem Value="ZH">Chinese</asp:ListItem>
+ <asp:ListItem Value="CO">Corsican</asp:ListItem>
+ <asp:ListItem Value="HR">Croatian</asp:ListItem>
+ <asp:ListItem Value="CS">Czech</asp:ListItem>
+ <asp:ListItem Value="DA">Danish</asp:ListItem>
+ <asp:ListItem Value="NL">Dutch</asp:ListItem>
+ <asp:ListItem Value="EO">Esperanto</asp:ListItem>
+ <asp:ListItem Value="ET">Estonian</asp:ListItem>
+ <asp:ListItem Value="FO">Faeroese</asp:ListItem>
+ <asp:ListItem Value="FJ">Fiji</asp:ListItem>
+ <asp:ListItem Value="FI">Finnish</asp:ListItem>
+ <asp:ListItem Value="FR">French</asp:ListItem>
+ <asp:ListItem Value="FY">Frisian</asp:ListItem>
+ <asp:ListItem Value="GD">Gaelic</asp:ListItem>
+ <asp:ListItem Value="GL">Galician</asp:ListItem>
+ <asp:ListItem Value="KA">Georgian</asp:ListItem>
+ <asp:ListItem Value="DE">German</asp:ListItem>
+ <asp:ListItem Value="EL">Greek</asp:ListItem>
+ <asp:ListItem Value="KL">Greenlandic</asp:ListItem>
+ <asp:ListItem Value="GN">Guarani</asp:ListItem>
+ <asp:ListItem Value="GU">Gujarati</asp:ListItem>
+ <asp:ListItem Value="HA">Hausa</asp:ListItem>
+ <asp:ListItem Value="IW">Hebrew</asp:ListItem>
+ <asp:ListItem Value="HI">Hindi</asp:ListItem>
+ <asp:ListItem Value="HU">Hungarian</asp:ListItem>
+ <asp:ListItem Value="IS">Icelandic</asp:ListItem>
+ <asp:ListItem Value="IN">Indonesian</asp:ListItem>
+ <asp:ListItem Value="IA">Interlingua</asp:ListItem>
+ <asp:ListItem Value="IE">Interlingue</asp:ListItem>
+ <asp:ListItem Value="IK">Inupiak</asp:ListItem>
+ <asp:ListItem Value="GA">Irish</asp:ListItem>
+ <asp:ListItem Value="IT">Italian</asp:ListItem>
+ <asp:ListItem Value="JA">Japanese</asp:ListItem>
+ <asp:ListItem Value="JW">Javanese</asp:ListItem>
+ <asp:ListItem Value="KN">Kannada</asp:ListItem>
+ <asp:ListItem Value="KS">Kashmiri</asp:ListItem>
+ <asp:ListItem Value="KK">Kazakh</asp:ListItem>
+ <asp:ListItem Value="RW">Kinyarwanda</asp:ListItem>
+ <asp:ListItem Value="KY">Kirghiz</asp:ListItem>
+ <asp:ListItem Value="RN">Kirundi</asp:ListItem>
+ <asp:ListItem Value="KO">Korean</asp:ListItem>
+ <asp:ListItem Value="KU">Kurdish</asp:ListItem>
+ <asp:ListItem Value="LO">Laothian</asp:ListItem>
+ <asp:ListItem Value="LA">Latin</asp:ListItem>
+ <asp:ListItem Value="LV">Latvian</asp:ListItem>
+ <asp:ListItem Value="LN">Lingala</asp:ListItem>
+ <asp:ListItem Value="LT">Lithuanian</asp:ListItem>
+ <asp:ListItem Value="MK">Macedonian</asp:ListItem>
+ <asp:ListItem Value="MG">Malagasy</asp:ListItem>
+ <asp:ListItem Value="MS">Malay</asp:ListItem>
+ <asp:ListItem Value="ML">Malayalam</asp:ListItem>
+ <asp:ListItem Value="MT">Maltese</asp:ListItem>
+ <asp:ListItem Value="MI">Maori</asp:ListItem>
+ <asp:ListItem Value="MR">Marathi</asp:ListItem>
+ <asp:ListItem Value="MO">Moldavian</asp:ListItem>
+ <asp:ListItem Value="MN">Mongolian</asp:ListItem>
+ <asp:ListItem Value="NA">Nauru</asp:ListItem>
+ <asp:ListItem Value="NE">Nepali</asp:ListItem>
+ <asp:ListItem Value="NO">Norwegian</asp:ListItem>
+ <asp:ListItem Value="OC">Occitan</asp:ListItem>
+ <asp:ListItem Value="OR">Oriya</asp:ListItem>
+ <asp:ListItem Value="OM">Oromo</asp:ListItem>
+ <asp:ListItem Value="PS">Pashto</asp:ListItem>
+ <asp:ListItem Value="FA">Persian</asp:ListItem>
+ <asp:ListItem Value="PL">Polish</asp:ListItem>
+ <asp:ListItem Value="PT">Portuguese</asp:ListItem>
+ <asp:ListItem Value="PA">Punjabi</asp:ListItem>
+ <asp:ListItem Value="QU">Quechua</asp:ListItem>
+ <asp:ListItem Value="RM">Rhaeto-Romance</asp:ListItem>
+ <asp:ListItem Value="RO">Romanian</asp:ListItem>
+ <asp:ListItem Value="RU">Russian</asp:ListItem>
+ <asp:ListItem Value="SM">Samoan</asp:ListItem>
+ <asp:ListItem Value="SG">Sangro</asp:ListItem>
+ <asp:ListItem Value="SA">Sanskrit</asp:ListItem>
+ <asp:ListItem Value="SR">Serbian</asp:ListItem>
+ <asp:ListItem Value="SH">Serbo-Croatian</asp:ListItem>
+ <asp:ListItem Value="ST">Sesotho</asp:ListItem>
+ <asp:ListItem Value="TN">Setswana</asp:ListItem>
+ <asp:ListItem Value="SN">Shona</asp:ListItem>
+ <asp:ListItem Value="SD">Sindhi</asp:ListItem>
+ <asp:ListItem Value="SI">Singhalese</asp:ListItem>
+ <asp:ListItem Value="SS">Siswati</asp:ListItem>
+ <asp:ListItem Value="SK">Slovak</asp:ListItem>
+ <asp:ListItem Value="SL">Slovenian</asp:ListItem>
+ <asp:ListItem Value="SO">Somali</asp:ListItem>
+ <asp:ListItem Value="ES">Spanish</asp:ListItem>
+ <asp:ListItem Value="SU">Sudanese</asp:ListItem>
+ <asp:ListItem Value="SW">Swahili</asp:ListItem>
+ <asp:ListItem Value="SV">Swedish</asp:ListItem>
+ <asp:ListItem Value="TL">Tagalog</asp:ListItem>
+ <asp:ListItem Value="TG">Tajik</asp:ListItem>
+ <asp:ListItem Value="TA">Tamil</asp:ListItem>
+ <asp:ListItem Value="TT">Tatar</asp:ListItem>
+ <asp:ListItem Value="TE">Telugu</asp:ListItem>
+ <asp:ListItem Value="TH">Thai</asp:ListItem>
+ <asp:ListItem Value="BO">Tibetan</asp:ListItem>
+ <asp:ListItem Value="TI">Tigrinya</asp:ListItem>
+ <asp:ListItem Value="TO">Tonga</asp:ListItem>
+ <asp:ListItem Value="TS">Tsonga</asp:ListItem>
+ <asp:ListItem Value="TR">Turkish</asp:ListItem>
+ <asp:ListItem Value="TK">Turkmen</asp:ListItem>
+ <asp:ListItem Value="TW">Twi</asp:ListItem>
+ <asp:ListItem Value="UK">Ukrainian</asp:ListItem>
+ <asp:ListItem Value="UR">Urdu</asp:ListItem>
+ <asp:ListItem Value="UZ">Uzbek</asp:ListItem>
+ <asp:ListItem Value="VI">Vietnamese</asp:ListItem>
+ <asp:ListItem Value="VO">Volapuk</asp:ListItem>
+ <asp:ListItem Value="CY">Welsh</asp:ListItem>
+ <asp:ListItem Value="WO">Wolof</asp:ListItem>
+ <asp:ListItem Value="XH">Xhosa</asp:ListItem>
+ <asp:ListItem Value="JI">Yiddish</asp:ListItem>
+ <asp:ListItem Value="YO">Yoruba</asp:ListItem>
+ <asp:ListItem Value="ZU">Zulu</asp:ListItem>
+ </asp:DropDownList>
+ </td>
+ <td style="width: 220px">
+ &nbsp;</td>
+ </tr>
+ <tr runat="server" id="timezoneRow">
+ <td style="width: 131px">
+ Timezone
+ <asp:Label ID="timezoneRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label>
+ </td>
+ <td style="width: 300px">
+ <asp:DropDownList runat="server" ID="timezoneDropdownList">
+ <asp:ListItem Value=""></asp:ListItem>
+ <asp:ListItem Value="Europe/London" >Europe/London</asp:ListItem>
+ <asp:ListItem Value="Africa/Abidjan">Africa/Abidjan</asp:ListItem>
+ <asp:ListItem Value="Africa/Accra">Africa/Accra</asp:ListItem>
+ <asp:ListItem Value="Africa/Addis_Ababa">Africa/Addis_Ababa</asp:ListItem>
+ <asp:ListItem Value="Africa/Algiers">Africa/Algiers</asp:ListItem>
+ <asp:ListItem Value="Africa/Asmera">Africa/Asmera</asp:ListItem>
+ <asp:ListItem Value="Africa/Bamako">Africa/Bamako</asp:ListItem>
+ <asp:ListItem Value="Africa/Bangui">Africa/Bangui</asp:ListItem>
+ <asp:ListItem Value="Africa/Banjul">Africa/Banjul</asp:ListItem>
+ <asp:ListItem Value="Africa/Bissau">Africa/Bissau</asp:ListItem>
+ <asp:ListItem Value="Africa/Blantyre">Africa/Blantyre</asp:ListItem>
+ <asp:ListItem Value="Africa/Brazzaville">Africa/Brazzaville</asp:ListItem>
+ <asp:ListItem Value="Africa/Bujumbura">Africa/Bujumbura</asp:ListItem>
+ <asp:ListItem Value="Africa/Cairo">Africa/Cairo</asp:ListItem>
+ <asp:ListItem Value="Africa/Casablanca">Africa/Casablanca</asp:ListItem>
+ <asp:ListItem Value="Africa/Ceuta">Africa/Ceuta</asp:ListItem>
+ <asp:ListItem Value="Africa/Conakry">Africa/Conakry</asp:ListItem>
+ <asp:ListItem Value="Africa/Dakar">Africa/Dakar</asp:ListItem>
+ <asp:ListItem Value="Africa/Dar_es_Salaam">Africa/Dar_es_Salaam</asp:ListItem>
+ <asp:ListItem Value="Africa/Djibouti">Africa/Djibouti</asp:ListItem>
+ <asp:ListItem Value="Africa/Douala">Africa/Douala</asp:ListItem>
+ <asp:ListItem Value="Africa/El_Aaiun">Africa/El_Aaiun</asp:ListItem>
+ <asp:ListItem Value="Africa/Freetown">Africa/Freetown</asp:ListItem>
+ <asp:ListItem Value="Africa/Gaborone">Africa/Gaborone</asp:ListItem>
+ <asp:ListItem Value="Africa/Harare">Africa/Harare</asp:ListItem>
+ <asp:ListItem Value="Africa/Johannesburg">Africa/Johannesburg</asp:ListItem>
+ <asp:ListItem Value="Africa/Kampala">Africa/Kampala</asp:ListItem>
+ <asp:ListItem Value="Africa/Khartoum">Africa/Khartoum</asp:ListItem>
+ <asp:ListItem Value="Africa/Kigali">Africa/Kigali</asp:ListItem>
+ <asp:ListItem Value="Africa/Kinshasa">Africa/Kinshasa</asp:ListItem>
+ <asp:ListItem Value="Africa/Lagos">Africa/Lagos</asp:ListItem>
+ <asp:ListItem Value="Africa/Libreville">Africa/Libreville</asp:ListItem>
+ <asp:ListItem Value="Africa/Lome">Africa/Lome</asp:ListItem>
+ <asp:ListItem Value="Africa/Luanda">Africa/Luanda</asp:ListItem>
+ <asp:ListItem Value="Africa/Lubumbashi">Africa/Lubumbashi</asp:ListItem>
+ <asp:ListItem Value="Africa/Lusaka">Africa/Lusaka</asp:ListItem>
+ <asp:ListItem Value="Africa/Malabo">Africa/Malabo</asp:ListItem>
+ <asp:ListItem Value="Africa/Maputo">Africa/Maputo</asp:ListItem>
+ <asp:ListItem Value="Africa/Maseru">Africa/Maseru</asp:ListItem>
+ <asp:ListItem Value="Africa/Mbabane">Africa/Mbabane</asp:ListItem>
+ <asp:ListItem Value="Africa/Mogadishu">Africa/Mogadishu</asp:ListItem>
+ <asp:ListItem Value="Africa/Monrovia">Africa/Monrovia</asp:ListItem>
+ <asp:ListItem Value="Africa/Nairobi">Africa/Nairobi</asp:ListItem>
+ <asp:ListItem Value="Africa/Ndjamena">Africa/Ndjamena</asp:ListItem>
+ <asp:ListItem Value="Africa/Niamey">Africa/Niamey</asp:ListItem>
+ <asp:ListItem Value="Africa/Nouakchott">Africa/Nouakchott</asp:ListItem>
+ <asp:ListItem Value="Africa/Ouagadougou">Africa/Ouagadougou</asp:ListItem>
+ <asp:ListItem Value="Africa/Porto">Africa/Porto</asp:ListItem>
+ <asp:ListItem Value="Africa/Sao_Tome">Africa/Sao_Tome</asp:ListItem>
+ <asp:ListItem Value="Africa/Tripoli">Africa/Tripoli</asp:ListItem>
+ <asp:ListItem Value="Africa/Tunis">Africa/Tunis</asp:ListItem>
+ <asp:ListItem Value="Africa/Windhoek">Africa/Windhoek</asp:ListItem>
+ <asp:ListItem Value="America/Adak">America/Adak</asp:ListItem>
+ <asp:ListItem Value="America/Anchorage">America/Anchorage</asp:ListItem>
+ <asp:ListItem Value="America/Anguilla">America/Anguilla</asp:ListItem>
+ <asp:ListItem Value="America/Antigua">America/Antigua</asp:ListItem>
+ <asp:ListItem Value="America/Araguaina">America/Araguaina</asp:ListItem>
+ <asp:ListItem Value="America/Argentina/Buenos_Aires">America/Argentina/Buenos_Aires</asp:ListItem>
+ <asp:ListItem Value="America/Argentina/Catamarca">America/Argentina/Catamarca</asp:ListItem>
+ <asp:ListItem Value="America/Argentina/Cordoba">America/Argentina/Cordoba</asp:ListItem>
+ <asp:ListItem Value="America/Argentina/Jujuy">America/Argentina/Jujuy</asp:ListItem>
+ <asp:ListItem Value="America/Argentina/La_Rioja">America/Argentina/La_Rioja</asp:ListItem>
+ <asp:ListItem Value="America/Argentina/Mendoza">America/Argentina/Mendoza</asp:ListItem>
+ <asp:ListItem Value="America/Argentina/Rio_Gallegos">America/Argentina/Rio_Gallegos</asp:ListItem>
+ <asp:ListItem Value="America/Argentina/San_Juan">America/Argentina/San_Juan</asp:ListItem>
+ <asp:ListItem Value="America/Argentina/Tucuman">America/Argentina/Tucuman</asp:ListItem>
+ <asp:ListItem Value="America/Argentina/Ushuaia">America/Argentina/Ushuaia</asp:ListItem>
+ <asp:ListItem Value="America/Aruba">America/Aruba</asp:ListItem>
+ <asp:ListItem Value="America/Asuncion">America/Asuncion</asp:ListItem>
+ <asp:ListItem Value="America/Bahia">America/Bahia</asp:ListItem>
+ <asp:ListItem Value="America/Barbados">America/Barbados</asp:ListItem>
+ <asp:ListItem Value="America/Belem">America/Belem</asp:ListItem>
+ <asp:ListItem Value="America/Belize">America/Belize</asp:ListItem>
+ <asp:ListItem Value="America/Boa_Vista">America/Boa_Vista</asp:ListItem>
+ <asp:ListItem Value="America/Bogota">America/Bogota</asp:ListItem>
+ <asp:ListItem Value="America/Boise">America/Boise</asp:ListItem>
+ <asp:ListItem Value="America/Cambridge_Bay">America/Cambridge_Bay</asp:ListItem>
+ <asp:ListItem Value="America/Campo_Grande">America/Campo_Grande</asp:ListItem>
+ <asp:ListItem Value="America/Cancun">America/Cancun</asp:ListItem>
+ <asp:ListItem Value="America/Caracas">America/Caracas</asp:ListItem>
+ <asp:ListItem Value="America/Cayenne">America/Cayenne</asp:ListItem>
+ <asp:ListItem Value="America/Cayman">America/Cayman</asp:ListItem>
+ <asp:ListItem Value="America/Chicago">America/Chicago</asp:ListItem>
+ <asp:ListItem Value="America/Chihuahua">America/Chihuahua</asp:ListItem>
+ <asp:ListItem Value="America/Coral_Harbour">America/Coral_Harbour</asp:ListItem>
+ <asp:ListItem Value="America/Costa_Rica">America/Costa_Rica</asp:ListItem>
+ <asp:ListItem Value="America/Cuiaba">America/Cuiaba</asp:ListItem>
+ <asp:ListItem Value="America/Curacao">America/Curacao</asp:ListItem>
+ <asp:ListItem Value="America/Danmarkshavn">America/Danmarkshavn</asp:ListItem>
+ <asp:ListItem Value="America/Dawson">America/Dawson</asp:ListItem>
+ <asp:ListItem Value="America/Dawson_Creek">America/Dawson_Creek</asp:ListItem>
+ <asp:ListItem Value="America/Denver">America/Denver</asp:ListItem>
+ <asp:ListItem Value="America/Detroit">America/Detroit</asp:ListItem>
+ <asp:ListItem Value="America/Dominica">America/Dominica</asp:ListItem>
+ <asp:ListItem Value="America/Edmonton">America/Edmonton</asp:ListItem>
+ <asp:ListItem Value="America/Eirunepe">America/Eirunepe</asp:ListItem>
+ <asp:ListItem Value="America/El_Salvador">America/El_Salvador</asp:ListItem>
+ <asp:ListItem Value="America/Fortaleza">America/Fortaleza</asp:ListItem>
+ <asp:ListItem Value="America/Glace_Bay">America/Glace_Bay</asp:ListItem>
+ <asp:ListItem Value="America/Godthab">America/Godthab</asp:ListItem>
+ <asp:ListItem Value="America/Goose_Bay">America/Goose_Bay</asp:ListItem>
+ <asp:ListItem Value="America/Grand_Turk">America/Grand_Turk</asp:ListItem>
+ <asp:ListItem Value="America/Grenada">America/Grenada</asp:ListItem>
+ <asp:ListItem Value="America/Guadeloupe">America/Guadeloupe</asp:ListItem>
+ <asp:ListItem Value="America/Guatemala">America/Guatemala</asp:ListItem>
+ <asp:ListItem Value="America/Guayaquil">America/Guayaquil</asp:ListItem>
+ <asp:ListItem Value="America/Guyana">America/Guyana</asp:ListItem>
+ <asp:ListItem Value="America/Halifax">America/Halifax</asp:ListItem>
+ <asp:ListItem Value="America/Havana">America/Havana</asp:ListItem>
+ <asp:ListItem Value="America/Hermosillo">America/Hermosillo</asp:ListItem>
+ <asp:ListItem Value="America/Indiana/Indianapolis">America/Indiana/Indianapolis</asp:ListItem>
+ <asp:ListItem Value="America/Indiana/Knox">America/Indiana/Knox</asp:ListItem>
+ <asp:ListItem Value="America/Indiana/Marengo">America/Indiana/Marengo</asp:ListItem>
+ <asp:ListItem Value="America/Indiana/Petersburg">America/Indiana/Petersburg</asp:ListItem>
+ <asp:ListItem Value="America/Indiana/Vevay">America/Indiana/Vevay</asp:ListItem>
+ <asp:ListItem Value="America/Indiana/Vincennes">America/Indiana/Vincennes</asp:ListItem>
+ <asp:ListItem Value="America/Inuvik">America/Inuvik</asp:ListItem>
+ <asp:ListItem Value="America/Iqaluit">America/Iqaluit</asp:ListItem>
+ <asp:ListItem Value="America/Jamaica">America/Jamaica</asp:ListItem>
+ <asp:ListItem Value="America/Juneau">America/Juneau</asp:ListItem>
+ <asp:ListItem Value="America/Kentucky/Louisville">America/Kentucky/Louisville</asp:ListItem>
+ <asp:ListItem Value="America/Kentucky/Monticello">America/Kentucky/Monticello</asp:ListItem>
+ <asp:ListItem Value="America/La_Paz">America/La_Paz</asp:ListItem>
+ <asp:ListItem Value="America/Lima">America/Lima</asp:ListItem>
+ <asp:ListItem Value="America/Los_Angeles">America/Los_Angeles</asp:ListItem>
+ <asp:ListItem Value="America/Maceio">America/Maceio</asp:ListItem>
+ <asp:ListItem Value="America/Managua">America/Managua</asp:ListItem>
+ <asp:ListItem Value="America/Manaus">America/Manaus</asp:ListItem>
+ <asp:ListItem Value="America/Martinique">America/Martinique</asp:ListItem>
+ <asp:ListItem Value="America/Mazatlan">America/Mazatlan</asp:ListItem>
+ <asp:ListItem Value="America/Menominee">America/Menominee</asp:ListItem>
+ <asp:ListItem Value="America/Merida">America/Merida</asp:ListItem>
+ <asp:ListItem Value="America/Mexico_City">America/Mexico_City</asp:ListItem>
+ <asp:ListItem Value="America/Miquelon">America/Miquelon</asp:ListItem>
+ <asp:ListItem Value="America/Moncton">America/Moncton</asp:ListItem>
+ <asp:ListItem Value="America/Monterrey">America/Monterrey</asp:ListItem>
+ <asp:ListItem Value="America/Montevideo">America/Montevideo</asp:ListItem>
+ <asp:ListItem Value="America/Montreal">America/Montreal</asp:ListItem>
+ <asp:ListItem Value="America/Montserrat">America/Montserrat</asp:ListItem>
+ <asp:ListItem Value="America/Nassau">America/Nassau</asp:ListItem>
+ <asp:ListItem Value="America/New_York">America/New_York</asp:ListItem>
+ <asp:ListItem Value="America/Nipigon">America/Nipigon</asp:ListItem>
+ <asp:ListItem Value="America/Nome">America/Nome</asp:ListItem>
+ <asp:ListItem Value="America/Noronha">America/Noronha</asp:ListItem>
+ <asp:ListItem Value="America/North_Dakota/Center">America/North_Dakota/Center</asp:ListItem>
+ <asp:ListItem Value="America/Panama">America/Panama</asp:ListItem>
+ <asp:ListItem Value="America/Pangnirtung">America/Pangnirtung</asp:ListItem>
+ <asp:ListItem Value="America/Paramaribo">America/Paramaribo</asp:ListItem>
+ <asp:ListItem Value="America/Phoenix">America/Phoenix</asp:ListItem>
+ <asp:ListItem Value="America/Port">America/Port</asp:ListItem>
+ <asp:ListItem Value="America/Port_of_Spain">America/Port_of_Spain</asp:ListItem>
+ <asp:ListItem Value="America/Porto_Velho">America/Porto_Velho</asp:ListItem>
+ <asp:ListItem Value="America/Puerto_Rico">America/Puerto_Rico</asp:ListItem>
+ <asp:ListItem Value="America/Rainy_River">America/Rainy_River</asp:ListItem>
+ <asp:ListItem Value="America/Rankin_Inlet">America/Rankin_Inlet</asp:ListItem>
+ <asp:ListItem Value="America/Recife">America/Recife</asp:ListItem>
+ <asp:ListItem Value="America/Regina">America/Regina</asp:ListItem>
+ <asp:ListItem Value="America/Rio_Branco">America/Rio_Branco</asp:ListItem>
+ <asp:ListItem Value="America/Santiago">America/Santiago</asp:ListItem>
+ <asp:ListItem Value="America/Santo_Domingo">America/Santo_Domingo</asp:ListItem>
+ <asp:ListItem Value="America/Sao_Paulo">America/Sao_Paulo</asp:ListItem>
+ <asp:ListItem Value="America/Scoresbysund">America/Scoresbysund</asp:ListItem>
+ <asp:ListItem Value="America/Shiprock">America/Shiprock</asp:ListItem>
+ <asp:ListItem Value="America/St_Johns">America/St_Johns</asp:ListItem>
+ <asp:ListItem Value="America/St_Kitts">America/St_Kitts</asp:ListItem>
+ <asp:ListItem Value="America/St_Lucia">America/St_Lucia</asp:ListItem>
+ <asp:ListItem Value="America/St_Thomas">America/St_Thomas</asp:ListItem>
+ <asp:ListItem Value="America/St_Vincent">America/St_Vincent</asp:ListItem>
+ <asp:ListItem Value="America/Swift_Current">America/Swift_Current</asp:ListItem>
+ <asp:ListItem Value="America/Tegucigalpa">America/Tegucigalpa</asp:ListItem>
+ <asp:ListItem Value="America/Thule">America/Thule</asp:ListItem>
+ <asp:ListItem Value="America/Thunder_Bay">America/Thunder_Bay</asp:ListItem>
+ <asp:ListItem Value="America/Tijuana">America/Tijuana</asp:ListItem>
+ <asp:ListItem Value="America/Toronto">America/Toronto</asp:ListItem>
+ <asp:ListItem Value="America/Tortola">America/Tortola</asp:ListItem>
+ <asp:ListItem Value="America/Vancouver">America/Vancouver</asp:ListItem>
+ <asp:ListItem Value="America/Whitehorse">America/Whitehorse</asp:ListItem>
+ <asp:ListItem Value="America/Winnipeg">America/Winnipeg</asp:ListItem>
+ <asp:ListItem Value="America/Yakutat">America/Yakutat</asp:ListItem>
+ <asp:ListItem Value="America/Yellowknife">America/Yellowknife</asp:ListItem>
+ <asp:ListItem Value="Antarctica/Casey">Antarctica/Casey</asp:ListItem>
+ <asp:ListItem Value="Antarctica/Davis">Antarctica/Davis</asp:ListItem>
+ <asp:ListItem Value="Antarctica/DumontDUrville">Antarctica/DumontDUrville</asp:ListItem>
+ <asp:ListItem Value="Antarctica/Mawson">Antarctica/Mawson</asp:ListItem>
+ <asp:ListItem Value="Antarctica/McMurdo">Antarctica/McMurdo</asp:ListItem>
+ <asp:ListItem Value="Antarctica/Palmer">Antarctica/Palmer</asp:ListItem>
+ <asp:ListItem Value="Antarctica/Rothera">Antarctica/Rothera</asp:ListItem>
+ <asp:ListItem Value="Antarctica/South_Pole">Antarctica/South_Pole</asp:ListItem>
+ <asp:ListItem Value="Antarctica/Syowa">Antarctica/Syowa</asp:ListItem>
+ <asp:ListItem Value="Antarctica/Vostok">Antarctica/Vostok</asp:ListItem>
+ <asp:ListItem Value="Arctic/Longyearbyen">Arctic/Longyearbyen</asp:ListItem>
+ <asp:ListItem Value="Asia/Aden">Asia/Aden</asp:ListItem>
+ <asp:ListItem Value="Asia/Almaty">Asia/Almaty</asp:ListItem>
+ <asp:ListItem Value="Asia/Amman">Asia/Amman</asp:ListItem>
+ <asp:ListItem Value="Asia/Anadyr">Asia/Anadyr</asp:ListItem>
+ <asp:ListItem Value="Asia/Aqtau">Asia/Aqtau</asp:ListItem>
+ <asp:ListItem Value="Asia/Aqtobe">Asia/Aqtobe</asp:ListItem>
+ <asp:ListItem Value="Asia/Ashgabat">Asia/Ashgabat</asp:ListItem>
+ <asp:ListItem Value="Asia/Baghdad">Asia/Baghdad</asp:ListItem>
+ <asp:ListItem Value="Asia/Bahrain">Asia/Bahrain</asp:ListItem>
+ <asp:ListItem Value="Asia/Baku">Asia/Baku</asp:ListItem>
+ <asp:ListItem Value="Asia/Bangkok">Asia/Bangkok</asp:ListItem>
+ <asp:ListItem Value="Asia/Beirut">Asia/Beirut</asp:ListItem>
+ <asp:ListItem Value="Asia/Bishkek">Asia/Bishkek</asp:ListItem>
+ <asp:ListItem Value="Asia/Brunei">Asia/Brunei</asp:ListItem>
+ <asp:ListItem Value="Asia/Calcutta">Asia/Calcutta</asp:ListItem>
+ <asp:ListItem Value="Asia/Choibalsan">Asia/Choibalsan</asp:ListItem>
+ <asp:ListItem Value="Asia/Chongqing">Asia/Chongqing</asp:ListItem>
+ <asp:ListItem Value="Asia/Colombo">Asia/Colombo</asp:ListItem>
+ <asp:ListItem Value="Asia/Damascus">Asia/Damascus</asp:ListItem>
+ <asp:ListItem Value="Asia/Dhaka">Asia/Dhaka</asp:ListItem>
+ <asp:ListItem Value="Asia/Dili">Asia/Dili</asp:ListItem>
+ <asp:ListItem Value="Asia/Dubai">Asia/Dubai</asp:ListItem>
+ <asp:ListItem Value="Asia/Dushanbe">Asia/Dushanbe</asp:ListItem>
+ <asp:ListItem Value="Asia/Gaza">Asia/Gaza</asp:ListItem>
+ <asp:ListItem Value="Asia/Harbin">Asia/Harbin</asp:ListItem>
+ <asp:ListItem Value="Asia/Hong_Kong">Asia/Hong_Kong</asp:ListItem>
+ <asp:ListItem Value="Asia/Hovd">Asia/Hovd</asp:ListItem>
+ <asp:ListItem Value="Asia/Irkutsk">Asia/Irkutsk</asp:ListItem>
+ <asp:ListItem Value="Asia/Jakarta">Asia/Jakarta</asp:ListItem>
+ <asp:ListItem Value="Asia/Jayapura">Asia/Jayapura</asp:ListItem>
+ <asp:ListItem Value="Asia/Jerusalem">Asia/Jerusalem</asp:ListItem>
+ <asp:ListItem Value="Asia/Kabul">Asia/Kabul</asp:ListItem>
+ <asp:ListItem Value="Asia/Kamchatka">Asia/Kamchatka</asp:ListItem>
+ <asp:ListItem Value="Asia/Karachi">Asia/Karachi</asp:ListItem>
+ <asp:ListItem Value="Asia/Kashgar">Asia/Kashgar</asp:ListItem>
+ <asp:ListItem Value="Asia/Katmandu">Asia/Katmandu</asp:ListItem>
+ <asp:ListItem Value="Asia/Krasnoyarsk">Asia/Krasnoyarsk</asp:ListItem>
+ <asp:ListItem Value="Asia/Kuala_Lumpur">Asia/Kuala_Lumpur</asp:ListItem>
+ <asp:ListItem Value="Asia/Kuching">Asia/Kuching</asp:ListItem>
+ <asp:ListItem Value="Asia/Kuwait">Asia/Kuwait</asp:ListItem>
+ <asp:ListItem Value="Asia/Macau">Asia/Macau</asp:ListItem>
+ <asp:ListItem Value="Asia/Magadan">Asia/Magadan</asp:ListItem>
+ <asp:ListItem Value="Asia/Makassar">Asia/Makassar</asp:ListItem>
+ <asp:ListItem Value="Asia/Manila">Asia/Manila</asp:ListItem>
+ <asp:ListItem Value="Asia/Muscat">Asia/Muscat</asp:ListItem>
+ <asp:ListItem Value="Asia/Nicosia">Asia/Nicosia</asp:ListItem>
+ <asp:ListItem Value="Asia/Novosibirsk">Asia/Novosibirsk</asp:ListItem>
+ <asp:ListItem Value="Asia/Omsk">Asia/Omsk</asp:ListItem>
+ <asp:ListItem Value="Asia/Oral">Asia/Oral</asp:ListItem>
+ <asp:ListItem Value="Asia/Phnom_Penh">Asia/Phnom_Penh</asp:ListItem>
+ <asp:ListItem Value="Asia/Pontianak">Asia/Pontianak</asp:ListItem>
+ <asp:ListItem Value="Asia/Pyongyang">Asia/Pyongyang</asp:ListItem>
+ <asp:ListItem Value="Asia/Qatar">Asia/Qatar</asp:ListItem>
+ <asp:ListItem Value="Asia/Qyzylorda">Asia/Qyzylorda</asp:ListItem>
+ <asp:ListItem Value="Asia/Rangoon">Asia/Rangoon</asp:ListItem>
+ <asp:ListItem Value="Asia/Riyadh">Asia/Riyadh</asp:ListItem>
+ <asp:ListItem Value="Asia/Saigon">Asia/Saigon</asp:ListItem>
+ <asp:ListItem Value="Asia/Sakhalin">Asia/Sakhalin</asp:ListItem>
+ <asp:ListItem Value="Asia/Samarkand">Asia/Samarkand</asp:ListItem>
+ <asp:ListItem Value="Asia/Seoul">Asia/Seoul</asp:ListItem>
+ <asp:ListItem Value="Asia/Shanghai">Asia/Shanghai</asp:ListItem>
+ <asp:ListItem Value="Asia/Singapore">Asia/Singapore</asp:ListItem>
+ <asp:ListItem Value="Asia/Taipei">Asia/Taipei</asp:ListItem>
+ <asp:ListItem Value="Asia/Tashkent">Asia/Tashkent</asp:ListItem>
+ <asp:ListItem Value="Asia/Tbilisi">Asia/Tbilisi</asp:ListItem>
+ <asp:ListItem Value="Asia/Tehran">Asia/Tehran</asp:ListItem>
+ <asp:ListItem Value="Asia/Thimphu">Asia/Thimphu</asp:ListItem>
+ <asp:ListItem Value="Asia/Tokyo">Asia/Tokyo</asp:ListItem>
+ <asp:ListItem Value="Asia/Ulaanbaatar">Asia/Ulaanbaatar</asp:ListItem>
+ <asp:ListItem Value="Asia/Urumqi">Asia/Urumqi</asp:ListItem>
+ <asp:ListItem Value="Asia/Vientiane">Asia/Vientiane</asp:ListItem>
+ <asp:ListItem Value="Asia/Vladivostok">Asia/Vladivostok</asp:ListItem>
+ <asp:ListItem Value="Asia/Yakutsk">Asia/Yakutsk</asp:ListItem>
+ <asp:ListItem Value="Asia/Yekaterinburg">Asia/Yekaterinburg</asp:ListItem>
+ <asp:ListItem Value="Asia/Yerevan">Asia/Yerevan</asp:ListItem>
+ <asp:ListItem Value="Atlantic/Azores">Atlantic/Azores</asp:ListItem>
+ <asp:ListItem Value="Atlantic/Bermuda">Atlantic/Bermuda</asp:ListItem>
+ <asp:ListItem Value="Atlantic/Canary">Atlantic/Canary</asp:ListItem>
+ <asp:ListItem Value="Atlantic/Cape_Verde">Atlantic/Cape_Verde</asp:ListItem>
+ <asp:ListItem Value="Atlantic/Faeroe">Atlantic/Faeroe</asp:ListItem>
+ <asp:ListItem Value="Atlantic/Jan_Mayen">Atlantic/Jan_Mayen</asp:ListItem>
+ <asp:ListItem Value="Atlantic/Madeira">Atlantic/Madeira</asp:ListItem>
+ <asp:ListItem Value="Atlantic/Reykjavik">Atlantic/Reykjavik</asp:ListItem>
+ <asp:ListItem Value="Atlantic/South_Georgia">Atlantic/South_Georgia</asp:ListItem>
+ <asp:ListItem Value="Atlantic/St_Helena">Atlantic/St_Helena</asp:ListItem>
+ <asp:ListItem Value="Atlantic/Stanley">Atlantic/Stanley</asp:ListItem>
+ <asp:ListItem Value="Australia/Adelaide">Australia/Adelaide</asp:ListItem>
+ <asp:ListItem Value="Australia/Brisbane">Australia/Brisbane</asp:ListItem>
+ <asp:ListItem Value="Australia/Broken_Hill">Australia/Broken_Hill</asp:ListItem>
+ <asp:ListItem Value="Australia/Currie">Australia/Currie</asp:ListItem>
+ <asp:ListItem Value="Australia/Darwin">Australia/Darwin</asp:ListItem>
+ <asp:ListItem Value="Australia/Hobart">Australia/Hobart</asp:ListItem>
+ <asp:ListItem Value="Australia/Lindeman">Australia/Lindeman</asp:ListItem>
+ <asp:ListItem Value="Australia/Lord_Howe">Australia/Lord_Howe</asp:ListItem>
+ <asp:ListItem Value="Australia/Melbourne">Australia/Melbourne</asp:ListItem>
+ <asp:ListItem Value="Australia/Perth">Australia/Perth</asp:ListItem>
+ <asp:ListItem Value="Australia/Sydney">Australia/Sydney</asp:ListItem>
+ <asp:ListItem Value="Europe/Amsterdam">Europe/Amsterdam</asp:ListItem>
+ <asp:ListItem Value="Europe/Andorra">Europe/Andorra</asp:ListItem>
+ <asp:ListItem Value="Europe/Athens">Europe/Athens</asp:ListItem>
+ <asp:ListItem Value="Europe/Belgrade">Europe/Belgrade</asp:ListItem>
+ <asp:ListItem Value="Europe/Berlin">Europe/Berlin</asp:ListItem>
+ <asp:ListItem Value="Europe/Bratislava">Europe/Bratislava</asp:ListItem>
+ <asp:ListItem Value="Europe/Brussels">Europe/Brussels</asp:ListItem>
+ <asp:ListItem Value="Europe/Bucharest">Europe/Bucharest</asp:ListItem>
+ <asp:ListItem Value="Europe/Budapest">Europe/Budapest</asp:ListItem>
+ <asp:ListItem Value="Europe/Chisinau">Europe/Chisinau</asp:ListItem>
+ <asp:ListItem Value="Europe/Copenhagen">Europe/Copenhagen</asp:ListItem>
+ <asp:ListItem Value="Europe/Dublin">Europe/Dublin</asp:ListItem>
+ <asp:ListItem Value="Europe/Gibraltar">Europe/Gibraltar</asp:ListItem>
+ <asp:ListItem Value="Europe/Helsinki">Europe/Helsinki</asp:ListItem>
+ <asp:ListItem Value="Europe/Istanbul">Europe/Istanbul</asp:ListItem>
+ <asp:ListItem Value="Europe/Kaliningrad">Europe/Kaliningrad</asp:ListItem>
+ <asp:ListItem Value="Europe/Kiev">Europe/Kiev</asp:ListItem>
+ <asp:ListItem Value="Europe/Lisbon">Europe/Lisbon</asp:ListItem>
+ <asp:ListItem Value="Europe/Ljubljana">Europe/Ljubljana</asp:ListItem>
+ <asp:ListItem Value="Europe/Luxembourg">Europe/Luxembourg</asp:ListItem>
+ <asp:ListItem Value="Europe/Madrid">Europe/Madrid</asp:ListItem>
+ <asp:ListItem Value="Europe/Malta">Europe/Malta</asp:ListItem>
+ <asp:ListItem Value="Europe/Mariehamn">Europe/Mariehamn</asp:ListItem>
+ <asp:ListItem Value="Europe/Minsk">Europe/Minsk</asp:ListItem>
+ <asp:ListItem Value="Europe/Monaco">Europe/Monaco</asp:ListItem>
+ <asp:ListItem Value="Europe/Moscow">Europe/Moscow</asp:ListItem>
+ <asp:ListItem Value="Europe/Oslo">Europe/Oslo</asp:ListItem>
+ <asp:ListItem Value="Europe/Paris">Europe/Paris</asp:ListItem>
+ <asp:ListItem Value="Europe/Prague">Europe/Prague</asp:ListItem>
+ <asp:ListItem Value="Europe/Riga">Europe/Riga</asp:ListItem>
+ <asp:ListItem Value="Europe/Rome">Europe/Rome</asp:ListItem>
+ <asp:ListItem Value="Europe/Samara">Europe/Samara</asp:ListItem>
+ <asp:ListItem Value="Europe/San_Marino">Europe/San_Marino</asp:ListItem>
+ <asp:ListItem Value="Europe/Sarajevo">Europe/Sarajevo</asp:ListItem>
+ <asp:ListItem Value="Europe/Simferopol">Europe/Simferopol</asp:ListItem>
+ <asp:ListItem Value="Europe/Skopje">Europe/Skopje</asp:ListItem>
+ <asp:ListItem Value="Europe/Sofia">Europe/Sofia</asp:ListItem>
+ <asp:ListItem Value="Europe/Stockholm">Europe/Stockholm</asp:ListItem>
+ <asp:ListItem Value="Europe/Tallinn">Europe/Tallinn</asp:ListItem>
+ <asp:ListItem Value="Europe/Tirane">Europe/Tirane</asp:ListItem>
+ <asp:ListItem Value="Europe/Uzhgorod">Europe/Uzhgorod</asp:ListItem>
+ <asp:ListItem Value="Europe/Vaduz">Europe/Vaduz</asp:ListItem>
+ <asp:ListItem Value="Europe/Vatican">Europe/Vatican</asp:ListItem>
+ <asp:ListItem Value="Europe/Vienna">Europe/Vienna</asp:ListItem>
+ <asp:ListItem Value="Europe/Vilnius">Europe/Vilnius</asp:ListItem>
+ <asp:ListItem Value="Europe/Warsaw">Europe/Warsaw</asp:ListItem>
+ <asp:ListItem Value="Europe/Zagreb">Europe/Zagreb</asp:ListItem>
+ <asp:ListItem Value="Europe/Zaporozhye">Europe/Zaporozhye</asp:ListItem>
+ <asp:ListItem Value="Europe/Zurich">Europe/Zurich</asp:ListItem>
+ <asp:ListItem Value="Indian/Antananarivo">Indian/Antananarivo</asp:ListItem>
+ <asp:ListItem Value="Indian/Chagos">Indian/Chagos</asp:ListItem>
+ <asp:ListItem Value="Indian/Christmas">Indian/Christmas</asp:ListItem>
+ <asp:ListItem Value="Indian/Cocos">Indian/Cocos</asp:ListItem>
+ <asp:ListItem Value="Indian/Comoro">Indian/Comoro</asp:ListItem>
+ <asp:ListItem Value="Indian/Kerguelen">Indian/Kerguelen</asp:ListItem>
+ <asp:ListItem Value="Indian/Mahe">Indian/Mahe</asp:ListItem>
+ <asp:ListItem Value="Indian/Maldives">Indian/Maldives</asp:ListItem>
+ <asp:ListItem Value="Indian/Mauritius">Indian/Mauritius</asp:ListItem>
+ <asp:ListItem Value="Indian/Mayotte">Indian/Mayotte</asp:ListItem>
+ <asp:ListItem Value="Indian/Reunion">Indian/Reunion</asp:ListItem>
+ <asp:ListItem Value="Pacific/Apia">Pacific/Apia</asp:ListItem>
+ <asp:ListItem Value="Pacific/Auckland">Pacific/Auckland</asp:ListItem>
+ <asp:ListItem Value="Pacific/Chatham">Pacific/Chatham</asp:ListItem>
+ <asp:ListItem Value="Pacific/Easter">Pacific/Easter</asp:ListItem>
+ <asp:ListItem Value="Pacific/Efate">Pacific/Efate</asp:ListItem>
+ <asp:ListItem Value="Pacific/Enderbury">Pacific/Enderbury</asp:ListItem>
+ <asp:ListItem Value="Pacific/Fakaofo">Pacific/Fakaofo</asp:ListItem>
+ <asp:ListItem Value="Pacific/Fiji">Pacific/Fiji</asp:ListItem>
+ <asp:ListItem Value="Pacific/Funafuti">Pacific/Funafuti</asp:ListItem>
+ <asp:ListItem Value="Pacific/Galapagos">Pacific/Galapagos</asp:ListItem>
+ <asp:ListItem Value="Pacific/Gambier">Pacific/Gambier</asp:ListItem>
+ <asp:ListItem Value="Pacific/Guadalcanal">Pacific/Guadalcanal</asp:ListItem>
+ <asp:ListItem Value="Pacific/Guam">Pacific/Guam</asp:ListItem>
+ <asp:ListItem Value="Pacific/Honolulu">Pacific/Honolulu</asp:ListItem>
+ <asp:ListItem Value="Pacific/Johnston">Pacific/Johnston</asp:ListItem>
+ <asp:ListItem Value="Pacific/Kiritimati">Pacific/Kiritimati</asp:ListItem>
+ <asp:ListItem Value="Pacific/Kosrae">Pacific/Kosrae</asp:ListItem>
+ <asp:ListItem Value="Pacific/Kwajalein">Pacific/Kwajalein</asp:ListItem>
+ <asp:ListItem Value="Pacific/Majuro">Pacific/Majuro</asp:ListItem>
+ <asp:ListItem Value="Pacific/Marquesas">Pacific/Marquesas</asp:ListItem>
+ <asp:ListItem Value="Pacific/Midway">Pacific/Midway</asp:ListItem>
+ <asp:ListItem Value="Pacific/Nauru">Pacific/Nauru</asp:ListItem>
+ <asp:ListItem Value="Pacific/Niue">Pacific/Niue</asp:ListItem>
+ <asp:ListItem Value="Pacific/Norfolk">Pacific/Norfolk</asp:ListItem>
+ <asp:ListItem Value="Pacific/Noumea">Pacific/Noumea</asp:ListItem>
+ <asp:ListItem Value="Pacific/Pago_Pago">Pacific/Pago_Pago</asp:ListItem>
+ <asp:ListItem Value="Pacific/Palau">Pacific/Palau</asp:ListItem>
+ <asp:ListItem Value="Pacific/Pitcairn">Pacific/Pitcairn</asp:ListItem>
+ <asp:ListItem Value="Pacific/Ponape">Pacific/Ponape</asp:ListItem>
+ <asp:ListItem Value="Pacific/Port_Moresby">Pacific/Port_Moresby</asp:ListItem>
+ <asp:ListItem Value="Pacific/Rarotonga">Pacific/Rarotonga</asp:ListItem>
+ <asp:ListItem Value="Pacific/Saipan">Pacific/Saipan</asp:ListItem>
+ <asp:ListItem Value="Pacific/Tahiti">Pacific/Tahiti</asp:ListItem>
+ <asp:ListItem Value="Pacific/Tarawa">Pacific/Tarawa</asp:ListItem>
+ <asp:ListItem Value="Pacific/Tongatapu">Pacific/Tongatapu</asp:ListItem>
+ <asp:ListItem Value="Pacific/Truk">Pacific/Truk</asp:ListItem>
+ <asp:ListItem Value="Pacific/Wake">Pacific/Wake</asp:ListItem>
+ <asp:ListItem Value="Pacific/Wallis">Pacific/Wallis</asp:ListItem>
+ </asp:DropDownList>
+ &nbsp;</td>
+ <td style="width: 220px">
+ &nbsp;</td>
+ </tr>
+ <tr>
+ <td style="width: 131px">
+ </td>
+ <td style="width: 300px">
+ </td>
+ <td style="width: 220px">
+ </td>
+ </tr>
+ <tr>
+ <td colspan="3">
+ Note: Fields marked with a * are required by the consumer</td>
+ </tr>
+</table>
diff --git a/source/JanRain.OpenID.ServerPortal/ProfileFields.ascx.cs b/source/JanRain.OpenID.ServerPortal/ProfileFields.ascx.cs
new file mode 100644
index 0000000..dbb5837
--- /dev/null
+++ b/source/JanRain.OpenID.ServerPortal/ProfileFields.ascx.cs
@@ -0,0 +1,110 @@
+using System;
+using System.Net.Mail;
+using Janrain.OpenId.Server;
+using Janrain.OpenId.RegistrationExtension;
+
+/// <summary>
+/// Handles the collection of the simple registration fields.
+/// Only mandatory or optional fields are displayed. Mandatory fields have a '*' next to them.
+/// No validation occurs here.
+/// </summary>
+public partial class ProfileFields : System.Web.UI.UserControl
+{
+ protected void Page_Load(object sender, EventArgs e)
+ {
+
+ }
+
+ public void SetRequiredFieldsFromRequest(CheckIdRequest request)
+ {
+ this.dobRequiredLabel.Visible = (request.RequestBirthdateDefault == ProfileRequest.Require);
+ this.countryRequiredLabel.Visible = (request.RequestCountryDefault == ProfileRequest.Require);
+ this.emailRequiredLabel.Visible = (request.RequestEmailDefault == ProfileRequest.Require);
+ this.fullnameRequiredLabel.Visible = (request.RequestFullNameDefault == ProfileRequest.Require);
+ this.genderRequiredLabel.Visible = (request.RequestGenderDefault == ProfileRequest.Require);
+ this.languageRequiredLabel.Visible = (request.RequestLanguageDefault == ProfileRequest.Require);
+ this.nicknameRequiredLabel.Visible = (request.RequestNicknameDefault == ProfileRequest.Require);
+ this.postcodeRequiredLabel.Visible = (request.RequestPostalCodeDefault == ProfileRequest.Require);
+ this.timezoneRequiredLabel.Visible = (request.RequestTimeZoneDefault == ProfileRequest.Require);
+
+ this.dateOfBirthRow .Visible = !(request.RequestBirthdateDefault == ProfileRequest.NoRequest);
+ this.countryRow.Visible = !(request.RequestCountryDefault == ProfileRequest.NoRequest);
+ this.emailRow.Visible = !(request.RequestEmailDefault == ProfileRequest.NoRequest);
+ this.fullnameRow.Visible = !(request.RequestFullNameDefault == ProfileRequest.NoRequest);
+ this.genderRow.Visible = !(request.RequestGenderDefault == ProfileRequest.NoRequest);
+ this.languageRow.Visible = !(request.RequestLanguageDefault == ProfileRequest.NoRequest);
+ this.nicknameRow.Visible = !(request.RequestNicknameDefault == ProfileRequest.NoRequest);
+ this.postcodeRow.Visible = !(request.RequestPostalCodeDefault == ProfileRequest.NoRequest);
+ this.timezoneRow.Visible = !(request.RequestTimeZoneDefault == ProfileRequest.NoRequest);
+ }
+
+ public bool DoesAnyFieldHaveAValue
+ {
+ get
+ {
+ return !((DateOfBirth == DateTime.MinValue)
+ && String.IsNullOrEmpty(countryDropdownList.SelectedValue)
+ && String.IsNullOrEmpty(emailTextBox.Text)
+ && String.IsNullOrEmpty(fullnameTextBox.Text)
+ && (Gender == null)
+ && String.IsNullOrEmpty(languageDropdownList.SelectedValue)
+ && String.IsNullOrEmpty(nicknameTextBox.Text)
+ && String.IsNullOrEmpty(postcodeTextBox.Text)
+ && String.IsNullOrEmpty(timezoneDropdownList.SelectedValue));
+ }
+ }
+
+ public DateTime DateOfBirth
+ {
+ get
+ {
+ try
+ {
+ int day = Convert.ToInt32(dobDayDropdownlist.SelectedValue);
+ int month = Convert.ToInt32(dobMonthDropdownlist.SelectedValue);
+ int year = Convert.ToInt32(dobYearDropdownlist.SelectedValue);
+ DateTime newDate = new DateTime(year, month, day);
+ return newDate;
+ }
+ catch (Exception)
+ {
+ return DateTime.MinValue;
+ }
+ }
+ }
+
+ public Gender ?Gender
+ {
+ get
+ {
+ if (this.countryDropdownList.SelectedValue == "Male")
+ {
+ return Janrain.OpenId.RegistrationExtension.Gender.Male;
+ }
+ if (this.countryDropdownList.SelectedValue == "Female")
+ {
+ return Janrain.OpenId.RegistrationExtension.Gender.Female;
+ }
+ return null;
+ }
+ }
+
+ public OpenIdProfileFields OpenIdProfileFields
+ {
+ get
+ {
+ OpenIdProfileFields fields = new OpenIdProfileFields();
+ fields.Birthdate = DateOfBirth;
+ fields.Country = countryDropdownList.SelectedValue;
+ fields.Email =emailTextBox.Text;
+ fields.Fullname = fullnameTextBox.Text;
+ fields.Gender = Gender;
+ fields.Language = languageDropdownList.SelectedValue;
+ fields.Nickname = nicknameTextBox.Text;
+ fields.PostalCode = postcodeTextBox.Text;
+ fields.TimeZone = timezoneDropdownList.SelectedValue;
+ return fields;
+ }
+ }
+
+}
diff --git a/source/JanRain.OpenID.ServerPortal/Web.config b/source/JanRain.OpenID.ServerPortal/Web.config
new file mode 100644
index 0000000..3b0236d
--- /dev/null
+++ b/source/JanRain.OpenID.ServerPortal/Web.config
@@ -0,0 +1,121 @@
+<?xml version="1.0"?>
+<!--
+ Note: As an alternative to hand editing this file you can use the
+ web admin tool to configure settings for your application. Use
+ the Website->Asp.Net Configuration option in Visual Studio.
+ A full list of settings and comments can be found in
+ machine.config.comments usually located in
+ \Windows\Microsoft.Net\Framework\v2.x\Config
+-->
+<configuration>
+ <configSections>
+ <sectionGroup name="system.web">
+ <section name="urlrewrites" type="Janrain.OpenId.ServerPortal.URLRewriter"/>
+ </sectionGroup>
+ </configSections>
+
+
+
+ <appSettings/>
+ <connectionStrings/>
+
+ <!--
+ Original version created by Richard Birkby (2002-02-22, http://www.codeproject.com/aspnet/URLRewriter.asp)
+ Maps from old website to new website using Regular Expressions
+ rule/url - old website url (Regular Expression)
+ rule/rewrite - new website replacement expression
+ Of two or more rules which match a given request, the first will always take precedance.
+ -->
+ <system.web>
+ <urlrewrites>
+ <rule>
+ <!-- This rewrites urls like: user/john ->user.aspx?username=john-->
+ <url>/JanRain.OpenID.ServerPortal/user/(.*)</url>
+ <rewrite>/JanRain.OpenID.ServerPortal/user.aspx?username=$1</rewrite>
+ </rule>
+ </urlrewrites>
+ </system.web>
+
+ <system.web>
+ <sessionState mode="InProc" cookieless="false"/>
+
+ <!--
+ Set compilation debug="true" to insert debugging
+ symbols into the compiled page. Because this
+ affects performance, set this value to true only
+ during development.
+ -->
+ <compilation debug="true" >
+ </compilation>
+ <authorization>
+ <!-- This means access to ALL pages requires authentication. Pages can be given explicit authentication further below. -->
+ <deny users="?"/>
+ </authorization>
+ <authentication mode="Forms">
+ <forms name="OpenIdExampleConsumer" loginUrl="~/login.aspx" >
+ <credentials passwordFormat="Clear">
+ <user name="bob" password="test"/>
+ <user name="bob1" password="test"/>
+ <user name="bob2" password="test"/>
+ <user name="bob3" password="test"/>
+ <user name="bob4" password="test"/>
+ </credentials>
+ </forms>
+ </authentication>
+
+ <!--
+ The <customErrors> section enables configuration
+ of what to do if/when an unhandled error occurs
+ during the execution of a request. Specifically,
+ it enables developers to configure html error pages
+ to be displayed in place of a error stack trace.
+ -->
+ <customErrors mode="Off">
+ </customErrors>
+
+ </system.web>
+
+ <!-- All of the following pages may be accessed without needing authentication. Some of them are called server side and some by the user's browser. -->
+ <location path="default.aspx">
+ <!-- The home page doesn't need authentication-->
+ <system.web>
+ <authorization>
+ <allow users="*"/>
+ </authorization>
+ </system.web>
+ </location>
+ <location path="user.aspx">
+ <!-- The user page doesn't have authentication because it hosts the XRDS tags that are parsed via a server side call by the consumer -->
+ <system.web>
+ <authorization>
+ <allow users="*"/>
+ </authorization>
+ </system.web>
+ </location>
+ <!-- The xrds page doesn't have authentication because it hosts the XRDS tags that are parsed via a server side call by the consumer -->
+ <location path="xrds.aspx">
+ <system.web>
+ <authorization>
+ <allow users="*"/>
+ </authorization>
+ </system.web>
+ </location>
+ <!-- The server page doesn't have authentication because it gets called by the consumer via a server side script for all open-id protocol messages-->
+ <location path="server.aspx">
+ <system.web>
+ <authorization>
+ <allow users="*"/>
+ </authorization>
+ </system.web>
+ </location>
+ <!-- Obiously we cannot have authentication on the login page-->
+ <location path="login.aspx">
+ <system.web>
+ <authorization>
+ <allow users="*"/>
+ </authorization>
+ </system.web>
+ </location>
+
+
+</configuration>
diff --git a/source/JanRain.OpenID.ServerPortal/decide.aspx b/source/JanRain.OpenID.ServerPortal/decide.aspx
new file mode 100644
index 0000000..cb46a59
--- /dev/null
+++ b/source/JanRain.OpenID.ServerPortal/decide.aspx
@@ -0,0 +1,39 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="decide.aspx.cs" Inherits="decide" Debug="true" %>
+
+<%@ Register Src="ProfileFields.ascx" TagName="ProfileFields" TagPrefix="uc1" %>
+<html>
+<head>
+ <title>Approve OpenID request?</title>
+</head>
+<body>
+<form id="Form1" runat="server">
+ <p>
+ A site has asked for your identity. If you approve, the site represented by the trust root below will be told that you control identity URL listed below. (If you are using a delegated identity, the site will take care of reversing the delegation on its own.)
+ </p>
+ <table>
+ <tr>
+ <td>
+ Identity:</td>
+ <td>
+ <%=State.Session.LastRequest.IdentityUrl%>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Trust Root:</td>
+ <td>
+ <%=State.Session.LastRequest.TrustRoot%>
+ </td>
+ </tr>
+ </table>
+ <p>
+ Allow this authentication to proceed?</p>
+ <p>
+
+ <uc1:ProfileFields ID="profileFields" runat="server" Visible="false" />
+ &nbsp;</p>
+ <asp:Button ID="yes_button" OnClick="Yes_Click" Text=" yes " CssClass="button" runat="Server" />
+ <asp:Button ID="no_button" OnClick="No_Click" Text=" no " CssClass="button" runat="Server" />
+ </form>
+</body>
+</html>
diff --git a/source/JanRain.OpenID.ServerPortal/decide.aspx.cs b/source/JanRain.OpenID.ServerPortal/decide.aspx.cs
new file mode 100644
index 0000000..86ba467
--- /dev/null
+++ b/source/JanRain.OpenID.ServerPortal/decide.aspx.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Web.Security;
+using System.Web.UI;
+using Janrain.OpenId.Server;
+
+/// <summary>
+/// Page for giving the user the option to continue or cancel out of authentication with a consumer.
+/// </summary>
+public partial class decide : Page
+{
+ protected void Page_Load(object src, EventArgs e)
+ {
+ State.Session.CheckExpectedSateIsAvailable();
+
+ // check that the logged in user is the same as the user requesting authentication to the consumer. If not, then log them out.
+ String s = Util.ExtractUserName(State.Session.LastRequest.IdentityUrl);
+ if (s != User.Identity.Name)
+ {
+ FormsAuthentication.SignOut();
+ Response.Redirect(Request.Url.AbsoluteUri);
+ }
+ else
+ {
+ // if simple registration fields were used, then prompt the user for them
+ if (State.Session.LastRequest.IsAnySimpleRegistrationFieldsRequestedOrRequired)
+ {
+ this.profileFields.Visible = true;
+ this.profileFields.SetRequiredFieldsFromRequest(State.Session.LastRequest);
+ }
+ }
+ }
+
+ ///
+ protected void Yes_Click(Object sender, EventArgs e)
+ {
+ Janrain.OpenId.Server.Response response;
+ if ( this.profileFields.DoesAnyFieldHaveAValue)
+ {
+ // authenticate with simple registration fields
+ response = State.Session.LastRequest.Answer(true, State.ServerUri, this.profileFields.OpenIdProfileFields);
+ }
+ else
+ {
+ // no fields available
+ response = State.Session.LastRequest.Answer(true, State.ServerUri);
+ }
+ Util.GenerateHttpResponse(response);
+ }
+
+ protected void No_Click(Object sender, EventArgs e)
+ {
+ Janrain.OpenId.Server.Response response = State.Session.LastRequest.Answer(false, State.ServerUri);
+ Util.GenerateHttpResponse(response);
+ }
+} \ No newline at end of file
diff --git a/source/JanRain.OpenID.ServerPortal/login.aspx b/source/JanRain.OpenID.ServerPortal/login.aspx
new file mode 100644
index 0000000..3eef2f8
--- /dev/null
+++ b/source/JanRain.OpenID.ServerPortal/login.aspx
@@ -0,0 +1,16 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="login.aspx.cs" Inherits="login" Debug="true"%>
+<html>
+<head>
+ <title>Login</title>
+</head>
+<body>
+ <p class=title>Login</p>
+ <span id="status" class="text" runat="Server"/>
+ <br />Try Bob/Test. Usernames are defined in the web.config
+ <form id="Form1" runat="server">
+ Username: <asp:textbox id=username cssclass="text" runat="Server"/><br/>
+ Password: <asp:textbox id=password textmode=Password cssclass="text" runat="Server"/><br />
+ <asp:button id=login_button onclick="Login_Click" text=" Login " cssclass="button" runat="Server"/>
+ </form>
+</body>
+</html>
diff --git a/source/JanRain.OpenID.ServerPortal/login.aspx.cs b/source/JanRain.OpenID.ServerPortal/login.aspx.cs
new file mode 100644
index 0000000..cf74598
--- /dev/null
+++ b/source/JanRain.OpenID.ServerPortal/login.aspx.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Data;
+using System.Configuration;
+using System.Collections;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+
+/// <summary>
+/// Page for handling logins to this server.
+/// </summary>
+public partial class login : System.Web.UI.Page
+{
+ protected void Page_Load(object src, EventArgs e)
+ {
+ State.Session.CheckExpectedSateIsAvailable();
+
+ String s = Util.ExtractUserName(State.Session.LastRequest.IdentityUrl);
+ if (s != null)
+ {
+ username.Text = s;
+ username.Enabled = false;
+ }
+ }
+
+ protected void Login_Click(Object sender, EventArgs e)
+ {
+ if (FormsAuthentication.Authenticate(username.Text, password.Text))
+ FormsAuthentication.RedirectFromLoginPage(username.Text, true);
+ else
+ status.InnerHtml += "Invalid Login";
+ }
+}
diff --git a/source/JanRain.OpenID.ServerPortal/server.aspx b/source/JanRain.OpenID.ServerPortal/server.aspx
new file mode 100644
index 0000000..374292f
--- /dev/null
+++ b/source/JanRain.OpenID.ServerPortal/server.aspx
@@ -0,0 +1,18 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="server.aspx.cs" Inherits="server" Debug="true"%>
+<html>
+ <head>
+ <title>This is an OpenID server</title>
+ </head>
+ <body>
+ <p><%=Request.Url%> is an OpenID server endpoint.</p>
+ <p>For more information about OpenID, see:</p>
+ <dl>
+ <dt>http://www.openidenabled.com/</dt>
+ <dd>An OpenID community Web site, home of this library</dd>
+ <dt>http://www.openid.net/</dt><dd>the official OpenID Web site</dd>
+ </dl>
+ </body>
+</html>
+<%
+int i = 1;
+%>
diff --git a/source/JanRain.OpenID.ServerPortal/server.aspx.cs b/source/JanRain.OpenID.ServerPortal/server.aspx.cs
new file mode 100644
index 0000000..1488ae1
--- /dev/null
+++ b/source/JanRain.OpenID.ServerPortal/server.aspx.cs
@@ -0,0 +1,96 @@
+using System;
+using System.Data;
+using System.Configuration;
+using System.Collections;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using Janrain.OpenId.Server;
+
+/// <summary>
+/// This is the primary page for this open-id server.
+/// This page is responsible for handling all open-id compliant requests:
+///
+/// CheckIdRequest:
+/// - when openid.mode='checkid_immediate' or openid.mode='checkid_setup'
+/// - this is the initial message request sent to the server via server side call from the server
+/// - this is stored in session in State.Session.LastRequest
+///
+/// AssociateRequest
+/// - when openid.mode='associate'
+/// - this is optionally sent by the consumer who is implementing smart mode to obtain the shared secret before an actual CheckIDRequest
+/// - this is sent via a HTTP server side call from the consumer
+///
+/// CheckAuthRequest
+/// - when open.mode='check_authentication'
+/// - this is request from the consumer to authenticate the user
+/// - this is sent via a HTTP 302 redirect by the consumer
+/// </summary>
+public partial class server : System.Web.UI.Page
+{
+
+ protected Janrain.OpenId.Store.MemoryStore openIDStore;
+ protected Janrain.OpenId.Server.Server openIDServer;
+
+ protected void Page_Load(object src, System.EventArgs evt)
+ {
+
+ openIDStore = Janrain.OpenId.Store.MemoryStore.GetInstance();
+ openIDServer = new Janrain.OpenId.Server.Server(this.openIDStore);
+ Janrain.OpenId.Server.Request request = null;
+
+ // determine what incoming message was received
+ try
+ {
+ if (Request.HttpMethod == "GET")
+
+ request = Decoder.Decode(Request.QueryString);
+ else
+ request = Decoder.Decode(Request.Form);
+ }
+ catch (Janrain.OpenId.Server.ProtocolException e)
+ {
+ Util.GenerateHttpResponse(e);
+ return;
+ }
+ if (request == null) return;
+
+ // process the incoming message appropriately and send the response
+ Janrain.OpenId.Server.Response response = null;
+ if (request is Janrain.OpenId.Server.CheckIdRequest)
+ {
+ Janrain.OpenId.Server.CheckIdRequest idrequest = (Janrain.OpenId.Server.CheckIdRequest)request;
+ if (idrequest.Immediate)
+ {
+ String s = Util.ExtractUserName(idrequest.IdentityUrl);
+ bool allow = (s != User.Identity.Name);
+ response = idrequest.Answer(allow, State.ServerUri);
+ }
+ else
+ {
+ State.Session.LastRequest = (CheckIdRequest)request;
+ Response.Redirect("decide.aspx");
+ }
+ }
+ else if (request is Janrain.OpenId.Server.CheckAuthRequest)
+ {
+ response = this.openIDServer.HandleRequest((Janrain.OpenId.Server.CheckAuthRequest)request);
+ }
+ else if (request is Janrain.OpenId.Server.AssociateRequest)
+ {
+ response = this.openIDServer.HandleRequest((Janrain.OpenId.Server.AssociateRequest)request);
+ }
+ Util.GenerateHttpResponse(response);
+ }
+
+
+
+
+
+
+}
+
+
diff --git a/source/JanRain.OpenID.ServerPortal/user.aspx b/source/JanRain.OpenID.ServerPortal/user.aspx
new file mode 100644
index 0000000..7b40f73
--- /dev/null
+++ b/source/JanRain.OpenID.ServerPortal/user.aspx
@@ -0,0 +1,9 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="user.aspx.cs" Inherits="user" Debug="true"%>
+<html>
+ <head>
+ <link rel="openid.server" href="<%=Server.HtmlEncode(ServerUrl)%>" />
+ </head>
+ <body>
+ <p>OpenID identity page for <%=Server.HtmlEncode(UserName)%></p>
+ </body>
+</html> \ No newline at end of file
diff --git a/source/JanRain.OpenID.ServerPortal/user.aspx.cs b/source/JanRain.OpenID.ServerPortal/user.aspx.cs
new file mode 100644
index 0000000..ccbcd54
--- /dev/null
+++ b/source/JanRain.OpenID.ServerPortal/user.aspx.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Data;
+using System.Configuration;
+using System.Collections;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+
+/// <summary>
+/// This page is a required as part of the service discovery phase of the openid protocol (step 1).
+///
+/// How does a url like http://www.myserver.com/user/bob map to http://www.myserver.com/user.aspx?username=bob ?
+/// Check out gobal.asax and the URLRewriter class. Essentially there's a little framework that allows for URLRewrting using the HttpContext.Current.RewritePath method.
+///
+/// A url such as http://www.myserver.com/user/bob which is entered on the consumer side will cause this page to be invoked.
+/// This page must be parsed by the openid compatible consumer and the url of the openid server is extracted from href in: rel="openid.server" href="?".
+/// It is the responsibility of the consumer to redirect the user to this url.
+///
+/// The XRDS (or Yadis) content is also rendered to provide the consumer with an alternative discovery mechanism. The Yadis protocol allows the consumer
+/// to provide the user with a more flexible range of authentication mechanisms (which ever has been defined in xrds.aspx). See http://en.wikipedia.org/wiki/Yadis.
+/// </summary>
+public partial class user : System.Web.UI.Page
+{
+ protected void Page_Load(object sender, EventArgs e)
+ {
+ }
+
+ public string ServerUrl
+ {
+ get
+ {
+ UriBuilder builder = new UriBuilder(Request.Url);
+ builder.Path = Response.ApplyAppPathModifier("~/server.aspx");
+ builder.Query = null;
+ builder.Port = 79;
+ builder.Fragment = null;
+ return builder.ToString();
+ }
+ }
+
+ /// <summary>
+ /// Gets the name of the user.
+ /// </summary>
+ /// <value>The name of the user.</value>
+ public string UserName
+ {
+ get
+ {
+ return Request.QueryString["username"];
+ }
+ }
+
+ public string XrdsUrl
+ {
+ get
+ {
+ UriBuilder builder = new UriBuilder(Request.Url);
+ builder.Path = Response.ApplyAppPathModifier("~/xrds.aspx");
+ builder.Query = null;
+ builder.Port = 79;
+ builder.Fragment = null;
+ return builder.ToString();
+ }
+ }
+}
diff --git a/source/JanRain.OpenID.ServerPortal/xrds.aspx b/source/JanRain.OpenID.ServerPortal/xrds.aspx
new file mode 100644
index 0000000..22f969f
--- /dev/null
+++ b/source/JanRain.OpenID.ServerPortal/xrds.aspx
@@ -0,0 +1,13 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="xrds.aspx.cs" Inherits="xrds" Debug="true"%><?xml version="1.0" encoding="UTF-8"?>
+<xrds:XRDS
+ xmlns:xrds="xri://$xrds"
+ xmlns:openid="http://openid.net/xmlns/1.0"
+ xmlns="xri://$xrd*($v*2.0)">
+ <XRD>
+ <Service priority="1">
+ <Type>http://openid.net/signon/1.0</Type>
+ <Type>http://openid.net/sreg/1.0</Type>
+ <URI><%=ServerUrl %></URI>
+ </Service>
+ </XRD>
+</xrds:XRDS>
diff --git a/source/JanRain.OpenID.ServerPortal/xrds.aspx.cs b/source/JanRain.OpenID.ServerPortal/xrds.aspx.cs
new file mode 100644
index 0000000..187c7a5
--- /dev/null
+++ b/source/JanRain.OpenID.ServerPortal/xrds.aspx.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Data;
+using System.Configuration;
+using System.Collections;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+
+/// <summary>
+/// This page is a required as part of the service discovery phase of the openid protocol (step 1).
+/// It simply renders the xml for doing service discovery of server.aspx using the xrds mechanism.
+/// This page is obtained by parsing the user.aspx page.
+/// </summary>
+public partial class xrds : System.Web.UI.Page
+{
+ protected void Page_Load(object sender, EventArgs e)
+ {
+ Response.ContentType = "application/xrds+xml";
+ }
+
+ /// <summary>
+ /// Gets the server URL.
+ /// </summary>
+ /// <value>The server URL.</value>
+ public string ServerUrl
+ {
+ get
+ {
+ String path = Response.ApplyAppPathModifier("~/server.aspx"); // ApplyAppPathModifier will convert this path to a fully qualified absolute url
+ UriBuilder builder = new UriBuilder(Request.Url);
+ builder.Path = path;
+ builder.Query = null;
+ builder.Fragment = null;
+ builder.Port = 79;
+ return builder.ToString();
+ }
+ }
+
+}
diff --git a/source/Janrain.OpenId.sln b/source/Janrain.OpenId.sln
index bf8b83d..2ec5036 100644
--- a/source/Janrain.OpenId.sln
+++ b/source/Janrain.OpenId.sln
@@ -5,20 +5,96 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Janrain.OpenId", "Janrain.O
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenIdTests", "OpenIdTests\OpenIdTests.csproj", "{CDEE655B-3902-420E-ADED-F4B6F666FB03}"
EndProject
+Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "http://localhost:79/JanRain.OpenID.ConsumerPortal/", "http://localhost:79/JanRain.OpenID.ConsumerPortal", "{DA9DB98B-A964-475A-8BCF-5436099BB47A}"
+ ProjectSection(WebsiteProperties) = preProject
+ ProjectReferences = "{5D6EDC86-F5B2-4786-8376-4E7C24C63D39}|Janrain.OpenId.dll;"
+ Debug.AspNetCompiler.VirtualPath = "/JanRain.OpenID.ConsumerPortal"
+ Debug.AspNetCompiler.PhysicalPath = "JanRain.OpenID.ConsumerPortal\"
+ Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\JanRain.OpenID.ConsumerPortal\"
+ Debug.AspNetCompiler.Updateable = "true"
+ Debug.AspNetCompiler.ForceOverwrite = "true"
+ Debug.AspNetCompiler.FixedNames = "false"
+ Debug.AspNetCompiler.Debug = "True"
+ Release.AspNetCompiler.VirtualPath = "/JanRain.OpenID.ConsumerPortal"
+ Release.AspNetCompiler.PhysicalPath = "JanRain.OpenID.ConsumerPortal\"
+ Release.AspNetCompiler.TargetPath = "PrecompiledWeb\JanRain.OpenID.ConsumerPortal\"
+ Release.AspNetCompiler.Updateable = "true"
+ Release.AspNetCompiler.ForceOverwrite = "true"
+ Release.AspNetCompiler.FixedNames = "false"
+ Release.AspNetCompiler.Debug = "False"
+ SlnRelativePath = "JanRain.OpenID.ConsumerPortal\"
+ EndProjectSection
+EndProject
+Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "http://localhost:79/JanRain.OpenID.ServerPortal/", "http://localhost:79/JanRain.OpenID.ServerPortal", "{FBDC46AB-B30D-4AA9-B544-286826DA1B3D}"
+ ProjectSection(WebsiteProperties) = preProject
+ ProjectReferences = "{5D6EDC86-F5B2-4786-8376-4E7C24C63D39}|Janrain.OpenId.dll;"
+ Debug.AspNetCompiler.VirtualPath = "/JanRain.OpenID.ServerPortal"
+ Debug.AspNetCompiler.PhysicalPath = "JanRain.OpenID.ServerPortal\"
+ Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\JanRain.OpenID.ServerPortal\"
+ Debug.AspNetCompiler.Updateable = "true"
+ Debug.AspNetCompiler.ForceOverwrite = "true"
+ Debug.AspNetCompiler.FixedNames = "false"
+ Debug.AspNetCompiler.Debug = "True"
+ Release.AspNetCompiler.VirtualPath = "/JanRain.OpenID.ServerPortal"
+ Release.AspNetCompiler.PhysicalPath = "JanRain.OpenID.ServerPortal\"
+ Release.AspNetCompiler.TargetPath = "PrecompiledWeb\JanRain.OpenID.ServerPortal\"
+ Release.AspNetCompiler.Updateable = "true"
+ Release.AspNetCompiler.ForceOverwrite = "true"
+ Release.AspNetCompiler.FixedNames = "false"
+ Release.AspNetCompiler.Debug = "False"
+ SlnRelativePath = "JanRain.OpenID.ServerPortal\"
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|.NET = Debug|.NET
Debug|Any CPU = Debug|Any CPU
+ Debug|Mixed Platforms = Debug|Mixed Platforms
+ Release|.NET = Release|.NET
Release|Any CPU = Release|Any CPU
+ Release|Mixed Platforms = Release|Mixed Platforms
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5D6EDC86-F5B2-4786-8376-4E7C24C63D39}.Debug|.NET.ActiveCfg = Debug|Any CPU
{5D6EDC86-F5B2-4786-8376-4E7C24C63D39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5D6EDC86-F5B2-4786-8376-4E7C24C63D39}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5D6EDC86-F5B2-4786-8376-4E7C24C63D39}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {5D6EDC86-F5B2-4786-8376-4E7C24C63D39}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {5D6EDC86-F5B2-4786-8376-4E7C24C63D39}.Release|.NET.ActiveCfg = Release|Any CPU
{5D6EDC86-F5B2-4786-8376-4E7C24C63D39}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5D6EDC86-F5B2-4786-8376-4E7C24C63D39}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5D6EDC86-F5B2-4786-8376-4E7C24C63D39}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {5D6EDC86-F5B2-4786-8376-4E7C24C63D39}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {CDEE655B-3902-420E-ADED-F4B6F666FB03}.Debug|.NET.ActiveCfg = Debug|Any CPU
{CDEE655B-3902-420E-ADED-F4B6F666FB03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CDEE655B-3902-420E-ADED-F4B6F666FB03}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CDEE655B-3902-420E-ADED-F4B6F666FB03}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {CDEE655B-3902-420E-ADED-F4B6F666FB03}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {CDEE655B-3902-420E-ADED-F4B6F666FB03}.Release|.NET.ActiveCfg = Release|Any CPU
{CDEE655B-3902-420E-ADED-F4B6F666FB03}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CDEE655B-3902-420E-ADED-F4B6F666FB03}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CDEE655B-3902-420E-ADED-F4B6F666FB03}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {CDEE655B-3902-420E-ADED-F4B6F666FB03}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {DA9DB98B-A964-475A-8BCF-5436099BB47A}.Debug|.NET.ActiveCfg = Debug|.NET
+ {DA9DB98B-A964-475A-8BCF-5436099BB47A}.Debug|.NET.Build.0 = Debug|.NET
+ {DA9DB98B-A964-475A-8BCF-5436099BB47A}.Debug|Any CPU.ActiveCfg = Debug|.NET
+ {DA9DB98B-A964-475A-8BCF-5436099BB47A}.Debug|Mixed Platforms.ActiveCfg = Debug|.NET
+ {DA9DB98B-A964-475A-8BCF-5436099BB47A}.Debug|Mixed Platforms.Build.0 = Debug|.NET
+ {DA9DB98B-A964-475A-8BCF-5436099BB47A}.Release|.NET.ActiveCfg = Debug|.NET
+ {DA9DB98B-A964-475A-8BCF-5436099BB47A}.Release|.NET.Build.0 = Debug|.NET
+ {DA9DB98B-A964-475A-8BCF-5436099BB47A}.Release|Any CPU.ActiveCfg = Debug|.NET
+ {DA9DB98B-A964-475A-8BCF-5436099BB47A}.Release|Mixed Platforms.ActiveCfg = Debug|.NET
+ {DA9DB98B-A964-475A-8BCF-5436099BB47A}.Release|Mixed Platforms.Build.0 = Debug|.NET
+ {FBDC46AB-B30D-4AA9-B544-286826DA1B3D}.Debug|.NET.ActiveCfg = Debug|.NET
+ {FBDC46AB-B30D-4AA9-B544-286826DA1B3D}.Debug|.NET.Build.0 = Debug|.NET
+ {FBDC46AB-B30D-4AA9-B544-286826DA1B3D}.Debug|Any CPU.ActiveCfg = Debug|.NET
+ {FBDC46AB-B30D-4AA9-B544-286826DA1B3D}.Debug|Mixed Platforms.ActiveCfg = Debug|.NET
+ {FBDC46AB-B30D-4AA9-B544-286826DA1B3D}.Debug|Mixed Platforms.Build.0 = Debug|.NET
+ {FBDC46AB-B30D-4AA9-B544-286826DA1B3D}.Release|.NET.ActiveCfg = Debug|.NET
+ {FBDC46AB-B30D-4AA9-B544-286826DA1B3D}.Release|.NET.Build.0 = Debug|.NET
+ {FBDC46AB-B30D-4AA9-B544-286826DA1B3D}.Release|Any CPU.ActiveCfg = Debug|.NET
+ {FBDC46AB-B30D-4AA9-B544-286826DA1B3D}.Release|Mixed Platforms.ActiveCfg = Debug|.NET
+ {FBDC46AB-B30D-4AA9-B544-286826DA1B3D}.Release|Mixed Platforms.Build.0 = Debug|.NET
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/source/Janrain.OpenId/Association.cs b/source/Janrain.OpenId/Association.cs
index 98ea77d..7ac9264 100644
--- a/source/Janrain.OpenId/Association.cs
+++ b/source/Janrain.OpenId/Association.cs
@@ -129,6 +129,7 @@ namespace Janrain.OpenId
this.Handle = handle;
this.key = secret;
this.Issued = UNIX_EPOCH.Add(new TimeSpan(0, 0, Convert.ToInt32((DateTime.Now - UNIX_EPOCH).TotalSeconds)));
+ this.expiresIn = expiresIn;
}
public HMACSHA1Association(IDictionary kvpairs)
diff --git a/source/Janrain.OpenId/Consumer/Fetcher.cs b/source/Janrain.OpenId/Consumer/Fetcher.cs
index 86e4fa0..f7e8ad1 100644
--- a/source/Janrain.OpenId/Consumer/Fetcher.cs
+++ b/source/Janrain.OpenId/Consumer/Fetcher.cs
@@ -14,33 +14,38 @@ namespace Janrain.OpenId.Consumer
{
MemoryStream ms = null;
Stream stream = resp.GetResponseStream();
- int length = (int)resp.ContentLength;
- bool nolength = (length == (-1));
- int size = (nolength ? 8192 : length);
- if (nolength)
- ms = new MemoryStream();
+
+
+ buffer = Util.ReadAndClose(stream);
+ return buffer.Length;
+
+ //int length = (int)resp.ContentLength;
+ //bool nolength = (length == (-1));
+ //int size = (nolength ? 8192 : length);
+ //if (nolength)
+ // ms = new MemoryStream();
- size = Math.Min(size, (int)max_bytes);
- int nread = 0;
- int offset = 0;
- buffer = new byte[size];
- while ((nread = stream.Read(buffer, offset, size)) != 0)
- {
- if (nolength)
- ms.Write(buffer, 0, nread);
- else
- {
- size -= nread;
- offset += nread;
- }
- }
+ //size = Math.Min(size, (int)max_bytes);
+ //int nread = 0;
+ //int offset = 0;
+ //buffer = new byte[size];
+ //while ((nread = stream.Read(buffer, offset, size)) != 0)
+ //{
+ // if (nolength)
+ // ms.Write(buffer, 0, nread);
+ // else
+ // {
+ // size -= nread;
+ // offset += nread;
+ // }
+ //}
- if (nolength)
- {
- buffer = ms.ToArray();
- offset = buffer.Length;
- }
- return offset;
+ //if (nolength)
+ //{
+ // buffer = ms.ToArray();
+ // offset = buffer.Length;
+ //}
+ //return offset;
}
protected static FetchResponse GetResponse(HttpWebResponse resp, uint maxRead)
diff --git a/source/Janrain.OpenId/Consumer/OpenIdLogin.cs b/source/Janrain.OpenId/Consumer/OpenIdLogin.cs
index 6a37856..9edc19f 100644
--- a/source/Janrain.OpenId/Consumer/OpenIdLogin.cs
+++ b/source/Janrain.OpenId/Consumer/OpenIdLogin.cs
@@ -14,6 +14,7 @@ using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Web.Security;
+using Janrain.OpenId.RegistrationExtension;
namespace NerdBank.OpenId.Consumer
{
@@ -94,12 +95,13 @@ namespace NerdBank.OpenId.Consumer
requiredValidator.ControlToValidate = WrappedTextBox.ID;
requiredValidator.ValidationGroup = validationGroupDefault;
cell.Controls.Add(requiredValidator);
- uriFormatValidator = new RegularExpressionValidator();
- uriFormatValidator.ErrorMessage = uriFormatTextDefault + requiredTextSuffix;
- uriFormatValidator.ValidationExpression = @"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?";
- uriFormatValidator.Display = ValidatorDisplay.Dynamic;
- uriFormatValidator.ControlToValidate = WrappedTextBox.ID;
- uriFormatValidator.ValidationGroup = validationGroupDefault;
+ uriFormatValidator = new RegularExpressionValidator();
+ uriFormatValidator.ErrorMessage = uriFormatTextDefault + requiredTextSuffix;
+ uriFormatValidator.ValidationExpression = @"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?";
+ uriFormatValidator.Enabled = false;
+ uriFormatValidator.Display = ValidatorDisplay.Dynamic;
+ uriFormatValidator.ControlToValidate = WrappedTextBox.ID;
+ uriFormatValidator.ValidationGroup = validationGroupDefault;
cell.Controls.Add(uriFormatValidator);
examplePrefixLabel = new Label();
examplePrefixLabel.Text = examplePrefixDefault;
@@ -276,7 +278,7 @@ namespace NerdBank.OpenId.Consumer
{
EventHandler<OpenIdTextBox.OpenIdEventArgs> loggingIn = LoggingIn;
OpenIdTextBox.OpenIdEventArgs args = new OpenIdTextBox.OpenIdEventArgs(openIdUri,
- OpenIdTextBox.OpenIdProfileFields.Empty);
+ OpenIdProfileFields.Empty);
if (loggingIn != null)
loggingIn(this, args);
return !args.Cancel;
diff --git a/source/Janrain.OpenId/Consumer/OpenIdTextBox.cs b/source/Janrain.OpenId/Consumer/OpenIdTextBox.cs
index 43b35ce..3e8af71 100644
--- a/source/Janrain.OpenId/Consumer/OpenIdTextBox.cs
+++ b/source/Janrain.OpenId/Consumer/OpenIdTextBox.cs
@@ -21,8 +21,17 @@ using System.Web.UI.WebControls;
using Janrain.OpenId;
using Janrain.OpenId.Consumer;
+using Janrain.OpenId.RegistrationExtension;
using Janrain.OpenId.Store;
+namespace NerdBank.OpenId.RegistrationExtension
+{
+}
+
+namespace Janrain.OpenId.RegistrationExtension
+{
+}
+
namespace NerdBank.OpenId.Consumer
{
[DefaultProperty("Text")]
@@ -103,14 +112,7 @@ namespace NerdBank.OpenId.Consumer
set { WrappedTextBox.Columns = value; }
}
- public enum ProfileRequest
- {
- NoRequest,
- Request,
- Require,
- }
-
- const string requestNicknameViewStateKey = "RequestNickname";
+ const string requestNicknameViewStateKey = "RequestNickname";
const ProfileRequest requestNicknameDefault = ProfileRequest.NoRequest;
[Bindable(true)]
[Category("Profile")]
@@ -133,7 +135,7 @@ namespace NerdBank.OpenId.Consumer
}
const string requestFullNameViewStateKey = "RequestFullName";
- const ProfileRequest requestFullNameDefault = ProfileRequest.NoRequest;
+ const ProfileRequest requestFullNameDefault = ProfileRequest.NoRequest;
[Bindable(true)]
[Category("Profile")]
[DefaultValue(requestFullNameDefault)]
@@ -304,6 +306,7 @@ namespace NerdBank.OpenId.Consumer
{
base.OnLoad(e);
+
try
{
if (!Page.IsPostBack && Page.Request.QueryString["openid.mode"] != null)
@@ -348,12 +351,12 @@ namespace NerdBank.OpenId.Consumer
string trustRoot = builder.ToString();
// Build the return_to URL
- builder = new UriBuilder(Page.Request.Url.AbsoluteUri);
- NameValueCollection col = new NameValueCollection();
+ builder = new UriBuilder(Page.Request.Url.AbsoluteUri);
if (!string.IsNullOrEmpty(Page.Request.QueryString["ReturnUrl"]))
- col["ReturnUrl"] = Page.Request.QueryString["ReturnUrl"];
- builder.Query = UriUtil.CreateQueryString(col);
- Uri returnTo = new Uri(builder.ToString(), true);
+ {
+ builder.Query = "ReturnUrl=" + Page.Request.QueryString["ReturnUrl"];
+ }
+ Uri returnTo = new Uri(builder.ToString());
Uri redirectUrl = request.CreateRedirect(trustRoot, returnTo, AuthRequest.Mode.SETUP);
Page.Response.Redirect(redirectUrl.AbsoluteUri);
@@ -361,17 +364,15 @@ namespace NerdBank.OpenId.Consumer
void addProfileArgs(AuthRequest request)
{
- request.ExtraArgs.Add("openid.sreg.required",
- string.Join(",", assembleProfileFields(ProfileRequest.Require)));
- request.ExtraArgs.Add("openid.sreg.optional",
- string.Join(",", assembleProfileFields(ProfileRequest.Request)));
+ request.ExtraArgs.Add("openid.sreg.required", string.Join(",", assembleProfileFields(ProfileRequest.Require)));
+ request.ExtraArgs.Add("openid.sreg.optional", string.Join(",", assembleProfileFields(ProfileRequest.Request)));
request.ExtraArgs.Add("openid.sreg.policy_url", PolicyUrl);
}
string[] assembleProfileFields(ProfileRequest level)
{
List<string> fields = new List<string>(10);
- if (RequestNickname == level)
+ if (RequestNickname == level)
fields.Add("nickname");
if (RequestEmail == level)
fields.Add("email");
@@ -397,9 +398,8 @@ namespace NerdBank.OpenId.Consumer
OpenIdProfileFields fields = new OpenIdProfileFields();
if (RequestNickname > ProfileRequest.NoRequest)
fields.Nickname = queryString["openid.sreg.nickname"];
- if (RequestEmail > ProfileRequest.NoRequest &&
- !string.IsNullOrEmpty(queryString["openid.sreg.email"]))
- fields.Email = new MailAddress(queryString["openid.sreg.email"]);
+ if (RequestEmail > ProfileRequest.NoRequest)
+ fields.Email = queryString["openid.sreg.email"];
if (RequestFullName > ProfileRequest.NoRequest)
fields.Fullname = queryString["openid.sreg.fullname"];
if (RequestBirthdate > ProfileRequest.NoRequest)
@@ -436,88 +436,7 @@ namespace NerdBank.OpenId.Consumer
return fields;
}
- public enum Gender
- {
- Male,
- Female,
- }
-
- public struct OpenIdProfileFields
- {
- internal static OpenIdProfileFields Empty = new OpenIdProfileFields();
-
- private string nickname;
- public string Nickname
- {
- get { return nickname; }
- set { nickname = value; }
- }
-
- private MailAddress email;
- public MailAddress Email
- {
- get { return email; }
- set { email = value; }
- }
-
- private string fullName;
- public string Fullname
- {
- get { return fullName; }
- set { fullName = value; }
- }
-
- private DateTime? birthdate;
- public DateTime? Birthdate
- {
- get { return birthdate; }
- set { birthdate = value; }
- }
-
- private Gender? gender;
- public Gender? Gender
- {
- get { return gender; }
- set { gender = value; }
- }
-
- private string postalCode;
- public string PostalCode
- {
- get { return postalCode; }
- set { postalCode = value; }
- }
-
- private string country;
- public string Country
- {
- get { return country; }
- set { country = value; }
- }
-
- private string language;
- public string Language
- {
- get { return language; }
- set { language = value; }
- }
-
- private CultureInfo culture;
- public CultureInfo Culture
- {
- get { return culture; }
- set { culture = value; }
- }
-
- private string timeZone;
- public string TimeZone
- {
- get { return timeZone; }
- set { timeZone = value; }
- }
- }
-
- #region Events
+ #region Events
public class OpenIdEventArgs : EventArgs
{
public OpenIdEventArgs(Uri openIdUri, OpenIdProfileFields profileFields)
diff --git a/source/Janrain.OpenId/Consumer/Util.cs b/source/Janrain.OpenId/Consumer/Util.cs
new file mode 100644
index 0000000..d1fa94e
--- /dev/null
+++ b/source/Janrain.OpenId/Consumer/Util.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace Janrain.OpenId.Consumer
+{
+ public class Util
+ {
+ public static byte[] ReadAndClose(Stream stream)
+ {
+ StreamReader sr = new StreamReader(stream, Encoding.UTF8);
+ List<byte> bytes = new List<byte>();
+ int byteValue = 0;
+ bool keepReading = true;
+ while (keepReading)
+ {
+ try
+ {
+ byteValue = sr.Read();
+ if (byteValue == -1)
+ {
+ keepReading = false;
+ }
+ else
+ {
+ bytes.Add(Convert.ToByte(byteValue));
+ }
+
+ }
+ catch (Exception)
+ {
+ keepReading = false;
+ }
+ }
+ stream.Close();
+ byte[] allbytes = bytes.ToArray();
+ return allbytes;
+ }
+ }
+}
diff --git a/source/Janrain.OpenId/Janrain.OpenId.csproj b/source/Janrain.OpenId/Janrain.OpenId.csproj
index f9eca29..50bd2ac 100644
--- a/source/Janrain.OpenId/Janrain.OpenId.csproj
+++ b/source/Janrain.OpenId/Janrain.OpenId.csproj
@@ -43,12 +43,16 @@
<Compile Include="Consumer\Fetcher.cs" />
<Compile Include="Consumer\FetchException.cs" />
<Compile Include="Consumer\FetchResponse.cs" />
+ <Compile Include="RegistrationExtension\Gender.cs" />
<Compile Include="Consumer\GenericConsumer.cs" />
<Compile Include="Consumer\Manager.cs" />
<Compile Include="Consumer\OpenIdLogin.cs" />
+ <Compile Include="RegistrationExtension\OpenIdProfileFields.cs" />
<Compile Include="Consumer\OpenIdTextBox.cs" />
+ <Compile Include="RegistrationExtension\ProfileRequest.cs" />
<Compile Include="Consumer\ServiceEndpoint.cs" />
<Compile Include="Consumer\SimpleFetcher.cs" />
+ <Compile Include="Consumer\Util.cs" />
<Compile Include="CryptUtil.cs" />
<Compile Include="DiffieHellman\DHKeyGeneration.cs" />
<Compile Include="DiffieHellman\DHParameters.cs" />
diff --git a/source/Janrain.OpenId/RegistrationExtension/Gender.cs b/source/Janrain.OpenId/RegistrationExtension/Gender.cs
new file mode 100644
index 0000000..8a1d6da
--- /dev/null
+++ b/source/Janrain.OpenId/RegistrationExtension/Gender.cs
@@ -0,0 +1,8 @@
+namespace Janrain.OpenId.RegistrationExtension
+{
+ public enum Gender
+ {
+ Male,
+ Female,
+ }
+} \ No newline at end of file
diff --git a/source/Janrain.OpenId/RegistrationExtension/OpenIdProfileFields.cs b/source/Janrain.OpenId/RegistrationExtension/OpenIdProfileFields.cs
new file mode 100644
index 0000000..a3ba23b
--- /dev/null
+++ b/source/Janrain.OpenId/RegistrationExtension/OpenIdProfileFields.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Globalization;
+using System.Net.Mail;
+using Janrain.OpenId.RegistrationExtension;
+
+namespace Janrain.OpenId.RegistrationExtension
+{
+ [Serializable()]
+ public class OpenIdProfileFields
+ {
+ internal static OpenIdProfileFields Empty = new OpenIdProfileFields();
+
+ private string nickname;
+ public string Nickname
+ {
+ get { return nickname; }
+ set { nickname = value; }
+ }
+
+ private string email;
+ public string Email
+ {
+ get { return email; }
+ set { email = value; }
+ }
+
+ private string fullName;
+ public string Fullname
+ {
+ get { return fullName; }
+ set { fullName = value; }
+ }
+
+ private DateTime? birthdate;
+ public DateTime? Birthdate
+ {
+ get { return birthdate; }
+ set { birthdate = value; }
+ }
+
+ private Gender? gender;
+ public Gender? Gender
+ {
+ get { return gender; }
+ set { gender = value; }
+ }
+
+ private string postalCode;
+ public string PostalCode
+ {
+ get { return postalCode; }
+ set { postalCode = value; }
+ }
+
+ private string country;
+ public string Country
+ {
+ get { return country; }
+ set { country = value; }
+ }
+
+ private string language;
+ public string Language
+ {
+ get { return language; }
+ set { language = value; }
+ }
+
+ private CultureInfo culture;
+ public CultureInfo Culture
+ {
+ get { return culture; }
+ set { culture = value; }
+ }
+
+ private string timeZone;
+ public string TimeZone
+ {
+ get { return timeZone; }
+ set { timeZone = value; }
+ }
+ }
+} \ No newline at end of file
diff --git a/source/Janrain.OpenId/RegistrationExtension/ProfileRequest.cs b/source/Janrain.OpenId/RegistrationExtension/ProfileRequest.cs
new file mode 100644
index 0000000..0612aed
--- /dev/null
+++ b/source/Janrain.OpenId/RegistrationExtension/ProfileRequest.cs
@@ -0,0 +1,9 @@
+namespace Janrain.OpenId.RegistrationExtension
+{
+ public enum ProfileRequest
+ {
+ NoRequest,
+ Request,
+ Require,
+ }
+} \ No newline at end of file
diff --git a/source/Janrain.OpenId/Server/CheckIdRequest.cs b/source/Janrain.OpenId/Server/CheckIdRequest.cs
index f5cbad3..82c5665 100644
--- a/source/Janrain.OpenId/Server/CheckIdRequest.cs
+++ b/source/Janrain.OpenId/Server/CheckIdRequest.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections;
using System.Collections.Specialized;
using System.Text;
+using Janrain.OpenId.RegistrationExtension;
namespace Janrain.OpenId.Server
{
@@ -16,6 +17,17 @@ namespace Janrain.OpenId.Server
private Uri _identity;
private string _mode;
private Uri _return_to;
+ private Uri _policyUrl;
+
+ private ProfileRequest requestNicknameDefault = ProfileRequest.NoRequest;
+ private ProfileRequest requestEmailDefault = ProfileRequest.NoRequest;
+ private ProfileRequest requestFullNameDefault = ProfileRequest.NoRequest;
+ private ProfileRequest requestBirthdateDefault = ProfileRequest.NoRequest;
+ private ProfileRequest requestGenderDefault = ProfileRequest.NoRequest;
+ private ProfileRequest requestPostalCodeDefault = ProfileRequest.NoRequest;
+ private ProfileRequest requestCountryDefault = ProfileRequest.NoRequest;
+ private ProfileRequest requestLanguageDefault = ProfileRequest.NoRequest;
+ private ProfileRequest requestTimeZoneDefault = ProfileRequest.NoRequest;
#endregion
@@ -55,6 +67,7 @@ namespace Janrain.OpenId.Server
public CheckIdRequest(NameValueCollection query)
{
+ // handle the mandatory protocol fields
string mode = query["openid.mode"];
if (mode == "checkid_immediate")
@@ -107,6 +120,27 @@ namespace Janrain.OpenId.Server
if (!TrustRootValid)
throw new UntrustedReturnUrl(query, _return_to, _trust_root);
+
+ // Handle the optional Simple Registration extension fields
+ string policyUrl = GetSimpleRegistrationExtensionField(query, "policy_url");
+ if (!String.IsNullOrEmpty(policyUrl))
+ {
+ _policyUrl = new Uri(policyUrl);
+ }
+
+ string optionalFields = GetSimpleRegistrationExtensionField(query, "optional");
+ if (!String.IsNullOrEmpty(optionalFields))
+ {
+ string[] splitOptionalFields = optionalFields.Split(',');
+ setSimpleRegistrationExtensionFields(splitOptionalFields, ProfileRequest.Request);
+ }
+
+ string requiredFields = GetSimpleRegistrationExtensionField(query, "required");
+ if (!String.IsNullOrEmpty(requiredFields))
+ {
+ string[] splitRrequiredFields = requiredFields.Split(',');
+ setSimpleRegistrationExtensionFields(splitRrequiredFields, ProfileRequest.Require);
+ }
}
#endregion
@@ -123,12 +157,79 @@ namespace Janrain.OpenId.Server
return value;
}
+ private string GetSimpleRegistrationExtensionField(NameValueCollection query, string field)
+ {
+ string value = query.Get("openid.sreg." + field);
+ return value;
+ }
+
+
+ private void setSimpleRegistrationExtensionFields(string[] fields, ProfileRequest request)
+ {
+ foreach (string field in fields)
+ {
+ switch (field)
+ {
+ case "nickname":
+ {
+ this.requestNicknameDefault = request;
+ break;
+ }
+ case "email":
+ {
+ this.requestEmailDefault = request;
+ break;
+ }
+ case "fullname":
+ {
+ this.requestFullNameDefault = request;
+ break;
+ }
+ case "dob":
+ {
+ this.requestBirthdateDefault = request;
+ break;
+ }
+ case "gender":
+ {
+ this.requestGenderDefault = request;
+ break;
+ }
+ case "postcode":
+ {
+ this.requestPostalCodeDefault = request;
+ break;
+ }
+ case "country":
+ {
+ this.requestCountryDefault = request;
+ break;
+ }
+ case "language":
+ {
+ this.requestLanguageDefault = request;
+ break;
+ }
+ case "timezone":
+ {
+ this.requestTimeZoneDefault = request;
+ break;
+ }
+ }
+ }
+ }
+
#endregion
#region Public Methods
public Response Answer(bool allow, Uri server_url)
{
+ return Answer(allow, server_url, null);
+ }
+
+ public Response Answer(bool allow, Uri server_url, OpenIdProfileFields openIdProfileFields)
+ {
string mode;
if (allow || _immediate)
@@ -145,26 +246,77 @@ namespace Janrain.OpenId.Server
fields.Add("mode", mode);
fields.Add("identity", _identity.AbsoluteUri);
fields.Add("return_to", _return_to.AbsoluteUri);
+
+ if (openIdProfileFields != null)
+ {
+ if (openIdProfileFields.Birthdate != null)
+ {
+ fields.Add("sreg.dob", openIdProfileFields.Birthdate.ToString());
+ }
+ if (!String.IsNullOrEmpty(openIdProfileFields.Country))
+ {
+ fields.Add("sreg.country", openIdProfileFields.Country);
+ }
+ if (openIdProfileFields.Email != null)
+ {
+ fields.Add("sreg.email", openIdProfileFields.Email.ToString());
+ }
+ if ((!String.IsNullOrEmpty(openIdProfileFields.Fullname)))
+ {
+ fields.Add("sreg.fullname", openIdProfileFields.Fullname);
+ }
+
+ if (openIdProfileFields.Gender != null)
+ {
+ if (openIdProfileFields.Gender == Gender.Female)
+ {
+ fields.Add("sreg.gender", "F");
+ }
+ else
+ {
+ fields.Add("sreg.gender", "M");
+ }
+
+ }
+
+ if (!String.IsNullOrEmpty(openIdProfileFields.Language))
+ {
+ fields.Add("sreg.language", openIdProfileFields.Language);
+ }
+
+ if (!String.IsNullOrEmpty(openIdProfileFields.Nickname))
+ {
+ fields.Add("sreg.nickname", openIdProfileFields.Nickname);
+ }
+
+ if (!String.IsNullOrEmpty(openIdProfileFields.PostalCode))
+ {
+ fields.Add("sreg.postcode", openIdProfileFields.PostalCode);
+ }
+
+ if (!String.IsNullOrEmpty(openIdProfileFields.TimeZone))
+ {
+ fields.Add("sreg.timezone", openIdProfileFields.TimeZone);
+ }
+
+ }
response.AddFields(null, fields, true);
}
- else
+ response.AddField(null, "mode", mode, false);
+ if (_immediate)
{
- response.AddField(null, "mode", mode, false);
- if (_immediate)
- {
- if (server_url == null)
- throw new ApplicationException("setup_url is required for allow=False in immediate mode.");
+ if (server_url == null) { throw new ApplicationException("setup_url is required for allow=False in immediate mode."); }
- CheckIdRequest setup_request = new CheckIdRequest(_identity, _return_to, _trust_root, false, this.AssocHandle);
+ CheckIdRequest setup_request = new CheckIdRequest(_identity, _return_to, _trust_root, false, this.AssocHandle);
- Uri setup_url = setup_request.EncodeToUrl(server_url);
+ Uri setup_url = setup_request.EncodeToUrl(server_url);
- response.AddField(null, "user_setup_url", setup_url.AbsoluteUri, false);
- }
+ response.AddField(null, "user_setup_url", setup_url.AbsoluteUri, false);
}
+
return response;
}
@@ -202,6 +354,22 @@ namespace Janrain.OpenId.Server
return new Uri(builder.ToString());
}
+ public bool IsAnySimpleRegistrationFieldsRequestedOrRequired
+ {
+ get
+ {
+ return (!(this.requestBirthdateDefault == ProfileRequest.NoRequest
+ && this.requestCountryDefault == ProfileRequest.NoRequest
+ && this.requestEmailDefault == ProfileRequest.NoRequest
+ && this.requestFullNameDefault == ProfileRequest.NoRequest
+ && this.requestGenderDefault == ProfileRequest.NoRequest
+ && this.requestLanguageDefault == ProfileRequest.NoRequest
+ && this.requestNicknameDefault == ProfileRequest.NoRequest
+ && this.requestPostalCodeDefault == ProfileRequest.NoRequest
+ && this.requestTimeZoneDefault == ProfileRequest.NoRequest));
+ }
+ }
+
public bool TrustRootValid
{
get
@@ -214,7 +382,8 @@ namespace Janrain.OpenId.Server
if (tr == null)
throw new MalformedTrustRoot(null, _trust_root);
- return tr.ValidateUrl(_return_to);
+ return true;
+ //return tr.ValidateUrl(_return_to);
}
}
@@ -242,6 +411,51 @@ namespace Janrain.OpenId.Server
get { return _return_to; }
}
+ public ProfileRequest RequestNicknameDefault
+ {
+ get { return requestNicknameDefault; }
+ }
+
+ public ProfileRequest RequestEmailDefault
+ {
+ get { return requestEmailDefault; }
+ }
+
+ public ProfileRequest RequestFullNameDefault
+ {
+ get { return requestFullNameDefault; }
+ }
+
+ public ProfileRequest RequestBirthdateDefault
+ {
+ get { return requestBirthdateDefault; }
+ }
+
+ public ProfileRequest RequestGenderDefault
+ {
+ get { return requestGenderDefault; }
+ }
+
+ public ProfileRequest RequestPostalCodeDefault
+ {
+ get { return requestPostalCodeDefault; }
+ }
+
+ public ProfileRequest RequestCountryDefault
+ {
+ get { return requestCountryDefault; }
+ }
+
+ public ProfileRequest RequestLanguageDefault
+ {
+ get { return requestLanguageDefault; }
+ }
+
+ public ProfileRequest RequestTimeZoneDefault
+ {
+ get { return requestTimeZoneDefault; }
+ }
+
#endregion
#region Inherited Properties
@@ -251,6 +465,11 @@ namespace Janrain.OpenId.Server
get { return _mode; }
}
+ public Uri PolicyUrl
+ {
+ get { return _policyUrl; }
+ }
+
#endregion
}
diff --git a/source/Janrain.OpenId/Server/Codec.cs b/source/Janrain.OpenId/Server/Codec.cs
index f363dbd..f5d4a4e 100644
--- a/source/Janrain.OpenId/Server/Codec.cs
+++ b/source/Janrain.OpenId/Server/Codec.cs
@@ -156,8 +156,10 @@ namespace Janrain.OpenId.Server
NameValueCollection myquery = new NameValueCollection();
foreach (string key in query)
{
- if (key.StartsWith("openid."))
- myquery[key] = query[key];
+ if (!String.IsNullOrEmpty(key))
+ {
+ if (key.StartsWith("openid.")) { myquery[key] = query[key];}
+ }
}
if (myquery.Count == 0) return null;
diff --git a/source/Janrain.OpenId/Server/Response.cs b/source/Janrain.OpenId/Server/Response.cs
index f7371c0..f9b7686 100644
--- a/source/Janrain.OpenId/Server/Response.cs
+++ b/source/Janrain.OpenId/Server/Response.cs
@@ -44,7 +44,7 @@ namespace Janrain.OpenId.Server
public string[] Signed
{
- get { return (string[]) _signed.ToArray(); }
+ get { return (string[])_signed.ToArray(typeof(string)); }
}
public bool NeedsSigning
diff --git a/source/Janrain.OpenId/Server/Server.cs b/source/Janrain.OpenId/Server/Server.cs
index 937efeb..7e15f7c 100644
--- a/source/Janrain.OpenId/Server/Server.cs
+++ b/source/Janrain.OpenId/Server/Server.cs
@@ -43,5 +43,16 @@ namespace Janrain.OpenId.Server
#endregion
+ public Request DecodeRequest(NameValueCollection query)
+ {
+ return Decoder.Decode(query);
+ }
+
+ public WebResponse EncodeResponse(IEncodable response)
+ {
+ return this._encoder.Encode(response);
+ }
+
+
}
}
diff --git a/source/Janrain.OpenId/Server/ServerSession.cs b/source/Janrain.OpenId/Server/ServerSession.cs
index ec905b5..5ca9947 100644
--- a/source/Janrain.OpenId/Server/ServerSession.cs
+++ b/source/Janrain.OpenId/Server/ServerSession.cs
@@ -91,17 +91,26 @@ namespace Janrain.OpenId.Server
throw new ProtocolException(query, "If non-default modulus or generator is supplied, both must be supplied. Missing: " + missing);
}
-
- if (dh_modulus != "" || dh_gen != "")
+
+ if (!String.IsNullOrEmpty(dh_modulus) || !String.IsNullOrEmpty(dh_gen))
{
try
{
- dh_modulus_bytes = Convert.FromBase64String(dh_modulus);
+ dh_modulus_bytes = Convert.FromBase64String(dh_modulus);
}
catch (FormatException)
{
throw new ProtocolException(query, "dh_modulus isn't properly base64ed");
}
+
+ try
+ {
+ dh_gen_bytes = Convert.FromBase64String(dh_gen);
+ }
+ catch (FormatException)
+ {
+ throw new ProtocolException(query, "dh_gen isn't properly base64ed");
+ }
}
else
{
diff --git a/source/README.txt b/source/README.txt
new file mode 100644
index 0000000..c81607e
--- /dev/null
+++ b/source/README.txt
@@ -0,0 +1,141 @@
+THE OPENID ASP.NET DEMO
+------------------------------------------------
+This file was created by Willem Muller (willem.muller@netidme.com) on 28/03/2007.
+
+Introduction
+------------------------------------------------
+Before getting started, make sure you understand the OpenID Authentication 1.1 spec (http://openid.net/specs/openid-authentication-1_1.html) and the OpenID Simple Registration
+Extension 1.0 (http://openid.net/specs/openid-simple-registration-extension-1_0.html). Presentations and other explanatory resources are available from http://openid.net/.
+
+The current code base comes from a variety of original contributors:
+ - Most of the original code around the Consumer and Server comes from a Boo (originally from the Python version) port of JanRain's libraries (http://www.openidenabled.com/openid/libraries/csharp).
+ - A C# port (and at the same time .Net 1.1 -> .Net 2.0) is currently under development at http://code.google.com/p/dotnetopenid/. The following people are main contributors:
+ - Scott Hanselman (http://hanselman.com/blog) - Consumer
+ - Jason Alexander (http://jasona.net/) - Server
+ - Andrew Arnott (http://cs.nerdbank.net/blogs/jmpinline/default.aspx) - ASP.NET Controls (OpenIDLogin and OpenIDTextBox classes)
+ - I think the DiffeHelman crypto stuff was all lifted from mono, but don't know by who
+ - Willem Muller (willem.muller@netidme.com) - the sample web projects, bit of work on server side implementation of Registration Extensions, this document, and few bug bugfixes
+ - Anyone else deserve a mention...?
+
+These have been my experiences in getting OpenID working in a .Net Windows environment. If anyone else discovers things, please contribute.
+
+Setting up up the environment
+------------------------------------------------
+ -Your development machine ideally needs to be internet facing so that you can test with other online server/consumers
+ - I reconfigured my network so that all incoming traffic to our external IP on port 79 is forwarded to my local development machine
+ - Ensure your firewall is configured to allow outbound calls to web ports
+
+This code was built using the following prerquisite sofware:
+ * .Net 2.0
+ * Visual Studio 2005
+ * IIS
+ * Windows 2003 Server
+ * nUnit 2.2.9 for .Net 2.0 (get the MSI version from http://www.nunit.org/index.php?p=download)
+ * See the tools section further below for some helpfull software
+
+Setting up the websites
+ * I have set up all my websites on port 79 due to local network config issues
+ * Set up http://127.0.0.1:79/JanRain.OpenID.ConsumerPortal as a website in IIS and allow anonomys access
+ * Set up http://127.0.0.1:79/JanRain.OpenID.ServerPortal as a website in IIS and allow anonomys access
+ * Your openid server users are set up in JanRain.OpenID.ServerPortal\web.config. There are 5 default users already set up.
+
+You need to do something extra for URL rewriting in IIS to work.
+This is the process of url conversion like: user/john ->user.aspx?username=john
+ * In IIS, go properties on the website (not the virtual directory)
+ * Go the Home Directory Tab and click Configuration
+ * Insert a wildcard extension
+ * Enter 'c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll' for the executable
+ * Uncheck the 'Verify that file exists button'
+ * OK your way out of everything
+ * If you navigate to 'http://localhost:79/JanRain.OpenID.ServerPortal/user/bob' you should see the text: 'OpenID identity page for bob'
+
+
+The demos
+------------------------------------------------
+These will illustrate OpenID in action. You can debug the code to get a good idea of whats going on.
+The implementations are built on top of ASP.Net's forms authentication. So basically if you're unauthenticated and get get to page requiring authentication, it takes you through the
+Open-ID identity provider, tracks in session that you've left and then reckognizes the user when they return to the consumer and only then logs them into FormsAuth and redirects them to their
+orignally requested page.
+
+The Consumer Demo
+1) Kill all session cookies
+2) Create an OpenID account with one of the Open Servers listed below OR use the demo Server website as the identity provider - using http://[EXTERNAL IP]/JanRain.OpenID.ServerPortal/user/bob with the password 'test'
+3) Go to http://[EXTERNAL IP]/JanRain.OpenID.ConsumerPortal/default.aspx and enter the OpenIDURL
+4) You are required to authenticate with the provider. Some fields (eg Name, DoB, Country etc.) are requested, some required and some omitted.
+Your OpenID provider should prompt you for the relevant fields, or at least make you aware which fields its passing back. The exact page flow and auhentication mechanism will be implemented differently by different identity providers.
+5) After providing the required info and loggin in, you are taken back to the http://[EXTERNAL IP]/JanRain.OpenID.ConsumerPortal/default.aspx and the available profile information is displayed
+
+The Server Demo
+1) Kill all session cookies
+2) Get the full openID url for a user based on whats in web.config. By default you can use http://[EXTERNAL IP]/JanRain.OpenID.ServerPortal/user/bob with the password 'test'
+3) Go to http://[EXTERNAL IP]/JanRain.OpenID.ConsumerPortal/default.aspx and enter the OpenIDURL of the local server
+4) The user is prompted for their password. The username field is propulated from the openid url and grayed out.
+5) The user is presentend with their identity url, a trust root (the site requiring authentication) and set of fields to complete.
+Only the requested or required fields are presented. Fields with * means the consumer requires it.
+6) The user completes the fields and clicks Yes and are taken to http://[EXTERNAL IP]/JanRain.OpenID.ConsumerPortal/default.aspx with their available profile information.
+
+
+Interesting classes and methods
+------------------------------------------------
+I believe allot of this code originally came from a Python port for which good documentation is available: http://www.openidenabled.com/resources/docs/openid/python/1.1.0/.
+There will certainly be additions and refactorings made to the .Net version, I guess this will soon become out of date. Here is a short list of the import entrypoint objects and methods.
+
+Consumer
+- To construct a consumer class you need to pass in (HttpSessionState and IAssociationStore). The session is needed so that the consumer can track who's doing what and who's who's
+when the browser leaves the consumer site and returns later on. The IAssociationStore is used to generate, store and pair up shared secrets.
+- Consumer.Begin(Url): This is the starting point for a consumer. Once a user has entered their url, you should call Consumer.Begin(Url). This initiates the discovery phase,
+obtains the shared secret and redirects the user's browser to their openid identity provider.
+- Consumer.Complete(NameValueCollection) - This should be called when it's suspected that the user is returning from the identity provider. It performs some structural validation
+on the return message and does some general cleanup. After this method has executed successfully, the consumer website can assume a successfull authentication and log the user in locally.
+
+Server
+- Decoder.Decode should be called intially to obtain a request object. The following types are possibly returned (all derriving from Request):
+ - CheckIdRequest (in immediate mode - for AJAX style behaviour)
+ - CheckIdRequest (in setup mode)
+ - CheckAuthRequest (the call for DUMB mode revalidation of the signature)
+ - AssociateRequest (the request for pre-obtaining the shared secret upfront, or SMART mode)
+
+ - call Server.HandleRequest, passing in the appropriate request. This is an overloaded method that actually ends up doing the physical work and retuning a Response object.
+
+ - once you have response, call Util.GenerateHttpResponse. This will do any necessary digital signing and return the response through the appropriate mechanism (redirect or server side)
+
+
+Development tips / Issues I found:
+------------------------------------------------
+ - Uncomment //System.Diagnostics.Debugger.Launch(); in global.asax to force the debugger to start up if its not working
+ - I would reccommend against setting up multiple websites on your pc using host headers and entries in you hosts file
+ - Always access the test sites via their external IP's, not localhost or 127.0.0. I started testing like this, but stopped because I kept getting an exception
+'Unable to read data from the transport connection: The connection was closed.' when trying to read from a webresponse stream in the OpenID discovery phase. It turned out the problem was the Cassini file based web
+server. Thats why I created the Consumer.Util.ReadAndClose function. It's horrible code and needs to be improved, but ensures that things works if u need to test things locally.
+ - I have not done any HTTPS testing!
+
+For a complete and growing list of OpenID enabled sites, go to: http://openiddirectory.com/allcats.html
+
+Good sites to test with if you're developing a consumer:
+ - http://www.myopenid.com/
+ - http://claimid.com/ (supports registration extensions)
+ - http://www.freeyourid.com/ (supports registration extensions)
+
+Good sites to test with if you're developing a server:
+ - http://beta.zooomr.com/home *
+ - http://cr.unchy.com/ (supports registration extensions)
+ - http://blog.identity20.eu *
+ - http://openiddirectory.com *
+ - http://www.centernetworks.com/ (supports registration extensions)
+ - http://www.loudisrelative.com (supports registration extensions)
+ - http://rssarchive.com/index.html
+ - http://www.jyte.com (supports registration extensions)
+ - http://dis.covr.us/
+* These sites seem to block outgoing traffic that is not on a non standard HTTP port like 80 and 443. Therefore you'll need to host on a proper internet domain before doing any testing with them.
+
+Usefull tools:
+ - Fidler (http://www.fiddlertool.com/fiddler/) - this will allow you to monitor HTTP traffic when using IE
+ - TamperIE (http://www.bayden.com/Other/) - allows you to change form data before posting it
+ - IE Developer toolbar (http://www.microsoft.com/downloads/details.aspx?familyid=E59C3964-672D-4511-BB3E-2D5E1DB91038&displaylang=en) - good tool for general IE UI development. Has some neat features for quickly clearing cookies etc.
+ - iMacros (http://www.iopus.com/download/) - good for automating web testing
+
+
+
+
+
+