diff options
Diffstat (limited to 'samples/OpenIdProviderWebForms')
44 files changed, 3841 insertions, 0 deletions
diff --git a/samples/OpenIdProviderWebForms/.gitignore b/samples/OpenIdProviderWebForms/.gitignore new file mode 100644 index 0000000..b086a60 --- /dev/null +++ b/samples/OpenIdProviderWebForms/.gitignore @@ -0,0 +1,5 @@ +Bin +obj +*.user +*.log +StyleCop.Cache diff --git a/samples/OpenIdProviderWebForms/App_Data/.gitignore b/samples/OpenIdProviderWebForms/App_Data/.gitignore new file mode 100644 index 0000000..cb89d8a --- /dev/null +++ b/samples/OpenIdProviderWebForms/App_Data/.gitignore @@ -0,0 +1 @@ +*.LDF diff --git a/samples/OpenIdProviderWebForms/App_Data/Users.xml b/samples/OpenIdProviderWebForms/App_Data/Users.xml new file mode 100644 index 0000000..cffe009 --- /dev/null +++ b/samples/OpenIdProviderWebForms/App_Data/Users.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8" ?> +<Users> + <User> + <UserName>bob</UserName> + <Password>test</Password> + </User> + <User> + <UserName>bob1</UserName> + <Password>test</Password> + </User> + <User> + <UserName>bob2</UserName> + <Password>test</Password> + </User> + <User> + <UserName>bob3</UserName> + <Password>test</Password> + </User> + <User> + <UserName>bob4</UserName> + <Password>test</Password> + </User> +</Users> diff --git a/samples/OpenIdProviderWebForms/Code/CustomStore.cs b/samples/OpenIdProviderWebForms/Code/CustomStore.cs new file mode 100644 index 0000000..8031a59 --- /dev/null +++ b/samples/OpenIdProviderWebForms/Code/CustomStore.cs @@ -0,0 +1,89 @@ +//----------------------------------------------------------------------- +// <copyright file="CustomStore.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace OpenIdProviderWebForms.Code { + using System; + using System.Data; + using System.Globalization; + using System.Security.Cryptography; + using DotNetOpenAuth.OpenId; + using IProviderAssociationStore = DotNetOpenAuth.OpenId.IAssociationStore<DotNetOpenAuth.OpenId.AssociationRelyingPartyType>; + + /// <summary> + /// This custom store serializes all elements to demonstrate peristent and/or shared storage. + /// This is common in a web farm, for example. + /// </summary> + /// <remarks> + /// This doesn't actually serialize anything to a persistent store, so restarting the web server + /// will still clear everything this store is supposed to remember. + /// But we "persist" all associations and nonces into a DataTable to demonstrate + /// that using a database is possible. + /// </remarks> + public class CustomStore : IProviderAssociationStore { + private static CustomStoreDataSet dataSet = new CustomStoreDataSet(); + + #region IAssociationStore<AssociationRelyingPartyType> Members + + public void StoreAssociation(AssociationRelyingPartyType distinguishingFactor, Association assoc) { + var assocRow = dataSet.Association.NewAssociationRow(); + assocRow.DistinguishingFactor = distinguishingFactor.ToString(); + assocRow.Handle = assoc.Handle; + assocRow.Expires = assoc.Expires.ToLocalTime(); + assocRow.PrivateData = assoc.SerializePrivateData(); + dataSet.Association.AddAssociationRow(assocRow); + } + + public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor) { + // properly escape the URL to prevent injection attacks. + string value = distinguishingFactor.ToString(); + string filter = string.Format( + CultureInfo.InvariantCulture, + "{0} = '{1}'", + dataSet.Association.DistinguishingFactorColumn.ColumnName, + value); + string sort = dataSet.Association.ExpiresColumn.ColumnName + " DESC"; + DataView view = new DataView(dataSet.Association, filter, sort, DataViewRowState.CurrentRows); + if (view.Count == 0) { + return null; + } + var row = (CustomStoreDataSet.AssociationRow)view[0].Row; + return Association.Deserialize(row.Handle, row.Expires.ToUniversalTime(), row.PrivateData); + } + + public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor, string handle) { + var assocRow = dataSet.Association.FindByDistinguishingFactorHandle(distinguishingFactor.ToString(), handle); + return Association.Deserialize(assocRow.Handle, assocRow.Expires, assocRow.PrivateData); + } + + public bool RemoveAssociation(AssociationRelyingPartyType distinguishingFactor, string handle) { + var row = dataSet.Association.FindByDistinguishingFactorHandle(distinguishingFactor.ToString(), handle); + if (row != null) { + dataSet.Association.RemoveAssociationRow(row); + return true; + } else { + return false; + } + } + + public void ClearExpiredAssociations() { + this.removeExpiredRows(dataSet.Association, dataSet.Association.ExpiresColumn.ColumnName); + } + + #endregion + + private void removeExpiredRows(DataTable table, string expiredColumnName) { + string filter = string.Format( + CultureInfo.InvariantCulture, + "{0} < #{1}#", + expiredColumnName, + DateTime.Now); + DataView view = new DataView(table, filter, null, DataViewRowState.CurrentRows); + for (int i = view.Count - 1; i >= 0; i--) { + view.Delete(i); + } + } + } +} diff --git a/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.Designer.cs b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.Designer.cs new file mode 100644 index 0000000..58c20a9 --- /dev/null +++ b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.Designer.cs @@ -0,0 +1,621 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:2.0.50727.3521 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +#pragma warning disable 1591 + +namespace OpenIdProviderWebForms.Code { + + + /// <summary> + ///Represents a strongly typed in-memory cache of data. + ///</summary> + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "2.0.0.0")] + [global::System.Serializable()] + [global::System.ComponentModel.DesignerCategoryAttribute("code")] + [global::System.ComponentModel.ToolboxItem(true)] + [global::System.Xml.Serialization.XmlSchemaProviderAttribute("GetTypedDataSetSchema")] + [global::System.Xml.Serialization.XmlRootAttribute("CustomStoreDataSet")] + [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.DataSet")] + public partial class CustomStoreDataSet : global::System.Data.DataSet { + + private AssociationDataTable tableAssociation; + + private global::System.Data.SchemaSerializationMode _schemaSerializationMode = global::System.Data.SchemaSerializationMode.IncludeSchema; + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public CustomStoreDataSet() { + this.BeginInit(); + this.InitClass(); + global::System.ComponentModel.CollectionChangeEventHandler schemaChangedHandler = new global::System.ComponentModel.CollectionChangeEventHandler(this.SchemaChanged); + base.Tables.CollectionChanged += schemaChangedHandler; + base.Relations.CollectionChanged += schemaChangedHandler; + this.EndInit(); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + protected CustomStoreDataSet(global::System.Runtime.Serialization.SerializationInfo info, global::System.Runtime.Serialization.StreamingContext context) : + base(info, context, false) { + if ((this.IsBinarySerialized(info, context) == true)) { + this.InitVars(false); + global::System.ComponentModel.CollectionChangeEventHandler schemaChangedHandler1 = new global::System.ComponentModel.CollectionChangeEventHandler(this.SchemaChanged); + this.Tables.CollectionChanged += schemaChangedHandler1; + this.Relations.CollectionChanged += schemaChangedHandler1; + return; + } + string strSchema = ((string)(info.GetValue("XmlSchema", typeof(string)))); + if ((this.DetermineSchemaSerializationMode(info, context) == global::System.Data.SchemaSerializationMode.IncludeSchema)) { + global::System.Data.DataSet ds = new global::System.Data.DataSet(); + ds.ReadXmlSchema(new global::System.Xml.XmlTextReader(new global::System.IO.StringReader(strSchema))); + if ((ds.Tables["Association"] != null)) { + base.Tables.Add(new AssociationDataTable(ds.Tables["Association"])); + } + this.DataSetName = ds.DataSetName; + this.Prefix = ds.Prefix; + this.Namespace = ds.Namespace; + this.Locale = ds.Locale; + this.CaseSensitive = ds.CaseSensitive; + this.EnforceConstraints = ds.EnforceConstraints; + this.Merge(ds, false, global::System.Data.MissingSchemaAction.Add); + this.InitVars(); + } + else { + this.ReadXmlSchema(new global::System.Xml.XmlTextReader(new global::System.IO.StringReader(strSchema))); + } + this.GetSerializationData(info, context); + global::System.ComponentModel.CollectionChangeEventHandler schemaChangedHandler = new global::System.ComponentModel.CollectionChangeEventHandler(this.SchemaChanged); + base.Tables.CollectionChanged += schemaChangedHandler; + this.Relations.CollectionChanged += schemaChangedHandler; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.ComponentModel.Browsable(false)] + [global::System.ComponentModel.DesignerSerializationVisibility(global::System.ComponentModel.DesignerSerializationVisibility.Content)] + public AssociationDataTable Association { + get { + return this.tableAssociation; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.ComponentModel.BrowsableAttribute(true)] + [global::System.ComponentModel.DesignerSerializationVisibilityAttribute(global::System.ComponentModel.DesignerSerializationVisibility.Visible)] + public override global::System.Data.SchemaSerializationMode SchemaSerializationMode { + get { + return this._schemaSerializationMode; + } + set { + this._schemaSerializationMode = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.ComponentModel.DesignerSerializationVisibilityAttribute(global::System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public new global::System.Data.DataTableCollection Tables { + get { + return base.Tables; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.ComponentModel.DesignerSerializationVisibilityAttribute(global::System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public new global::System.Data.DataRelationCollection Relations { + get { + return base.Relations; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + protected override void InitializeDerivedDataSet() { + this.BeginInit(); + this.InitClass(); + this.EndInit(); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public override global::System.Data.DataSet Clone() { + CustomStoreDataSet cln = ((CustomStoreDataSet)(base.Clone())); + cln.InitVars(); + cln.SchemaSerializationMode = this.SchemaSerializationMode; + return cln; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + protected override bool ShouldSerializeTables() { + return false; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + protected override bool ShouldSerializeRelations() { + return false; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + protected override void ReadXmlSerializable(global::System.Xml.XmlReader reader) { + if ((this.DetermineSchemaSerializationMode(reader) == global::System.Data.SchemaSerializationMode.IncludeSchema)) { + this.Reset(); + global::System.Data.DataSet ds = new global::System.Data.DataSet(); + ds.ReadXml(reader); + if ((ds.Tables["Association"] != null)) { + base.Tables.Add(new AssociationDataTable(ds.Tables["Association"])); + } + this.DataSetName = ds.DataSetName; + this.Prefix = ds.Prefix; + this.Namespace = ds.Namespace; + this.Locale = ds.Locale; + this.CaseSensitive = ds.CaseSensitive; + this.EnforceConstraints = ds.EnforceConstraints; + this.Merge(ds, false, global::System.Data.MissingSchemaAction.Add); + this.InitVars(); + } + else { + this.ReadXml(reader); + this.InitVars(); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + protected override global::System.Xml.Schema.XmlSchema GetSchemaSerializable() { + global::System.IO.MemoryStream stream = new global::System.IO.MemoryStream(); + this.WriteXmlSchema(new global::System.Xml.XmlTextWriter(stream, null)); + stream.Position = 0; + return global::System.Xml.Schema.XmlSchema.Read(new global::System.Xml.XmlTextReader(stream), null); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + internal void InitVars() { + this.InitVars(true); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + internal void InitVars(bool initTable) { + this.tableAssociation = ((AssociationDataTable)(base.Tables["Association"])); + if ((initTable == true)) { + if ((this.tableAssociation != null)) { + this.tableAssociation.InitVars(); + } + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + private void InitClass() { + this.DataSetName = "CustomStoreDataSet"; + this.Prefix = ""; + this.Namespace = "http://tempuri.org/CustomStoreDataSet.xsd"; + this.EnforceConstraints = true; + this.SchemaSerializationMode = global::System.Data.SchemaSerializationMode.IncludeSchema; + this.tableAssociation = new AssociationDataTable(); + base.Tables.Add(this.tableAssociation); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + private bool ShouldSerializeAssociation() { + return false; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + private void SchemaChanged(object sender, global::System.ComponentModel.CollectionChangeEventArgs e) { + if ((e.Action == global::System.ComponentModel.CollectionChangeAction.Remove)) { + this.InitVars(); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public static global::System.Xml.Schema.XmlSchemaComplexType GetTypedDataSetSchema(global::System.Xml.Schema.XmlSchemaSet xs) { + CustomStoreDataSet ds = new CustomStoreDataSet(); + global::System.Xml.Schema.XmlSchemaComplexType type = new global::System.Xml.Schema.XmlSchemaComplexType(); + global::System.Xml.Schema.XmlSchemaSequence sequence = new global::System.Xml.Schema.XmlSchemaSequence(); + global::System.Xml.Schema.XmlSchemaAny any = new global::System.Xml.Schema.XmlSchemaAny(); + any.Namespace = ds.Namespace; + sequence.Items.Add(any); + type.Particle = sequence; + global::System.Xml.Schema.XmlSchema dsSchema = ds.GetSchemaSerializable(); + if (xs.Contains(dsSchema.TargetNamespace)) { + global::System.IO.MemoryStream s1 = new global::System.IO.MemoryStream(); + global::System.IO.MemoryStream s2 = new global::System.IO.MemoryStream(); + try { + global::System.Xml.Schema.XmlSchema schema = null; + dsSchema.Write(s1); + for (global::System.Collections.IEnumerator schemas = xs.Schemas(dsSchema.TargetNamespace).GetEnumerator(); schemas.MoveNext(); ) { + schema = ((global::System.Xml.Schema.XmlSchema)(schemas.Current)); + s2.SetLength(0); + schema.Write(s2); + if ((s1.Length == s2.Length)) { + s1.Position = 0; + s2.Position = 0; + for (; ((s1.Position != s1.Length) + && (s1.ReadByte() == s2.ReadByte())); ) { + ; + } + if ((s1.Position == s1.Length)) { + return type; + } + } + } + } + finally { + if ((s1 != null)) { + s1.Close(); + } + if ((s2 != null)) { + s2.Close(); + } + } + } + xs.Add(dsSchema); + return type; + } + + public delegate void AssociationRowChangeEventHandler(object sender, AssociationRowChangeEvent e); + + /// <summary> + ///Represents the strongly named DataTable class. + ///</summary> + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "2.0.0.0")] + [global::System.Serializable()] + [global::System.Xml.Serialization.XmlSchemaProviderAttribute("GetTypedTableSchema")] + public partial class AssociationDataTable : global::System.Data.TypedTableBase<AssociationRow> { + + private global::System.Data.DataColumn columnDistinguishingFactor; + + private global::System.Data.DataColumn columnHandle; + + private global::System.Data.DataColumn columnExpires; + + private global::System.Data.DataColumn columnPrivateData; + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public AssociationDataTable() { + this.TableName = "Association"; + this.BeginInit(); + this.InitClass(); + this.EndInit(); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + internal AssociationDataTable(global::System.Data.DataTable table) { + this.TableName = table.TableName; + if ((table.CaseSensitive != table.DataSet.CaseSensitive)) { + this.CaseSensitive = table.CaseSensitive; + } + if ((table.Locale.ToString() != table.DataSet.Locale.ToString())) { + this.Locale = table.Locale; + } + if ((table.Namespace != table.DataSet.Namespace)) { + this.Namespace = table.Namespace; + } + this.Prefix = table.Prefix; + this.MinimumCapacity = table.MinimumCapacity; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + protected AssociationDataTable(global::System.Runtime.Serialization.SerializationInfo info, global::System.Runtime.Serialization.StreamingContext context) : + base(info, context) { + this.InitVars(); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public global::System.Data.DataColumn DistinguishingFactorColumn { + get { + return this.columnDistinguishingFactor; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public global::System.Data.DataColumn HandleColumn { + get { + return this.columnHandle; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public global::System.Data.DataColumn ExpiresColumn { + get { + return this.columnExpires; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public global::System.Data.DataColumn PrivateDataColumn { + get { + return this.columnPrivateData; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.ComponentModel.Browsable(false)] + public int Count { + get { + return this.Rows.Count; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public AssociationRow this[int index] { + get { + return ((AssociationRow)(this.Rows[index])); + } + } + + public event AssociationRowChangeEventHandler AssociationRowChanging; + + public event AssociationRowChangeEventHandler AssociationRowChanged; + + public event AssociationRowChangeEventHandler AssociationRowDeleting; + + public event AssociationRowChangeEventHandler AssociationRowDeleted; + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public void AddAssociationRow(AssociationRow row) { + this.Rows.Add(row); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public AssociationRow AddAssociationRow(string DistinguishingFactor, string Handle, System.DateTime Expires, byte[] PrivateData) { + AssociationRow rowAssociationRow = ((AssociationRow)(this.NewRow())); + object[] columnValuesArray = new object[] { + DistinguishingFactor, + Handle, + Expires, + PrivateData}; + rowAssociationRow.ItemArray = columnValuesArray; + this.Rows.Add(rowAssociationRow); + return rowAssociationRow; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public AssociationRow FindByDistinguishingFactorHandle(string DistinguishingFactor, string Handle) { + return ((AssociationRow)(this.Rows.Find(new object[] { + DistinguishingFactor, + Handle}))); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public override global::System.Data.DataTable Clone() { + AssociationDataTable cln = ((AssociationDataTable)(base.Clone())); + cln.InitVars(); + return cln; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + protected override global::System.Data.DataTable CreateInstance() { + return new AssociationDataTable(); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + internal void InitVars() { + this.columnDistinguishingFactor = base.Columns["DistinguishingFactor"]; + this.columnHandle = base.Columns["Handle"]; + this.columnExpires = base.Columns["Expires"]; + this.columnPrivateData = base.Columns["PrivateData"]; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + private void InitClass() { + this.columnDistinguishingFactor = new global::System.Data.DataColumn("DistinguishingFactor", typeof(string), null, global::System.Data.MappingType.Element); + base.Columns.Add(this.columnDistinguishingFactor); + this.columnHandle = new global::System.Data.DataColumn("Handle", typeof(string), null, global::System.Data.MappingType.Element); + base.Columns.Add(this.columnHandle); + this.columnExpires = new global::System.Data.DataColumn("Expires", typeof(global::System.DateTime), null, global::System.Data.MappingType.Element); + base.Columns.Add(this.columnExpires); + this.columnPrivateData = new global::System.Data.DataColumn("PrivateData", typeof(byte[]), null, global::System.Data.MappingType.Element); + base.Columns.Add(this.columnPrivateData); + this.Constraints.Add(new global::System.Data.UniqueConstraint("PrimaryKey", new global::System.Data.DataColumn[] { + this.columnDistinguishingFactor, + this.columnHandle}, true)); + this.columnDistinguishingFactor.AllowDBNull = false; + this.columnHandle.AllowDBNull = false; + this.columnExpires.AllowDBNull = false; + this.columnPrivateData.AllowDBNull = false; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public AssociationRow NewAssociationRow() { + return ((AssociationRow)(this.NewRow())); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + protected override global::System.Data.DataRow NewRowFromBuilder(global::System.Data.DataRowBuilder builder) { + return new AssociationRow(builder); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + protected override global::System.Type GetRowType() { + return typeof(AssociationRow); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + protected override void OnRowChanged(global::System.Data.DataRowChangeEventArgs e) { + base.OnRowChanged(e); + if ((this.AssociationRowChanged != null)) { + this.AssociationRowChanged(this, new AssociationRowChangeEvent(((AssociationRow)(e.Row)), e.Action)); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + protected override void OnRowChanging(global::System.Data.DataRowChangeEventArgs e) { + base.OnRowChanging(e); + if ((this.AssociationRowChanging != null)) { + this.AssociationRowChanging(this, new AssociationRowChangeEvent(((AssociationRow)(e.Row)), e.Action)); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + protected override void OnRowDeleted(global::System.Data.DataRowChangeEventArgs e) { + base.OnRowDeleted(e); + if ((this.AssociationRowDeleted != null)) { + this.AssociationRowDeleted(this, new AssociationRowChangeEvent(((AssociationRow)(e.Row)), e.Action)); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + protected override void OnRowDeleting(global::System.Data.DataRowChangeEventArgs e) { + base.OnRowDeleting(e); + if ((this.AssociationRowDeleting != null)) { + this.AssociationRowDeleting(this, new AssociationRowChangeEvent(((AssociationRow)(e.Row)), e.Action)); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public void RemoveAssociationRow(AssociationRow row) { + this.Rows.Remove(row); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public static global::System.Xml.Schema.XmlSchemaComplexType GetTypedTableSchema(global::System.Xml.Schema.XmlSchemaSet xs) { + global::System.Xml.Schema.XmlSchemaComplexType type = new global::System.Xml.Schema.XmlSchemaComplexType(); + global::System.Xml.Schema.XmlSchemaSequence sequence = new global::System.Xml.Schema.XmlSchemaSequence(); + CustomStoreDataSet ds = new CustomStoreDataSet(); + global::System.Xml.Schema.XmlSchemaAny any1 = new global::System.Xml.Schema.XmlSchemaAny(); + any1.Namespace = "http://www.w3.org/2001/XMLSchema"; + any1.MinOccurs = new decimal(0); + any1.MaxOccurs = decimal.MaxValue; + any1.ProcessContents = global::System.Xml.Schema.XmlSchemaContentProcessing.Lax; + sequence.Items.Add(any1); + global::System.Xml.Schema.XmlSchemaAny any2 = new global::System.Xml.Schema.XmlSchemaAny(); + any2.Namespace = "urn:schemas-microsoft-com:xml-diffgram-v1"; + any2.MinOccurs = new decimal(1); + any2.ProcessContents = global::System.Xml.Schema.XmlSchemaContentProcessing.Lax; + sequence.Items.Add(any2); + global::System.Xml.Schema.XmlSchemaAttribute attribute1 = new global::System.Xml.Schema.XmlSchemaAttribute(); + attribute1.Name = "namespace"; + attribute1.FixedValue = ds.Namespace; + type.Attributes.Add(attribute1); + global::System.Xml.Schema.XmlSchemaAttribute attribute2 = new global::System.Xml.Schema.XmlSchemaAttribute(); + attribute2.Name = "tableTypeName"; + attribute2.FixedValue = "AssociationDataTable"; + type.Attributes.Add(attribute2); + type.Particle = sequence; + global::System.Xml.Schema.XmlSchema dsSchema = ds.GetSchemaSerializable(); + if (xs.Contains(dsSchema.TargetNamespace)) { + global::System.IO.MemoryStream s1 = new global::System.IO.MemoryStream(); + global::System.IO.MemoryStream s2 = new global::System.IO.MemoryStream(); + try { + global::System.Xml.Schema.XmlSchema schema = null; + dsSchema.Write(s1); + for (global::System.Collections.IEnumerator schemas = xs.Schemas(dsSchema.TargetNamespace).GetEnumerator(); schemas.MoveNext(); ) { + schema = ((global::System.Xml.Schema.XmlSchema)(schemas.Current)); + s2.SetLength(0); + schema.Write(s2); + if ((s1.Length == s2.Length)) { + s1.Position = 0; + s2.Position = 0; + for (; ((s1.Position != s1.Length) + && (s1.ReadByte() == s2.ReadByte())); ) { + ; + } + if ((s1.Position == s1.Length)) { + return type; + } + } + } + } + finally { + if ((s1 != null)) { + s1.Close(); + } + if ((s2 != null)) { + s2.Close(); + } + } + } + xs.Add(dsSchema); + return type; + } + } + + /// <summary> + ///Represents strongly named DataRow class. + ///</summary> + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "2.0.0.0")] + public partial class AssociationRow : global::System.Data.DataRow { + + private AssociationDataTable tableAssociation; + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + internal AssociationRow(global::System.Data.DataRowBuilder rb) : + base(rb) { + this.tableAssociation = ((AssociationDataTable)(this.Table)); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public string DistinguishingFactor { + get { + return ((string)(this[this.tableAssociation.DistinguishingFactorColumn])); + } + set { + this[this.tableAssociation.DistinguishingFactorColumn] = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public string Handle { + get { + return ((string)(this[this.tableAssociation.HandleColumn])); + } + set { + this[this.tableAssociation.HandleColumn] = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public System.DateTime Expires { + get { + return ((global::System.DateTime)(this[this.tableAssociation.ExpiresColumn])); + } + set { + this[this.tableAssociation.ExpiresColumn] = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public byte[] PrivateData { + get { + return ((byte[])(this[this.tableAssociation.PrivateDataColumn])); + } + set { + this[this.tableAssociation.PrivateDataColumn] = value; + } + } + } + + /// <summary> + ///Row event argument class + ///</summary> + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "2.0.0.0")] + public class AssociationRowChangeEvent : global::System.EventArgs { + + private AssociationRow eventRow; + + private global::System.Data.DataRowAction eventAction; + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public AssociationRowChangeEvent(AssociationRow row, global::System.Data.DataRowAction action) { + this.eventRow = row; + this.eventAction = action; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public AssociationRow Row { + get { + return this.eventRow; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public global::System.Data.DataRowAction Action { + get { + return this.eventAction; + } + } + } + } +} + +#pragma warning restore 1591
\ No newline at end of file diff --git a/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xsc b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xsc new file mode 100644 index 0000000..05b0199 --- /dev/null +++ b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xsc @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--<autogenerated> + This code was generated by a tool. + Changes to this file may cause incorrect behavior and will be lost if + the code is regenerated. +</autogenerated>--> +<DataSetUISetting Version="1.00" xmlns="urn:schemas-microsoft-com:xml-msdatasource"> + <TableUISettings /> +</DataSetUISetting>
\ No newline at end of file diff --git a/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xsd b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xsd new file mode 100644 index 0000000..63226bd --- /dev/null +++ b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xsd @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<xs:schema id="CustomStoreDataSet" targetNamespace="http://tempuri.org/CustomStoreDataSet.xsd" xmlns:mstns="http://tempuri.org/CustomStoreDataSet.xsd" xmlns="http://tempuri.org/CustomStoreDataSet.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:msprop="urn:schemas-microsoft-com:xml-msprop" attributeFormDefault="qualified" elementFormDefault="qualified"> + <xs:annotation> + <xs:appinfo source="urn:schemas-microsoft-com:xml-msdatasource"> + <DataSource DefaultConnectionIndex="0" FunctionsComponentName="QueriesTableAdapter" Modifier="AutoLayout, AnsiClass, Class, Public" SchemaSerializationMode="IncludeSchema" xmlns="urn:schemas-microsoft-com:xml-msdatasource"> + <Connections /> + <Tables /> + <Sources /> + </DataSource> + </xs:appinfo> + </xs:annotation> + <xs:element name="CustomStoreDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true" msprop:Generator_UserDSName="CustomStoreDataSet" msprop:Generator_DataSetName="CustomStoreDataSet" msprop:EnableTableAdapterManager="true"> + <xs:complexType> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="Association" msprop:Generator_UserTableName="Association" msprop:Generator_RowDeletedName="AssociationRowDeleted" msprop:Generator_RowChangedName="AssociationRowChanged" msprop:Generator_RowClassName="AssociationRow" msprop:Generator_RowChangingName="AssociationRowChanging" msprop:Generator_RowEvArgName="AssociationRowChangeEvent" msprop:Generator_RowEvHandlerName="AssociationRowChangeEventHandler" msprop:Generator_TableClassName="AssociationDataTable" msprop:Generator_TableVarName="tableAssociation" msprop:Generator_RowDeletingName="AssociationRowDeleting" msprop:Generator_TablePropName="Association"> + <xs:complexType> + <xs:sequence> + <xs:element name="DistinguishingFactor" msprop:Generator_UserColumnName="DistinguishingFactor" msprop:Generator_ColumnPropNameInRow="DistinguishingFactor" msprop:Generator_ColumnVarNameInTable="columnDistinguishingFactor" msprop:Generator_ColumnPropNameInTable="DistinguishingFactorColumn" type="xs:string" /> + <xs:element name="Handle" msprop:Generator_UserColumnName="Handle" msprop:Generator_ColumnPropNameInRow="Handle" msprop:Generator_ColumnVarNameInTable="columnHandle" msprop:Generator_ColumnPropNameInTable="HandleColumn" type="xs:string" /> + <xs:element name="Expires" msprop:Generator_UserColumnName="Expires" msprop:Generator_ColumnPropNameInRow="Expires" msprop:Generator_ColumnVarNameInTable="columnExpires" msprop:Generator_ColumnPropNameInTable="ExpiresColumn" type="xs:dateTime" /> + <xs:element name="PrivateData" msprop:Generator_UserColumnName="PrivateData" msprop:Generator_ColumnPropNameInRow="PrivateData" msprop:Generator_ColumnVarNameInTable="columnPrivateData" msprop:Generator_ColumnPropNameInTable="PrivateDataColumn" type="xs:base64Binary" /> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:choice> + </xs:complexType> + <xs:unique name="PrimaryKey" msdata:PrimaryKey="true"> + <xs:selector xpath=".//mstns:Association" /> + <xs:field xpath="mstns:DistinguishingFactor" /> + <xs:field xpath="mstns:Handle" /> + </xs:unique> + </xs:element> +</xs:schema>
\ No newline at end of file diff --git a/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xss b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xss new file mode 100644 index 0000000..0b3972e --- /dev/null +++ b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xss @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--<autogenerated> + This code was generated by a tool to store the dataset designer's layout information. + Changes to this file may cause incorrect behavior and will be lost if + the code is regenerated. +</autogenerated>--> +<DiagramLayout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ex:showrelationlabel="False" ViewPortX="0" ViewPortY="0" xmlns:ex="urn:schemas-microsoft-com:xml-msdatasource-layout-extended" xmlns="urn:schemas-microsoft-com:xml-msdatasource-layout"> + <Shapes> + <Shape ID="DesignTable:Association" ZOrder="1" X="349" Y="83" Height="105" Width="154" AdapterExpanded="true" DataTableExpanded="true" OldAdapterHeight="0" OldDataTableHeight="0" SplitterPosition="101" /> + </Shapes> + <Connectors /> +</DiagramLayout>
\ No newline at end of file diff --git a/samples/OpenIdProviderWebForms/Code/ReadOnlyXmlMembershipProvider.cs b/samples/OpenIdProviderWebForms/Code/ReadOnlyXmlMembershipProvider.cs new file mode 100644 index 0000000..54db5c0 --- /dev/null +++ b/samples/OpenIdProviderWebForms/Code/ReadOnlyXmlMembershipProvider.cs @@ -0,0 +1,270 @@ +namespace OpenIdProviderWebForms.Code { + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + using System.Configuration.Provider; + using System.Security.Permissions; + using System.Web; + using System.Web.Hosting; + using System.Web.Security; + using System.Xml; + + public class ReadOnlyXmlMembershipProvider : MembershipProvider { + private Dictionary<string, MembershipUser> users; + private string xmlFileName; + + // MembershipProvider Properties + public override string ApplicationName { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + + public override bool EnablePasswordRetrieval { + get { return false; } + } + + public override bool EnablePasswordReset { + get { return false; } + } + + public override int MaxInvalidPasswordAttempts { + get { throw new NotSupportedException(); } + } + + public override int MinRequiredNonAlphanumericCharacters { + get { throw new NotSupportedException(); } + } + + public override int MinRequiredPasswordLength { + get { throw new NotSupportedException(); } + } + + public override int PasswordAttemptWindow { + get { throw new NotSupportedException(); } + } + + public override MembershipPasswordFormat PasswordFormat { + get { throw new NotSupportedException(); } + } + + public override string PasswordStrengthRegularExpression { + get { throw new NotSupportedException(); } + } + + public override bool RequiresQuestionAndAnswer { + get { throw new NotSupportedException(); } + } + + public override bool RequiresUniqueEmail { + get { throw new NotSupportedException(); } + } + + // MembershipProvider Methods + public override void Initialize(string name, NameValueCollection config) { + // Verify that config isn't null + if (config == null) { + throw new ArgumentNullException("config"); + } + + // Assign the provider a default name if it doesn't have one + if (string.IsNullOrEmpty(name)) { + name = "ReadOnlyXmlMembershipProvider"; + } + + // Add a default "description" attribute to config if the + // attribute doesn't exist or is empty + if (string.IsNullOrEmpty(config["description"])) { + config.Remove("description"); + config.Add("description", "Read-only XML membership provider"); + } + + // Call the base class's Initialize method + base.Initialize(name, config); + + // Initialize _XmlFileName and make sure the path + // is app-relative + string path = config["xmlFileName"]; + + if (string.IsNullOrEmpty(path)) { + path = "~/App_Data/Users.xml"; + } + + if (!VirtualPathUtility.IsAppRelative(path)) { + throw new ArgumentException("xmlFileName must be app-relative"); + } + + string fullyQualifiedPath = VirtualPathUtility.Combine( + VirtualPathUtility.AppendTrailingSlash(HttpRuntime.AppDomainAppVirtualPath), + path); + + this.xmlFileName = HostingEnvironment.MapPath(fullyQualifiedPath); + config.Remove("xmlFileName"); + + // Make sure we have permission to read the XML data source and + // throw an exception if we don't + FileIOPermission permission = new FileIOPermission(FileIOPermissionAccess.Read, this.xmlFileName); + permission.Demand(); + + // Throw an exception if unrecognized attributes remain + if (config.Count > 0) { + string attr = config.GetKey(0); + if (!string.IsNullOrEmpty(attr)) { + throw new ProviderException("Unrecognized attribute: " + attr); + } + } + } + + public override bool ValidateUser(string username, string password) { + // Validate input parameters + if (string.IsNullOrEmpty(username) || + string.IsNullOrEmpty(password)) { + return false; + } + + try { + // Make sure the data source has been loaded + this.ReadMembershipDataStore(); + + // Validate the user name and password + MembershipUser user; + if (this.users.TryGetValue(username, out user)) { + if (user.Comment == password) { // Case-sensitive + // NOTE: A read/write membership provider + // would update the user's LastLoginDate here. + // A fully featured provider would also fire + // an AuditMembershipAuthenticationSuccess + // Web event + return true; + } + } + + // NOTE: A fully featured membership provider would + // fire an AuditMembershipAuthenticationFailure + // Web event here + return false; + } catch (Exception) { + return false; + } + } + + public override MembershipUser GetUser(string username, bool userIsOnline) { + // Note: This implementation ignores userIsOnline + + // Validate input parameters + if (string.IsNullOrEmpty(username)) { + return null; + } + + // Make sure the data source has been loaded + this.ReadMembershipDataStore(); + + // Retrieve the user from the data source + MembershipUser user; + if (this.users.TryGetValue(username, out user)) { + return user; + } + + return null; + } + + public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords) { + // Note: This implementation ignores pageIndex and pageSize, + // and it doesn't sort the MembershipUser objects returned + + // Make sure the data source has been loaded + this.ReadMembershipDataStore(); + + MembershipUserCollection users = new MembershipUserCollection(); + + foreach (KeyValuePair<string, MembershipUser> pair in this.users) { + users.Add(pair.Value); + } + + totalRecords = users.Count; + return users; + } + + public override int GetNumberOfUsersOnline() { + throw new NotSupportedException(); + } + + public override bool ChangePassword(string username, string oldPassword, string newPassword) { + throw new NotSupportedException(); + } + + public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer) { + throw new NotSupportedException(); + } + + public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status) { + throw new NotSupportedException(); + } + + public override bool DeleteUser(string username, bool deleteAllRelatedData) { + throw new NotSupportedException(); + } + + public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords) { + throw new NotSupportedException(); + } + + public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) { + throw new NotSupportedException(); + } + + public override string GetPassword(string username, string answer) { + throw new NotSupportedException(); + } + + public override MembershipUser GetUser(object providerUserKey, bool userIsOnline) { + throw new NotSupportedException(); + } + + public override string GetUserNameByEmail(string email) { + throw new NotSupportedException(); + } + + public override string ResetPassword(string username, string answer) { + throw new NotSupportedException(); + } + + public override bool UnlockUser(string userName) { + throw new NotSupportedException(); + } + + public override void UpdateUser(MembershipUser user) { + throw new NotSupportedException(); + } + + // Helper method + private void ReadMembershipDataStore() { + lock (this) { + if (this.users == null) { + this.users = new Dictionary<string, MembershipUser>(16, StringComparer.InvariantCultureIgnoreCase); + XmlDocument doc = new XmlDocument(); + doc.Load(this.xmlFileName); + XmlNodeList nodes = doc.GetElementsByTagName("User"); + + foreach (XmlNode node in nodes) { + MembershipUser user = new MembershipUser( + Name, // Provider name + node["UserName"].InnerText, // Username + null, // providerUserKey + null, // Email + string.Empty, // passwordQuestion + node["Password"].InnerText, // Comment + true, // isApproved + false, // isLockedOut + DateTime.Now, // creationDate + DateTime.Now, // lastLoginDate + DateTime.Now, // lastActivityDate + DateTime.Now, // lastPasswordChangedDate + new DateTime(1980, 1, 1)); // lastLockoutDate + + this.users.Add(user.UserName, user); + } + } + } + } + } +}
\ No newline at end of file diff --git a/samples/OpenIdProviderWebForms/Code/TracePageAppender.cs b/samples/OpenIdProviderWebForms/Code/TracePageAppender.cs new file mode 100644 index 0000000..1bb7a34 --- /dev/null +++ b/samples/OpenIdProviderWebForms/Code/TracePageAppender.cs @@ -0,0 +1,13 @@ +namespace OpenIdProviderWebForms.Code { + using System; + using System.Collections.Generic; + using System.IO; + using System.Web; + + public class TracePageAppender : log4net.Appender.AppenderSkeleton { + protected override void Append(log4net.Core.LoggingEvent loggingEvent) { + StringWriter sw = new StringWriter(Global.LogMessages); + Layout.Format(sw, loggingEvent); + } + } +} diff --git a/samples/OpenIdProviderWebForms/Code/URLRewriter.cs b/samples/OpenIdProviderWebForms/Code/URLRewriter.cs new file mode 100644 index 0000000..daa4dea --- /dev/null +++ b/samples/OpenIdProviderWebForms/Code/URLRewriter.cs @@ -0,0 +1,61 @@ +namespace OpenIdProviderWebForms.Code { + using System.Configuration; + using System.Diagnostics; + using System.Text.RegularExpressions; + using System.Web; + using System.Xml; + + // nicked from http://www.codeproject.com/aspnet/URLRewriter.asp + public class URLRewriter : IConfigurationSectionHandler { + public static log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + protected XmlNode rules = null; + + protected URLRewriter() { + } + + public static void Process() { + URLRewriter rewriter = (URLRewriter)ConfigurationManager.GetSection("urlrewrites"); + + string subst = rewriter.GetSubstitution(HttpContext.Current.Request.Path); + + if (!string.IsNullOrEmpty(subst)) { + Logger.InfoFormat("Rewriting url '{0}' to '{1}' ", HttpContext.Current.Request.Path, subst); + HttpContext.Current.RewritePath(subst); + } + } + + public string GetSubstitution(string path) { + foreach (XmlNode node in this.rules.SelectNodes("rule")) { + // get the url and rewrite nodes + XmlNode urlNode = node.SelectSingleNode("url"); + XmlNode rewriteNode = node.SelectSingleNode("rewrite"); + + // check validity of the values + if (urlNode == null || string.IsNullOrEmpty(urlNode.InnerText) + || rewriteNode == null || string.IsNullOrEmpty(rewriteNode.InnerText)) { + Logger.Warn("Invalid urlrewrites rule discovered in web.config file."); + continue; + } + + Regex reg = new Regex(urlNode.InnerText, RegexOptions.IgnoreCase); + + // if match, return the substitution + Match match = reg.Match(path); + if (match.Success) { + return reg.Replace(path, rewriteNode.InnerText); + } + } + + return null; // no rewrite + } + + #region Implementation of IConfigurationSectionHandler + public object Create(object parent, object configContext, XmlNode section) { + this.rules = section; + + return this; + } + #endregion + } +}
\ No newline at end of file diff --git a/samples/OpenIdProviderWebForms/Code/Util.cs b/samples/OpenIdProviderWebForms/Code/Util.cs new file mode 100644 index 0000000..5cec951 --- /dev/null +++ b/samples/OpenIdProviderWebForms/Code/Util.cs @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------- +// <copyright file="Util.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace OpenIdProviderWebForms.Code { + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Net; + using System.Text; + using System.Web; + using DotNetOpenAuth.OpenId; + using DotNetOpenAuth.OpenId.Provider; + + public class Util { + public static string ExtractUserName(Uri url) { + return url.Segments[url.Segments.Length - 1]; + } + + public static string ExtractUserName(Identifier identifier) { + return ExtractUserName(new Uri(identifier.ToString())); + } + + public static Identifier BuildIdentityUrl() { + string username = HttpContext.Current.User.Identity.Name; + + // be sure to normalize case the way the user's identity page does. + username = username.Substring(0, 1).ToUpperInvariant() + username.Substring(1).ToLowerInvariant(); + return new Uri(HttpContext.Current.Request.Url, "/user/" + username); + } + + internal static void ProcessAuthenticationChallenge(IAuthenticationRequest idrequest) { + if (idrequest.Immediate) { + if (idrequest.IsDirectedIdentity) { + if (HttpContext.Current.User.Identity.IsAuthenticated) { + idrequest.LocalIdentifier = Util.BuildIdentityUrl(); + idrequest.IsAuthenticated = true; + } else { + idrequest.IsAuthenticated = false; + } + } else { + string userOwningOpenIdUrl = Util.ExtractUserName(idrequest.LocalIdentifier); + + // NOTE: in a production provider site, you may want to only + // respond affirmatively if the user has already authorized this consumer + // to know the answer. + idrequest.IsAuthenticated = userOwningOpenIdUrl == HttpContext.Current.User.Identity.Name; + } + } else { + HttpContext.Current.Response.Redirect("~/decide.aspx", true); + } + } + } +}
\ No newline at end of file diff --git a/samples/OpenIdProviderWebForms/Default.aspx b/samples/OpenIdProviderWebForms/Default.aspx new file mode 100644 index 0000000..a0cb02a --- /dev/null +++ b/samples/OpenIdProviderWebForms/Default.aspx @@ -0,0 +1,53 @@ +<%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="~/Site.Master" %> + +<%@ Import Namespace="OpenIdProviderWebForms.Code" %> +<%@ Import Namespace="DotNetOpenAuth.OpenId.Provider" %> +<%@ Import Namespace="DotNetOpenAuth.Messaging" %> +<%@ Register Assembly="DotNetOpenAuth" Namespace="DotNetOpenAuth.OpenId" TagPrefix="openid" %> +<%@ Register Assembly="DotNetOpenAuth" Namespace="DotNetOpenAuth" TagPrefix="openauth" %> + +<script runat="server"> + protected void sendAssertionButton_Click(object sender, EventArgs e) { + TextBox relyingPartySite = (TextBox)loginView.FindControl("relyingPartySite"); + Uri providerEndpoint = new Uri(Request.Url, Page.ResolveUrl("~/server.aspx")); + OpenIdProvider op = new OpenIdProvider(); + try { + op.PrepareUnsolicitedAssertion(providerEndpoint, relyingPartySite.Text, Util.BuildIdentityUrl(), Util.BuildIdentityUrl()).Send(); + } catch (ProtocolException ex) { + Label errorLabel = (Label)loginView.FindControl("errorLabel"); + errorLabel.Visible = true; + errorLabel.Text = ex.Message; + } + } +</script> + +<asp:Content runat="server" ContentPlaceHolderID="head"> + <openauth:XrdsPublisher runat="server" XrdsUrl="~/op_xrds.aspx" /> +</asp:Content> +<asp:Content runat="server" ContentPlaceHolderID="Main"> + <h2>Provider </h2> + <p>Welcome. This site doesn't do anything more than simple authentication of users. + Start the authentication process on the Relying Party sample site, or log in here + and send an unsolicited assertion. </p> + <asp:LoginView runat="server" ID="loginView"> + <LoggedInTemplate> + <asp:Panel runat="server" DefaultButton="sendAssertionButton"> + Since you're logged in, try sending an unsolicited assertion to an OpenID 2.0 relying + party site. Just type in the URL to the site's home page. This could be the sample + relying party web site. + <br /> + <asp:TextBox runat="server" ID="relyingPartySite" Columns="40" /> + <asp:Button runat="server" ID="sendAssertionButton" Text="Send assertion" OnClick="sendAssertionButton_Click" /> + <asp:RequiredFieldValidator runat="server" ControlToValidate="relyingPartySite" Text="Specify relying party site first" /> + <br /> + An unsolicited assertion is a way to log in to a relying party site directly from + your OpenID Provider. + <p> + <asp:Label runat="server" EnableViewState="false" Visible="false" ID="errorLabel" + ForeColor="Red" /> + </p> + </asp:Panel> + </LoggedInTemplate> + </asp:LoginView> + <asp:LoginStatus runat="server" /> +</asp:Content> diff --git a/samples/OpenIdProviderWebForms/Global.asax b/samples/OpenIdProviderWebForms/Global.asax new file mode 100644 index 0000000..a67f1b1 --- /dev/null +++ b/samples/OpenIdProviderWebForms/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="OpenIdProviderWebForms.Global" Language="C#" %> diff --git a/samples/OpenIdProviderWebForms/Global.asax.cs b/samples/OpenIdProviderWebForms/Global.asax.cs new file mode 100644 index 0000000..89d9268 --- /dev/null +++ b/samples/OpenIdProviderWebForms/Global.asax.cs @@ -0,0 +1,82 @@ +//----------------------------------------------------------------------- +// <copyright file="Global.asax.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace OpenIdProviderWebForms { + using System; + using System.Collections.Specialized; + using System.IO; + using System.Text; + using System.Web; + using OpenIdProviderWebForms.Code; + + public class Global : System.Web.HttpApplication { + public static log4net.ILog Logger = log4net.LogManager.GetLogger(typeof(Global)); + + internal static StringBuilder LogMessages = new StringBuilder(); + + public static string ToString(NameValueCollection collection) { + using (StringWriter sw = new StringWriter()) { + foreach (string key in collection.Keys) { + if (key.StartsWith("__")) { + continue; // skip + } + sw.WriteLine("{0} = '{1}'", key, collection[key]); + } + return sw.ToString(); + } + } + + protected void Application_Start(object sender, EventArgs e) { + log4net.Config.XmlConfigurator.Configure(); + Logger.Info("Sample starting..."); + } + + protected void Application_End(object sender, EventArgs e) { + Logger.Info("Sample shutting down..."); + + // this would be automatic, but in partial trust scenarios it is not. + log4net.LogManager.Shutdown(); + } + + 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(); + Logger.DebugFormat("Processing {0} on {1} ", this.Request.HttpMethod, this.stripQueryString(this.Request.Url)); + if (Request.QueryString.Count > 0) { + Logger.DebugFormat("Querystring follows: \n{0}", ToString(Request.QueryString)); + } + if (Request.Form.Count > 0) { + Logger.DebugFormat("Posted form follows: \n{0}", ToString(Request.Form)); + } + + URLRewriter.Process(); + } + + protected void Application_AuthenticateRequest(object sender, EventArgs e) { + Logger.DebugFormat("User {0} authenticated.", HttpContext.Current.User != null ? "IS" : "is NOT"); + } + + protected void Application_EndRequest(object sender, EventArgs e) { + } + + protected void Application_Error(object sender, EventArgs e) { + Logger.ErrorFormat( + "An unhandled exception was raised. Details follow: {0}", + HttpContext.Current.Server.GetLastError()); + } + + private string stripQueryString(Uri uri) { + UriBuilder builder = new UriBuilder(uri); + builder.Query = null; + return builder.ToString(); + } + } +}
\ No newline at end of file diff --git a/samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj b/samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj new file mode 100644 index 0000000..179f4f8 --- /dev/null +++ b/samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj @@ -0,0 +1,191 @@ +<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>9.0.30729</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{2A59DE0A-B76A-4B42-9A33-04D34548353D}</ProjectGuid> + <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>OpenIdProviderWebForms</RootNamespace> + <AssemblyName>OpenIdProviderWebForms</AssemblyName> + <TargetFrameworkVersion>v3.5</TargetFrameworkVersion> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\</OutputPath> + <DefineConstants>DEBUG</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\..\lib\log4net.dll</HintPath> + </Reference> + <Reference Include="System" /> + <Reference Include="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.Data" /> + <Reference Include="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.Drawing" /> + <Reference Include="System.Web" /> + <Reference Include="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.Web.Extensions.Design, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.Xml" /> + <Reference Include="System.Configuration" /> + <Reference Include="System.Web.Services" /> + <Reference Include="System.EnterpriseServices" /> + <Reference Include="System.Web.Mobile" /> + <Reference Include="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + </ItemGroup> + <ItemGroup> + <Content Include="App_Data\Users.xml" /> + <Content Include="op_xrds.aspx" /> + <Content Include="decide.aspx" /> + <Content Include="Default.aspx" /> + <Content Include="login.aspx" /> + <Content Include="ProfileFields.ascx" /> + <Content Include="server.aspx" /> + <Content Include="user.aspx" /> + <Content Include="Global.asax" /> + <Content Include="Web.config" /> + <Content Include="user_xrds.aspx" /> + </ItemGroup> + <ItemGroup> + <Compile Include="Code\CustomStore.cs" /> + <Compile Include="Code\CustomStoreDataSet.Designer.cs"> + <DependentUpon>CustomStoreDataSet.xsd</DependentUpon> + <AutoGen>True</AutoGen> + <DesignTime>True</DesignTime> + </Compile> + <Compile Include="Code\ReadOnlyXmlMembershipProvider.cs" /> + <Compile Include="Code\TracePageAppender.cs" /> + <Compile Include="Code\URLRewriter.cs" /> + <Compile Include="Code\Util.cs" /> + <Compile Include="decide.aspx.cs"> + <DependentUpon>decide.aspx</DependentUpon> + <SubType>ASPXCodeBehind</SubType> + </Compile> + <Compile Include="decide.aspx.designer.cs"> + <DependentUpon>decide.aspx</DependentUpon> + </Compile> + <Compile Include="Global.asax.cs"> + <DependentUpon>Global.asax</DependentUpon> + </Compile> + <Compile Include="login.aspx.cs"> + <DependentUpon>login.aspx</DependentUpon> + <SubType>ASPXCodeBehind</SubType> + </Compile> + <Compile Include="login.aspx.designer.cs"> + <DependentUpon>login.aspx</DependentUpon> + </Compile> + <Compile Include="ProfileFields.ascx.cs"> + <DependentUpon>ProfileFields.ascx</DependentUpon> + <SubType>ASPXCodeBehind</SubType> + </Compile> + <Compile Include="ProfileFields.ascx.designer.cs"> + <DependentUpon>ProfileFields.ascx</DependentUpon> + </Compile> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Provider.ashx.cs"> + <DependentUpon>Provider.ashx</DependentUpon> + </Compile> + <Compile Include="server.aspx.cs"> + <DependentUpon>server.aspx</DependentUpon> + <SubType>ASPXCodeBehind</SubType> + </Compile> + <Compile Include="server.aspx.designer.cs"> + <DependentUpon>server.aspx</DependentUpon> + </Compile> + <Compile Include="TracePage.aspx.cs"> + <DependentUpon>TracePage.aspx</DependentUpon> + <SubType>ASPXCodeBehind</SubType> + </Compile> + <Compile Include="TracePage.aspx.designer.cs"> + <DependentUpon>TracePage.aspx</DependentUpon> + </Compile> + <Compile Include="user.aspx.cs"> + <DependentUpon>user.aspx</DependentUpon> + <SubType>ASPXCodeBehind</SubType> + </Compile> + <Compile Include="user.aspx.designer.cs"> + <DependentUpon>user.aspx</DependentUpon> + </Compile> + </ItemGroup> + <ItemGroup> + <Content Include="favicon.ico" /> + <Content Include="images\dotnetopenid_tiny.gif" /> + <Content Include="Site.Master" /> + <Content Include="styles.css" /> + <Content Include="TracePage.aspx" /> + </ItemGroup> + <ItemGroup> + <None Include="Code\CustomStoreDataSet.xsc"> + <DependentUpon>CustomStoreDataSet.xsd</DependentUpon> + </None> + <None Include="Code\CustomStoreDataSet.xsd"> + <Generator>MSDataSetGenerator</Generator> + <LastGenOutput>CustomStoreDataSet.Designer.cs</LastGenOutput> + <SubType>Designer</SubType> + </None> + <None Include="Code\CustomStoreDataSet.xss"> + <DependentUpon>CustomStoreDataSet.xsd</DependentUpon> + </None> + <Content Include="Provider.ashx" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\src\DotNetOpenAuth\DotNetOpenAuth.csproj"> + <Project>{3191B653-F76D-4C1A-9A5A-347BC3AAAAB7}</Project> + <Name>DotNetOpenAuth</Name> + </ProjectReference> + </ItemGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> + <ProjectExtensions> + <VisualStudio> + <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}"> + <WebProjectProperties> + <UseIIS>False</UseIIS> + <AutoAssignPort>True</AutoAssignPort> + <DevelopmentServerPort>28597</DevelopmentServerPort> + <DevelopmentServerVPath>/</DevelopmentServerVPath> + <IISUrl> + </IISUrl> + <NTLMAuthentication>False</NTLMAuthentication> + <UseCustomServer>False</UseCustomServer> + <CustomServerUrl> + </CustomServerUrl> + <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile> + </WebProjectProperties> + </FlavorProperties> + </VisualStudio> + </ProjectExtensions> +</Project>
\ No newline at end of file diff --git a/samples/OpenIdProviderWebForms/ProfileFields.ascx b/samples/OpenIdProviderWebForms/ProfileFields.ascx new file mode 100644 index 0000000..9f368d5 --- /dev/null +++ b/samples/OpenIdProviderWebForms/ProfileFields.ascx @@ -0,0 +1,1024 @@ +<%@ Control Language="C#" AutoEventWireup="true" Inherits="OpenIdProviderWebForms.ProfileFields" CodeBehind="ProfileFields.ascx.cs" %> +This consumer has requested the following fields from you<br /> +<table> + <tr> + <td> + + </td> + <td> + <asp:HyperLink ID="privacyLink" runat="server" Text="Privacy Policy" + Target="_blank" /> + </td> + </tr> + <tr runat="server" id="nicknameRow"> + <td> + Nickname + <asp:Label ID="nicknameRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label> + </td> + <td> + <asp:TextBox ID="nicknameTextBox" runat="server"></asp:TextBox> + </td> + </tr> + <tr runat="server" id="emailRow"> + <td> + Email + <asp:Label ID="emailRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label> + </td> + <td> + <asp:TextBox ID="emailTextBox" runat="server"></asp:TextBox> + </td> + </tr> + <tr runat="server" id="fullnameRow"> + <td> + FullName + <asp:Label ID="fullnameRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label> + </td> + <td> + <asp:TextBox ID="fullnameTextBox" runat="server"></asp:TextBox> + </td> + </tr> + <tr runat="server" id="dateOfBirthRow"> + <td> + Date of Birth + <asp:Label ID="dobRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label> + </td> + <td> + <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> + <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> + + <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> + </tr> + <tr runat="server" id="genderRow"> + <td> + Gender + <asp:Label ID="genderRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label> + </td> + <td> + <asp:DropDownList ID="genderDropdownList" runat="server"> + <asp:ListItem Selected="True"></asp:ListItem> + <asp:ListItem>Male</asp:ListItem> + <asp:ListItem>Female</asp:ListItem> + </asp:DropDownList> + </td> + </tr> + <tr runat="server" id="postcodeRow"> + <td> + Post Code + <asp:Label ID="postcodeRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label> + </td> + <td> + <asp:TextBox ID="postcodeTextBox" runat="server"></asp:TextBox> + </td> + </tr> + <tr runat="server" id="countryRow"> + <td> + Country + <asp:Label ID="countryRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label> + </td> + <td> + <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> + </tr> + <tr runat="server" id="languageRow"> + <td> + Language + <asp:Label ID="languageRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label> + </td> + <td> + <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> + </tr> + <tr runat="server" id="timezoneRow"> + <td> + Timezone + <asp:Label ID="timezoneRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label> + </td> + <td> + <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> + + </td> + </tr> + <tr> + <td> + </td> + <td> + </td> + </tr> + <tr> + <td colspan="2"> + Note: Fields marked with a * are required by the consumer + </td> + </tr> +</table> diff --git a/samples/OpenIdProviderWebForms/ProfileFields.ascx.cs b/samples/OpenIdProviderWebForms/ProfileFields.ascx.cs new file mode 100644 index 0000000..893830f --- /dev/null +++ b/samples/OpenIdProviderWebForms/ProfileFields.ascx.cs @@ -0,0 +1,137 @@ +namespace OpenIdProviderWebForms { + using System; + using DotNetOpenAuth.OpenId.Extensions; + using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; + + /// <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 { + public bool DoesAnyFieldHaveAValue { + get { + return !((this.DateOfBirth == null) + && string.IsNullOrEmpty(this.countryDropdownList.SelectedValue) + && string.IsNullOrEmpty(this.emailTextBox.Text) + && string.IsNullOrEmpty(this.fullnameTextBox.Text) + && (this.Gender == null) + && string.IsNullOrEmpty(this.languageDropdownList.SelectedValue) + && string.IsNullOrEmpty(this.nicknameTextBox.Text) + && string.IsNullOrEmpty(this.postcodeTextBox.Text) + && string.IsNullOrEmpty(this.timezoneDropdownList.SelectedValue)); + } + } + + public DateTime? DateOfBirth { + get { + try { + int day = Convert.ToInt32(this.dobDayDropdownlist.SelectedValue); + int month = Convert.ToInt32(this.dobMonthDropdownlist.SelectedValue); + int year = Convert.ToInt32(this.dobYearDropdownlist.SelectedValue); + DateTime newDate = new DateTime(year, month, day); + return newDate; + } catch (Exception) { + return null; + } + } + + set { + if (value.HasValue) { + this.dobDayDropdownlist.SelectedValue = value.Value.Day.ToString(); + this.dobMonthDropdownlist.SelectedValue = value.Value.Month.ToString(); + this.dobYearDropdownlist.SelectedValue = value.Value.Year.ToString(); + } else { + this.dobDayDropdownlist.SelectedValue = string.Empty; + this.dobMonthDropdownlist.SelectedValue = string.Empty; + this.dobYearDropdownlist.SelectedValue = string.Empty; + } + } + } + + public Gender? Gender { + get { + if (this.genderDropdownList.SelectedValue == "Male") { + return DotNetOpenAuth.OpenId.Extensions.SimpleRegistration.Gender.Male; + } + if (this.genderDropdownList.SelectedValue == "Female") { + return DotNetOpenAuth.OpenId.Extensions.SimpleRegistration.Gender.Female; + } + return null; + } + + set { + if (value.HasValue) { + this.genderDropdownList.SelectedValue = value.Value.ToString(); + } else { + this.genderDropdownList.SelectedIndex = -1; + } + } + } + + public void SetRequiredFieldsFromRequest(ClaimsRequest requestFields) { + if (requestFields.PolicyUrl != null) { + this.privacyLink.NavigateUrl = requestFields.PolicyUrl.AbsoluteUri; + } else { + this.privacyLink.Visible = false; + } + + this.dobRequiredLabel.Visible = (requestFields.BirthDate == DemandLevel.Require); + this.countryRequiredLabel.Visible = (requestFields.Country == DemandLevel.Require); + this.emailRequiredLabel.Visible = (requestFields.Email == DemandLevel.Require); + this.fullnameRequiredLabel.Visible = (requestFields.FullName == DemandLevel.Require); + this.genderRequiredLabel.Visible = (requestFields.Gender == DemandLevel.Require); + this.languageRequiredLabel.Visible = (requestFields.Language == DemandLevel.Require); + this.nicknameRequiredLabel.Visible = (requestFields.Nickname == DemandLevel.Require); + this.postcodeRequiredLabel.Visible = (requestFields.PostalCode == DemandLevel.Require); + this.timezoneRequiredLabel.Visible = (requestFields.TimeZone == DemandLevel.Require); + + this.dateOfBirthRow.Visible = !(requestFields.BirthDate == DemandLevel.NoRequest); + this.countryRow.Visible = !(requestFields.Country == DemandLevel.NoRequest); + this.emailRow.Visible = !(requestFields.Email == DemandLevel.NoRequest); + this.fullnameRow.Visible = !(requestFields.FullName == DemandLevel.NoRequest); + this.genderRow.Visible = !(requestFields.Gender == DemandLevel.NoRequest); + this.languageRow.Visible = !(requestFields.Language == DemandLevel.NoRequest); + this.nicknameRow.Visible = !(requestFields.Nickname == DemandLevel.NoRequest); + this.postcodeRow.Visible = !(requestFields.PostalCode == DemandLevel.NoRequest); + this.timezoneRow.Visible = !(requestFields.TimeZone == DemandLevel.NoRequest); + } + + public ClaimsResponse GetOpenIdProfileFields(ClaimsRequest request) { + if (request == null) { + throw new ArgumentNullException("request"); + } + + ClaimsResponse fields = request.CreateResponse(); + fields.BirthDate = this.DateOfBirth; + fields.Country = this.countryDropdownList.SelectedValue; + fields.Email = this.emailTextBox.Text; + fields.FullName = this.fullnameTextBox.Text; + fields.Gender = this.Gender; + fields.Language = this.languageDropdownList.SelectedValue; + fields.Nickname = this.nicknameTextBox.Text; + fields.PostalCode = this.postcodeTextBox.Text; + fields.TimeZone = this.timezoneDropdownList.SelectedValue; + return fields; + } + + public void SetOpenIdProfileFields(ClaimsResponse value) { + if (value == null) { + throw new ArgumentNullException("value"); + } + + this.DateOfBirth = value.BirthDate; + this.countryDropdownList.SelectedValue = value.Country; + this.emailTextBox.Text = value.Email; + this.fullnameTextBox.Text = value.FullName; + this.Gender = value.Gender; + this.languageDropdownList.SelectedValue = value.Language; + this.nicknameTextBox.Text = value.Nickname; + this.postcodeTextBox.Text = value.PostalCode; + this.timezoneDropdownList.SelectedValue = value.TimeZone; + } + + protected void Page_Load(object sender, EventArgs e) { + } + } +}
\ No newline at end of file diff --git a/samples/OpenIdProviderWebForms/ProfileFields.ascx.designer.cs b/samples/OpenIdProviderWebForms/ProfileFields.ascx.designer.cs new file mode 100644 index 0000000..e546539 --- /dev/null +++ b/samples/OpenIdProviderWebForms/ProfileFields.ascx.designer.cs @@ -0,0 +1,286 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:2.0.50727.3521 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace OpenIdProviderWebForms { + + + public partial class ProfileFields { + + /// <summary> + /// privacyLink control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.HyperLink privacyLink; + + /// <summary> + /// nicknameRow control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.HtmlControls.HtmlTableRow nicknameRow; + + /// <summary> + /// nicknameRequiredLabel control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.Label nicknameRequiredLabel; + + /// <summary> + /// nicknameTextBox control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.TextBox nicknameTextBox; + + /// <summary> + /// emailRow control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.HtmlControls.HtmlTableRow emailRow; + + /// <summary> + /// emailRequiredLabel control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.Label emailRequiredLabel; + + /// <summary> + /// emailTextBox control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.TextBox emailTextBox; + + /// <summary> + /// fullnameRow control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.HtmlControls.HtmlTableRow fullnameRow; + + /// <summary> + /// fullnameRequiredLabel control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.Label fullnameRequiredLabel; + + /// <summary> + /// fullnameTextBox control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.TextBox fullnameTextBox; + + /// <summary> + /// dateOfBirthRow control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.HtmlControls.HtmlTableRow dateOfBirthRow; + + /// <summary> + /// dobRequiredLabel control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.Label dobRequiredLabel; + + /// <summary> + /// dobDayDropdownlist control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.DropDownList dobDayDropdownlist; + + /// <summary> + /// dobMonthDropdownlist control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.DropDownList dobMonthDropdownlist; + + /// <summary> + /// dobYearDropdownlist control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.DropDownList dobYearDropdownlist; + + /// <summary> + /// genderRow control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.HtmlControls.HtmlTableRow genderRow; + + /// <summary> + /// genderRequiredLabel control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.Label genderRequiredLabel; + + /// <summary> + /// genderDropdownList control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.DropDownList genderDropdownList; + + /// <summary> + /// postcodeRow control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.HtmlControls.HtmlTableRow postcodeRow; + + /// <summary> + /// postcodeRequiredLabel control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.Label postcodeRequiredLabel; + + /// <summary> + /// postcodeTextBox control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.TextBox postcodeTextBox; + + /// <summary> + /// countryRow control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.HtmlControls.HtmlTableRow countryRow; + + /// <summary> + /// countryRequiredLabel control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.Label countryRequiredLabel; + + /// <summary> + /// countryDropdownList control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.DropDownList countryDropdownList; + + /// <summary> + /// languageRow control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.HtmlControls.HtmlTableRow languageRow; + + /// <summary> + /// languageRequiredLabel control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.Label languageRequiredLabel; + + /// <summary> + /// languageDropdownList control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.DropDownList languageDropdownList; + + /// <summary> + /// timezoneRow control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.HtmlControls.HtmlTableRow timezoneRow; + + /// <summary> + /// timezoneRequiredLabel control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.Label timezoneRequiredLabel; + + /// <summary> + /// timezoneDropdownList control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.DropDownList timezoneDropdownList; + } +} diff --git a/samples/OpenIdProviderWebForms/Properties/AssemblyInfo.cs b/samples/OpenIdProviderWebForms/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..42b2126 --- /dev/null +++ b/samples/OpenIdProviderWebForms/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenIdProviderWebForms sample")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ProviderPortal")] +[assembly: AssemblyCopyright("Copyright © 2008")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("3d5900ae-111a-45be-96b3-d9e4606ca793")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/samples/OpenIdProviderWebForms/Provider.ashx b/samples/OpenIdProviderWebForms/Provider.ashx new file mode 100644 index 0000000..aa90b8f --- /dev/null +++ b/samples/OpenIdProviderWebForms/Provider.ashx @@ -0,0 +1 @@ +<%@ WebHandler Language="C#" CodeBehind="Provider.ashx.cs" Class="OpenIdProviderWebForms.Provider" %> diff --git a/samples/OpenIdProviderWebForms/Provider.ashx.cs b/samples/OpenIdProviderWebForms/Provider.ashx.cs new file mode 100644 index 0000000..5257a5d --- /dev/null +++ b/samples/OpenIdProviderWebForms/Provider.ashx.cs @@ -0,0 +1,61 @@ +namespace OpenIdProviderWebForms { + using System.Web; + using System.Web.SessionState; + using DotNetOpenAuth.OpenId.Provider; + + /// <summary> + /// A fast OpenID message handler that responds to OpenID messages + /// directed at the Provider. + /// </summary> + /// <remarks> + /// This performs the same function as server.aspx, which uses the ProviderEndpoint + /// control to reduce the amount of source code in the web site. A typical Provider + /// site will have EITHER this .ashx handler OR the .aspx page -- NOT both. + /// </remarks> + public class Provider : IHttpHandler, IRequiresSessionState { + public bool IsReusable { + get { return true; } + } + + public void ProcessRequest(HttpContext context) { + OpenIdProvider provider = new OpenIdProvider(); + IRequest request = provider.GetRequest(); + if (request != null) { + // Some OpenID requests are automatable and can be responded to immediately. + if (!request.IsResponseReady) { + // But authentication requests cannot be responded to until something on + // this site decides whether to approve or disapprove the authentication. + var idrequest = (IAuthenticationRequest)request; + + // We store the authentication request in the user's session so that + // redirects and user prompts can appear and eventually some page can decide + // to respond to the OpenID authentication request either affirmatively or + // negatively. + ProviderEndpoint.PendingAuthenticationRequest = idrequest; + + // We delegate that approval process to our utility method that we share + // with our other Provider sample page server.aspx. + Code.Util.ProcessAuthenticationChallenge(idrequest); + + // As part of authentication approval, the user may need to authenticate + // to this Provider and/or decide whether to allow the requesting RP site + // to log this user in. If any UI needs to be presented to the user, + // the previous call to ProcessAuthenticationChallenge MAY not return + // due to a redirect to some ASPX page. + } else { + // Some other automatable OpenID request is coming down, so clear + // any previously session stored authentication request that might be + // stored for this user. + ProviderEndpoint.PendingAuthenticationRequest = null; + } + + // Whether this was an automated message or an authentication message, + // if there is a response ready to send back immediately, do so. + if (request.IsResponseReady) { + request.Response.Send(); + ProviderEndpoint.PendingAuthenticationRequest = null; + } + } + } + } +} diff --git a/samples/OpenIdProviderWebForms/Site.Master b/samples/OpenIdProviderWebForms/Site.Master new file mode 100644 index 0000000..c7aa510 --- /dev/null +++ b/samples/OpenIdProviderWebForms/Site.Master @@ -0,0 +1,20 @@ +<%@ Master Language="C#" AutoEventWireup="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 id="Head1" runat="server"> + <title>OpenID Provider, by DotNetOpenId</title> + <link href="/styles.css" rel="stylesheet" type="text/css" /> + <asp:ContentPlaceHolder ID="head" runat="server" /> +</head> +<body> + <form id="form1" runat="server"> + <div><a href="http://dotnetopenid.googlecode.com"> + <img runat="server" src="~/images/dotnetopenid_tiny.gif" title="Jump to the project web site." + alt="DotNetOpenId" border='0' /></a> </div> + <div> + <asp:ContentPlaceHolder ID="Main" runat="server" /> + </div> + </form> +</body> +</html> diff --git a/samples/OpenIdProviderWebForms/TracePage.aspx b/samples/OpenIdProviderWebForms/TracePage.aspx new file mode 100644 index 0000000..615b445 --- /dev/null +++ b/samples/OpenIdProviderWebForms/TracePage.aspx @@ -0,0 +1,16 @@ +<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TracePage.aspx.cs" Inherits="OpenIdProviderWebForms.TracePage" %> + +<!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></title> +</head> +<body> + <form id="form1" runat="server"> + <p align="right"> + <asp:Button runat="server" Text="Clear log" ID="clearLogButton" OnClick="clearLogButton_Click" /> + </p> + <pre><asp:PlaceHolder runat="server" ID="placeHolder1" /></pre> + </form> +</body> +</html> diff --git a/samples/OpenIdProviderWebForms/TracePage.aspx.cs b/samples/OpenIdProviderWebForms/TracePage.aspx.cs new file mode 100644 index 0000000..5dcb18f --- /dev/null +++ b/samples/OpenIdProviderWebForms/TracePage.aspx.cs @@ -0,0 +1,21 @@ +namespace OpenIdProviderWebForms { + using System; + using System.Collections.Generic; + using System.Web; + using System.Web.UI; + using System.Web.UI.WebControls; + using OpenIdProviderWebForms.Code; + + public partial class TracePage : System.Web.UI.Page { + protected void Page_Load(object sender, EventArgs e) { + this.placeHolder1.Controls.Add(new Label { Text = Global.LogMessages.ToString() }); + } + + protected void clearLogButton_Click(object sender, EventArgs e) { + Global.LogMessages.Length = 0; + + // clear the page immediately, and allow for F5 without a Postback warning. + Response.Redirect(Request.Url.AbsoluteUri); + } + } +}
\ No newline at end of file diff --git a/samples/OpenIdProviderWebForms/TracePage.aspx.designer.cs b/samples/OpenIdProviderWebForms/TracePage.aspx.designer.cs new file mode 100644 index 0000000..6760f9b --- /dev/null +++ b/samples/OpenIdProviderWebForms/TracePage.aspx.designer.cs @@ -0,0 +1,43 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:2.0.50727.3521 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace OpenIdProviderWebForms { + + + public partial class TracePage { + + /// <summary> + /// form1 control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.HtmlControls.HtmlForm form1; + + /// <summary> + /// clearLogButton control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.Button clearLogButton; + + /// <summary> + /// placeHolder1 control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.PlaceHolder placeHolder1; + } +} diff --git a/samples/OpenIdProviderWebForms/Web.config b/samples/OpenIdProviderWebForms/Web.config new file mode 100644 index 0000000..598e4bf --- /dev/null +++ b/samples/OpenIdProviderWebForms/Web.config @@ -0,0 +1,192 @@ +<?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> + <section name="uri" type="System.Configuration.UriSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> + <section name="urlrewrites" type="OpenIdProviderWebForms.Code.URLRewriter" requirePermission="false"/> + <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler" requirePermission="false"/> + <section name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection" requirePermission="false" allowLocation="true"/> + <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> + <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> + <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/> + <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> + <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/> + <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/> + <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/> + <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/> + </sectionGroup> + </sectionGroup> + </sectionGroup> + </configSections> + <!-- this is an optional configuration section where aspects of dotnetopenid can be customized --> + <dotNetOpenAuth> + <openid> + <provider> + <!-- Uncomment the following to activate the sample custom store. --> + <!--<store type="OpenIdProviderWebForms.Code.CustomStore, OpenIdProviderWebForms" />--> + </provider> + </openid> + <messaging> + <untrustedWebRequest> + <whitelistHosts> + <!-- since this is a sample, and will often be used with localhost --> + <add name="localhost"/> + </whitelistHosts> + </untrustedWebRequest> + </messaging> + </dotNetOpenAuth> + <!-- The uri section is necessary to turn on .NET 3.5 support for IDN (international domain names), + which is necessary for OpenID urls with unicode characters in the domain/host name. --> + <uri> + <idn enabled="All"/> + <iriParsing enabled="true"/> + </uri> + <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. + --> + <urlrewrites> + <rule> + <!-- This rewrites urls like: user/john ->user.aspx?username=john--> + <url>/user/(.*)</url> + <rewrite>/user.aspx?username=$1</rewrite> + </rule> + </urlrewrites> + <system.web> + <!-- + 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"> + <assemblies> + <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/> + <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> + <add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/> + <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/> + </assemblies> + </compilation> + <sessionState mode="InProc" cookieless="false"/> + <membership defaultProvider="AspNetReadOnlyXmlMembershipProvider"> + <providers> + <clear/> + <add name="AspNetReadOnlyXmlMembershipProvider" type="OpenIdProviderWebForms.Code.ReadOnlyXmlMembershipProvider" description="Read-only XML membership provider" xmlFileName="~/App_Data/Users.xml"/> + </providers> + </membership> + <authentication mode="Forms"> + <forms name="ProviderSession"/> + <!-- named cookie prevents conflicts with other samples --> + </authentication> + <customErrors mode="RemoteOnly"/> + <!-- Trust level discussion: + Full: everything works + High: TRACE compilation symbol must NOT be defined + Medium/Low: doesn't work on default machine.config, because WebPermission.Connect is denied. + --> + <trust level="High" originUrl=""/> + <pages> + <controls> + <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> + <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> + </controls> + </pages> + <httpHandlers> + <remove verb="*" path="*.asmx"/> + <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> + <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> + <add verb="GET,HEAD" path="ScriptResource.axd" validate="false" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> + </httpHandlers> + <httpModules> + <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> + </httpModules> + </system.web> + <location path="decide.aspx"> + <system.web> + <authorization> + <deny users="?"/> + </authorization> + </system.web> + </location> + <!-- log4net is a 3rd party (free) logger library that dotnetopenid will use if present but does not require. --> + <log4net> + <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender"> + <file value="Provider.log"/> + <appendToFile value="true"/> + <rollingStyle value="Size"/> + <maxSizeRollBackups value="10"/> + <maximumFileSize value="100KB"/> + <staticLogFileName value="true"/> + <layout type="log4net.Layout.PatternLayout"> + <conversionPattern value="%date (GMT%date{%z}) [%thread] %-5level %logger - %message%newline"/> + </layout> + </appender> + <appender name="TracePageAppender" type="ProviderPortal.Code.TracePageAppender, ProviderPortal"> + <layout type="log4net.Layout.PatternLayout"> + <conversionPattern value="%date (GMT%date{%z}) [%thread] %-5level %logger - %message%newline"/> + </layout> + </appender> + <!-- Setup the root category, add the appenders and set the default level --> + <root> + <level value="INFO"/> + <!--<appender-ref ref="RollingFileAppender" />--> + <appender-ref ref="TracePageAppender"/> + </root> + <!-- Specify the level for some specific categories --> + <logger name="DotNetOpenId"> + <level value="ALL"/> + </logger> + </log4net> + <system.codedom> + <compilers> + <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider,System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4"> + <providerOption name="CompilerVersion" value="v3.5"/> + <providerOption name="WarnAsError" value="false"/> + </compiler> + <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4"> + <providerOption name="CompilerVersion" value="v3.5"/> + <providerOption name="OptionInfer" value="true"/> + <providerOption name="WarnAsError" value="false"/> + </compiler> + </compilers> + </system.codedom> + <system.webServer> + <validation validateIntegratedModeConfiguration="false"/> + <modules> + <remove name="ScriptModule"/> + <add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> + </modules> + <handlers> + <remove name="WebServiceHandlerFactory-Integrated"/> + <remove name="ScriptHandlerFactory"/> + <remove name="ScriptHandlerFactoryAppServices"/> + <remove name="ScriptResource"/> + <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> + <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> + <add name="ScriptResource" verb="GET,HEAD" path="ScriptResource.axd" preCondition="integratedMode" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> + </handlers> + </system.webServer> + <runtime> + <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> + <dependentAssembly> + <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/> + <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/> + <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/> + </dependentAssembly> + </assemblyBinding> + </runtime> +</configuration> diff --git a/samples/OpenIdProviderWebForms/decide.aspx b/samples/OpenIdProviderWebForms/decide.aspx new file mode 100644 index 0000000..54c2f01 --- /dev/null +++ b/samples/OpenIdProviderWebForms/decide.aspx @@ -0,0 +1,34 @@ +<%@ Page Language="C#" AutoEventWireup="true" Inherits="OpenIdProviderWebForms.decide" CodeBehind="decide.aspx.cs" MasterPageFile="~/Site.Master" %> + +<%@ Register Src="ProfileFields.ascx" TagName="ProfileFields" TagPrefix="uc1" %> +<asp:Content runat="server" ContentPlaceHolderID="Main"> + <p> + A site has asked to authenticate that you own the identifier below. You should + only do this if you wish to log in to the site given by the Realm.</p> + <p> + This site + <asp:Label ID="relyingPartyVerificationResultLabel" runat="server" + Font-Bold="True" Text="failed" /> verification. </p> + <table> + <tr> + <td> + Identifier: </td> + <td> + <asp:Label runat="server" ID='identityUrlLabel' /> + </td> + </tr> + <tr> + <td> + Realm: </td> + <td> + <asp:Label runat="server" ID='realmLabel' /> + </td> + </tr> + </table> + <p> + Allow this authentication to proceed? + </p> + <uc1:ProfileFields ID="profileFields" runat="server" Visible="false" /> + <asp:Button ID="yes_button" OnClick="Yes_Click" Text=" yes " runat="Server" /> + <asp:Button ID="no_button" OnClick="No_Click" Text=" no " runat="Server" /> +</asp:Content>
\ No newline at end of file diff --git a/samples/OpenIdProviderWebForms/decide.aspx.cs b/samples/OpenIdProviderWebForms/decide.aspx.cs new file mode 100644 index 0000000..1ca0138 --- /dev/null +++ b/samples/OpenIdProviderWebForms/decide.aspx.cs @@ -0,0 +1,75 @@ +namespace OpenIdProviderWebForms { + using System; + using System.Diagnostics; + using System.Web.Security; + using System.Web.UI; + using DotNetOpenAuth.OpenId.Extensions.ProviderAuthenticationPolicy; + using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; + using DotNetOpenAuth.OpenId.Provider; + + /// <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) { + if (ProviderEndpoint.PendingAuthenticationRequest == null) { + Response.Redirect("~/"); + } + + if (ProviderEndpoint.PendingAuthenticationRequest.IsDirectedIdentity) { + ProviderEndpoint.PendingAuthenticationRequest.LocalIdentifier = Code.Util.BuildIdentityUrl(); + } + this.relyingPartyVerificationResultLabel.Text = + ProviderEndpoint.PendingAuthenticationRequest.IsReturnUrlDiscoverable ? "passed" : "failed"; + + this.identityUrlLabel.Text = ProviderEndpoint.PendingAuthenticationRequest.LocalIdentifier.ToString(); + this.realmLabel.Text = ProviderEndpoint.PendingAuthenticationRequest.Realm.ToString(); + + // check that the logged in user is the same as the user requesting authentication to the consumer. If not, then log them out. + if (string.Equals(User.Identity.Name, Code.Util.ExtractUserName(ProviderEndpoint.PendingAuthenticationRequest.LocalIdentifier), StringComparison.OrdinalIgnoreCase)) { + // if simple registration fields were used, then prompt the user for them + var requestedFields = ProviderEndpoint.PendingAuthenticationRequest.GetExtension<ClaimsRequest>(); + if (requestedFields != null) { + this.profileFields.Visible = true; + this.profileFields.SetRequiredFieldsFromRequest(requestedFields); + if (!IsPostBack) { + var sregResponse = requestedFields.CreateResponse(); + sregResponse.Email = Membership.GetUser().Email; + this.profileFields.SetOpenIdProfileFields(sregResponse); + } + } + } else { + FormsAuthentication.SignOut(); + Response.Redirect(Request.Url.AbsoluteUri); + } + } + + protected void Yes_Click(object sender, EventArgs e) { + var sregRequest = ProviderEndpoint.PendingAuthenticationRequest.GetExtension<ClaimsRequest>(); + ClaimsResponse sregResponse = null; + if (sregRequest != null) { + sregResponse = this.profileFields.GetOpenIdProfileFields(sregRequest); + ProviderEndpoint.PendingAuthenticationRequest.AddResponseExtension(sregResponse); + } + var papeRequest = ProviderEndpoint.PendingAuthenticationRequest.GetExtension<PolicyRequest>(); + PolicyResponse papeResponse = null; + if (papeRequest != null) { + papeResponse = new PolicyResponse(); + papeResponse.NistAssuranceLevel = NistAssuranceLevel.InsufficientForLevel1; + ProviderEndpoint.PendingAuthenticationRequest.AddResponseExtension(papeResponse); + } + + ProviderEndpoint.PendingAuthenticationRequest.IsAuthenticated = true; + Debug.Assert(ProviderEndpoint.PendingAuthenticationRequest.IsResponseReady, "Setting authentication should be all that's necessary."); + ProviderEndpoint.PendingAuthenticationRequest.Response.Send(); + ProviderEndpoint.PendingAuthenticationRequest = null; + } + + protected void No_Click(object sender, EventArgs e) { + ProviderEndpoint.PendingAuthenticationRequest.IsAuthenticated = false; + Debug.Assert(ProviderEndpoint.PendingAuthenticationRequest.IsResponseReady, "Setting authentication should be all that's necessary."); + ProviderEndpoint.PendingAuthenticationRequest.Response.Send(); + ProviderEndpoint.PendingAuthenticationRequest = null; + } + } +}
\ No newline at end of file diff --git a/samples/OpenIdProviderWebForms/decide.aspx.designer.cs b/samples/OpenIdProviderWebForms/decide.aspx.designer.cs new file mode 100644 index 0000000..795d1c7 --- /dev/null +++ b/samples/OpenIdProviderWebForms/decide.aspx.designer.cs @@ -0,0 +1,70 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:2.0.50727.3521 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace OpenIdProviderWebForms { + + + public partial class decide { + + /// <summary> + /// relyingPartyVerificationResultLabel control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.Label relyingPartyVerificationResultLabel; + + /// <summary> + /// identityUrlLabel control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.Label identityUrlLabel; + + /// <summary> + /// realmLabel control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.Label realmLabel; + + /// <summary> + /// profileFields control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::OpenIdProviderWebForms.ProfileFields profileFields; + + /// <summary> + /// yes_button control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.Button yes_button; + + /// <summary> + /// no_button control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.Button no_button; + } +} diff --git a/samples/OpenIdProviderWebForms/favicon.ico b/samples/OpenIdProviderWebForms/favicon.ico Binary files differnew file mode 100644 index 0000000..beb3cb5 --- /dev/null +++ b/samples/OpenIdProviderWebForms/favicon.ico diff --git a/samples/OpenIdProviderWebForms/images/dotnetopenid_tiny.gif b/samples/OpenIdProviderWebForms/images/dotnetopenid_tiny.gif Binary files differnew file mode 100644 index 0000000..c4ed4f5 --- /dev/null +++ b/samples/OpenIdProviderWebForms/images/dotnetopenid_tiny.gif diff --git a/samples/OpenIdProviderWebForms/login.aspx b/samples/OpenIdProviderWebForms/login.aspx new file mode 100644 index 0000000..e8f42c5 --- /dev/null +++ b/samples/OpenIdProviderWebForms/login.aspx @@ -0,0 +1,17 @@ +<%@ Page Language="C#" AutoEventWireup="true" Inherits="OpenIdProviderWebForms.login" CodeBehind="login.aspx.cs" MasterPageFile="~/Site.Master" %> +<asp:Content ID="Content1" runat="server" ContentPlaceHolderID="Main"> + <p> + Usernames are defined in the App_Data\Users.xml file. + </p> + <asp:Login runat="server" ID="login1" /> + + <p>Credentials to try (each with their own OpenID)</p> + <table> + <tr><td>Username</td><td>Password</td></tr> + <tr><td>bob</td><td>test</td></tr> + <tr><td>bob1</td><td>test</td></tr> + <tr><td>bob2</td><td>test</td></tr> + <tr><td>bob3</td><td>test</td></tr> + <tr><td>bob4</td><td>test</td></tr> + </table> +</asp:Content>
\ No newline at end of file diff --git a/samples/OpenIdProviderWebForms/login.aspx.cs b/samples/OpenIdProviderWebForms/login.aspx.cs new file mode 100644 index 0000000..4051877 --- /dev/null +++ b/samples/OpenIdProviderWebForms/login.aspx.cs @@ -0,0 +1,22 @@ +namespace OpenIdProviderWebForms { + using System; + using System.Web.UI.WebControls; + using DotNetOpenAuth.OpenId.Provider; + + /// <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) { + if (!IsPostBack) { + if (ProviderEndpoint.PendingAuthenticationRequest != null && + !ProviderEndpoint.PendingAuthenticationRequest.IsDirectedIdentity) { + this.login1.UserName = Code.Util.ExtractUserName( + ProviderEndpoint.PendingAuthenticationRequest.LocalIdentifier); + ((TextBox)this.login1.FindControl("UserName")).ReadOnly = true; + this.login1.FindControl("Password").Focus(); + } + } + } + } +}
\ No newline at end of file diff --git a/samples/OpenIdProviderWebForms/login.aspx.designer.cs b/samples/OpenIdProviderWebForms/login.aspx.designer.cs new file mode 100644 index 0000000..83826a1 --- /dev/null +++ b/samples/OpenIdProviderWebForms/login.aspx.designer.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:2.0.50727.3521 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace OpenIdProviderWebForms { + + + public partial class login { + + /// <summary> + /// login1 control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.Login login1; + } +} diff --git a/samples/OpenIdProviderWebForms/op_xrds.aspx b/samples/OpenIdProviderWebForms/op_xrds.aspx new file mode 100644 index 0000000..afcfc75 --- /dev/null +++ b/samples/OpenIdProviderWebForms/op_xrds.aspx @@ -0,0 +1,19 @@ +<%@ Page Language="C#" AutoEventWireup="true" ContentType="application/xrds+xml" %><?xml version="1.0" encoding="UTF-8"?> +<%-- +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 XRDS doc is discovered via the user.aspx page. +--%> +<xrds:XRDS + xmlns:xrds="xri://$xrds" + xmlns:openid="http://openid.net/xmlns/1.0" + xmlns="xri://$xrd*($v*2.0)"> + <XRD> + <Service priority="10"> + <Type>http://specs.openid.net/auth/2.0/server</Type> + <Type>http://openid.net/extensions/sreg/1.1</Type> + <URI><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/server.aspx"))%></URI> + </Service> + </XRD> +</xrds:XRDS> diff --git a/samples/OpenIdProviderWebForms/server.aspx b/samples/OpenIdProviderWebForms/server.aspx new file mode 100644 index 0000000..10030a6 --- /dev/null +++ b/samples/OpenIdProviderWebForms/server.aspx @@ -0,0 +1,53 @@ +<%@ Page Language="C#" AutoEventWireup="true" Inherits="OpenIdProviderWebForms.server" CodeBehind="server.aspx.cs" ValidateRequest="false" %> + +<%@ Register Assembly="DotNetOpenAuth" Namespace="DotNetOpenAuth.OpenId.Provider" TagPrefix="openid" %> +<html> +<head> + <title>This is an OpenID server</title> +</head> +<body> + <form runat='server'> + <%-- This page provides an example of how to use the ProviderEndpoint control on an ASPX page + to host an OpenID Provider. Alternatively for greater performance an .ashx file can be used. + See Provider.ashx for an example. A typical web site will NOT use both .ashx and .aspx + provider endpoints. + This server.aspx page is the default provider endpoint to use. To switch to the .ashx handler, + change the user_xrds.aspx and op_xrds.aspx files to point to provider.ashx instead of server.aspx. + --%> + <openid:ProviderEndpoint runat="server" OnAuthenticationChallenge="provider_AuthenticationChallenge" /> + <p> + <asp:Label ID="serverEndpointUrl" runat="server" EnableViewState="false" /> + is an OpenID server endpoint. + </p> + <p> + For more information about OpenID, see: + </p> + <table> + <tr> + <td> + <a href="http://dotnetopenid.googlecode.com/">http://dotnetopenid.googlecode.com/</a> + </td> + <td> + Home of this library + </td> + </tr> + <tr> + <td> + <a href="http://www.openid.net/">http://www.openid.net/</a> + </td> + <td> + The official OpenID Web site + </td> + </tr> + <tr> + <td> + <a href="http://www.openidenabled.com/">http://www.openidenabled.com/</a> + </td> + <td> + An OpenID community Web site + </td> + </tr> + </table> + </form> +</body> +</html> diff --git a/samples/OpenIdProviderWebForms/server.aspx.cs b/samples/OpenIdProviderWebForms/server.aspx.cs new file mode 100644 index 0000000..c0af0b4 --- /dev/null +++ b/samples/OpenIdProviderWebForms/server.aspx.cs @@ -0,0 +1,18 @@ +namespace OpenIdProviderWebForms { + using System; + using DotNetOpenAuth.OpenId.Provider; + + /// <summary> + /// This is the primary page for this open-id provider. + /// This page is responsible for handling all open-id compliant requests. + /// </summary> + public partial class server : System.Web.UI.Page { + protected void Page_Load(object src, System.EventArgs evt) { + this.serverEndpointUrl.Text = Request.Url.ToString(); + } + + protected void provider_AuthenticationChallenge(object sender, AuthenticationChallengeEventArgs e) { + Code.Util.ProcessAuthenticationChallenge(e.Request); + } + } +}
\ No newline at end of file diff --git a/samples/OpenIdProviderWebForms/server.aspx.designer.cs b/samples/OpenIdProviderWebForms/server.aspx.designer.cs new file mode 100644 index 0000000..89c8c8a --- /dev/null +++ b/samples/OpenIdProviderWebForms/server.aspx.designer.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:2.0.50727.3521 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace OpenIdProviderWebForms { + + + public partial class server { + + /// <summary> + /// serverEndpointUrl control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.Label serverEndpointUrl; + } +} diff --git a/samples/OpenIdProviderWebForms/styles.css b/samples/OpenIdProviderWebForms/styles.css new file mode 100644 index 0000000..2e4d3db --- /dev/null +++ b/samples/OpenIdProviderWebForms/styles.css @@ -0,0 +1,10 @@ +h2 +{ + font-style: italic; +} + +body +{ + font-family: Cambria, Arial, Times New Roman; + font-size: 12pt; +}
\ No newline at end of file diff --git a/samples/OpenIdProviderWebForms/user.aspx b/samples/OpenIdProviderWebForms/user.aspx new file mode 100644 index 0000000..7306e79 --- /dev/null +++ b/samples/OpenIdProviderWebForms/user.aspx @@ -0,0 +1,17 @@ +<%@ Page Language="C#" AutoEventWireup="true" Inherits="OpenIdProviderWebForms.user" CodeBehind="user.aspx.cs" MasterPageFile="~/Site.Master" %> + +<%@ Register Assembly="DotNetOpenAuth" Namespace="DotNetOpenAuth.OpenId.Provider" TagPrefix="openid" %> +<asp:Content ID="Content2" runat="server" ContentPlaceHolderID="head"> + <openid:IdentityEndpoint ID="IdentityEndpoint20" runat="server" ProviderEndpointUrl="~/Server.aspx" + XrdsUrl="~/user_xrds.aspx" ProviderVersion="V20" + AutoNormalizeRequest="true" OnNormalizeUri="IdentityEndpoint20_NormalizeUri" /> + <!-- and for backward compatibility with OpenID 1.x RPs... --> + <openid:IdentityEndpoint ID="IdentityEndpoint11" runat="server" ProviderEndpointUrl="~/Server.aspx" + ProviderVersion="V11" /> +</asp:Content> +<asp:Content ID="Content1" runat="server" ContentPlaceHolderID="Main"> + <p> + OpenID identity page for + <asp:Label runat="server" ID="usernameLabel" EnableViewState="false" /> + </p> +</asp:Content>
\ No newline at end of file diff --git a/samples/OpenIdProviderWebForms/user.aspx.cs b/samples/OpenIdProviderWebForms/user.aspx.cs new file mode 100644 index 0000000..f530f15 --- /dev/null +++ b/samples/OpenIdProviderWebForms/user.aspx.cs @@ -0,0 +1,33 @@ +namespace OpenIdProviderWebForms { + using System; + using DotNetOpenAuth.OpenId.Provider; + + /// <summary> + /// This page is a required as part of the service discovery phase of the openid protocol (step 1). + /// </summary> + /// <remarks> + /// <para>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.</para> + /// <para>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.</para> + /// <para>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.</para> + /// </remarks> + public partial class user : System.Web.UI.Page { + protected void Page_Load(object sender, EventArgs e) { + this.usernameLabel.Text = Request.QueryString["username"]; + } + + protected void IdentityEndpoint20_NormalizeUri(object sender, IdentityEndpointNormalizationEventArgs e) { + // This sample Provider has a custom policy for normalizing URIs, which is that the whole + // path of the URI be lowercase except for the first letter of the username. + UriBuilder normalized = new UriBuilder(e.UserSuppliedIdentifier); + string username = Request.QueryString["username"].TrimEnd('/').ToLowerInvariant(); + username = username.Substring(0, 1).ToUpperInvariant() + username.Substring(1); + normalized.Path = "/user/" + username; + normalized.Scheme = "http"; // for a real Provider, this should be HTTPS if supported. + e.NormalizedIdentifier = normalized.Uri; + } + } +}
\ No newline at end of file diff --git a/samples/OpenIdProviderWebForms/user.aspx.designer.cs b/samples/OpenIdProviderWebForms/user.aspx.designer.cs new file mode 100644 index 0000000..ab7b4a1 --- /dev/null +++ b/samples/OpenIdProviderWebForms/user.aspx.designer.cs @@ -0,0 +1,43 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:2.0.50727.3521 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace OpenIdProviderWebForms { + + + public partial class user { + + /// <summary> + /// IdentityEndpoint20 control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::DotNetOpenAuth.OpenId.Provider.IdentityEndpoint IdentityEndpoint20; + + /// <summary> + /// IdentityEndpoint11 control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::DotNetOpenAuth.OpenId.Provider.IdentityEndpoint IdentityEndpoint11; + + /// <summary> + /// usernameLabel control. + /// </summary> + /// <remarks> + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// </remarks> + protected global::System.Web.UI.WebControls.Label usernameLabel; + } +} diff --git a/samples/OpenIdProviderWebForms/user_xrds.aspx b/samples/OpenIdProviderWebForms/user_xrds.aspx new file mode 100644 index 0000000..275e413 --- /dev/null +++ b/samples/OpenIdProviderWebForms/user_xrds.aspx @@ -0,0 +1,24 @@ +<%@ Page Language="C#" AutoEventWireup="true" ContentType="application/xrds+xml" %><?xml version="1.0" encoding="UTF-8"?> +<%-- +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 XRDS doc is discovered via the user.aspx page. +--%> +<xrds:XRDS + xmlns:xrds="xri://$xrds" + xmlns:openid="http://openid.net/xmlns/1.0" + xmlns="xri://$xrd*($v*2.0)"> + <XRD> + <Service priority="10"> + <Type>http://specs.openid.net/auth/2.0/signon</Type> + <Type>http://openid.net/extensions/sreg/1.1</Type> + <URI><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/server.aspx"))%></URI> + </Service> + <Service priority="20"> + <Type>http://openid.net/signon/1.0</Type> + <Type>http://openid.net/extensions/sreg/1.1</Type> + <URI><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/server.aspx"))%></URI> + </Service> + </XRD> +</xrds:XRDS> |