summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2009-11-03 12:52:08 -0800
committerAndrew Arnott <andrewarnott@gmail.com>2009-11-03 12:52:08 -0800
commit89b5c35ae19f81d8ead9109ea2c9d5871d419f8c (patch)
tree03b62282892ec270e04d8fb5bdaf3e1c10f83ef7
parentb13badacaeddc376c563889c472d64812cc8e8d3 (diff)
parentd85f1056a53bd1c32a223cefab946d339052911d (diff)
downloadDotNetOpenAuth-89b5c35ae19f81d8ead9109ea2c9d5871d419f8c.zip
DotNetOpenAuth-89b5c35ae19f81d8ead9109ea2c9d5871d419f8c.tar.gz
DotNetOpenAuth-89b5c35ae19f81d8ead9109ea2c9d5871d419f8c.tar.bz2
Merge branch 'v3.1' into v3.2
Conflicts: src/version.txt
-rw-r--r--samples/OpenIdOfflineProvider/HttpHost.cs15
-rw-r--r--samples/OpenIdProviderMvc/Code/ReadOnlyXmlMembershipProvider.cs2
-rw-r--r--samples/OpenIdProviderMvc/Models/User.cs4
-rw-r--r--samples/OpenIdProviderWebForms/Code/CustomStore.cs5
-rw-r--r--samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.Designer.cs6
-rw-r--r--samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xsd17
-rw-r--r--samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xss2
-rw-r--r--samples/OpenIdRelyingPartyWebForms/Code/CustomStore.cs5
-rw-r--r--samples/OpenIdRelyingPartyWebForms/Code/CustomStoreDataSet.xsd17
-rw-r--r--samples/OpenIdRelyingPartyWebForms/Code/CustomStoreDataSet.xss2
-rw-r--r--samples/OpenIdRelyingPartyWebForms/Code/CustomStoreDataSet1.Designer.cs6
-rw-r--r--src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj1
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/OutgoingWebResponseTests.cs36
-rw-r--r--src/DotNetOpenAuth.sln1
-rw-r--r--src/DotNetOpenAuth/InfoCard/InfoCardSelector.cs23
-rw-r--r--src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs11
-rw-r--r--src/DotNetOpenAuth/Messaging/IncomingWebResponse.cs2
-rw-r--r--src/DotNetOpenAuth/Messaging/OutgoingWebResponse.cs10
-rw-r--r--src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs21
-rw-r--r--src/DotNetOpenAuth/OAuth/WebConsumer.cs3
20 files changed, 136 insertions, 53 deletions
diff --git a/samples/OpenIdOfflineProvider/HttpHost.cs b/samples/OpenIdOfflineProvider/HttpHost.cs
index 390275a..a2558f4 100644
--- a/samples/OpenIdOfflineProvider/HttpHost.cs
+++ b/samples/OpenIdOfflineProvider/HttpHost.cs
@@ -121,14 +121,19 @@ namespace DotNetOpenAuth.OpenIdOfflineProvider {
private void ProcessRequests() {
Contract.Requires(this.listener != null);
- try {
- while (true) {
+ while (true) {
+ try {
HttpListenerContext context = this.listener.GetContext();
this.handler(context);
+ } catch (HttpListenerException ex) {
+ if (this.listener.IsListening) {
+ App.Logger.Error("Unexpected exception.", ex);
+ } else {
+ // the listener is probably being shut down
+ App.Logger.Warn("HTTP listener is closing down.", ex);
+ break;
+ }
}
- } catch (HttpListenerException ex) {
- // the listener is probably being shut down
- App.Logger.Warn("HTTP listener is closing down.", ex);
}
}
}
diff --git a/samples/OpenIdProviderMvc/Code/ReadOnlyXmlMembershipProvider.cs b/samples/OpenIdProviderMvc/Code/ReadOnlyXmlMembershipProvider.cs
index cc5a321..d66573f 100644
--- a/samples/OpenIdProviderMvc/Code/ReadOnlyXmlMembershipProvider.cs
+++ b/samples/OpenIdProviderMvc/Code/ReadOnlyXmlMembershipProvider.cs
@@ -237,6 +237,8 @@
}
internal string GetSalt(string userName) {
+ // This is just a sample with no database... a real web app MUST return
+ // a reasonable salt here and have that salt be persistent for each user.
this.ReadMembershipDataStore();
return this.users[userName].Email;
}
diff --git a/samples/OpenIdProviderMvc/Models/User.cs b/samples/OpenIdProviderMvc/Models/User.cs
index 443c004..198b8fa 100644
--- a/samples/OpenIdProviderMvc/Models/User.cs
+++ b/samples/OpenIdProviderMvc/Models/User.cs
@@ -8,10 +8,6 @@
using OpenIdProviderMvc.Code;
internal class User {
- internal static Uri PpidClaimedIdentifierBaseUri {
- get { return Util.GetAppPathRootedUri("anon?id="); }
- }
-
internal static Uri ClaimedIdentifierBaseUri {
get { return Util.GetAppPathRootedUri("user/"); }
}
diff --git a/samples/OpenIdProviderWebForms/Code/CustomStore.cs b/samples/OpenIdProviderWebForms/Code/CustomStore.cs
index d8181fe..7face0b 100644
--- a/samples/OpenIdProviderWebForms/Code/CustomStore.cs
+++ b/samples/OpenIdProviderWebForms/Code/CustomStore.cs
@@ -109,13 +109,14 @@ namespace OpenIdProviderWebForms.Code {
// at you in the result of a race condition somewhere in your web site UI code
// and display some message to have the user try to log in again, and possibly
// warn them about a replay attack.
+ timestamp = timestamp.ToLocalTime();
lock (this) {
- if (dataSet.Nonce.FindByCodeContext(nonce, context) != null) {
+ if (dataSet.Nonce.FindByIssuedCodeContext(timestamp, nonce, context) != null) {
return false;
}
TimeSpan maxMessageAge = DotNetOpenAuth.Configuration.DotNetOpenAuthSection.Configuration.Messaging.MaximumMessageLifetime;
- dataSet.Nonce.AddNonceRow(context, nonce, timestamp.ToLocalTime(), (timestamp + maxMessageAge).ToLocalTime());
+ dataSet.Nonce.AddNonceRow(context, nonce, timestamp, timestamp + maxMessageAge);
return true;
}
}
diff --git a/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.Designer.cs b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.Designer.cs
index d836261..813ff62 100644
--- a/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.Designer.cs
+++ b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
-// Runtime Version:2.0.50727.3521
+// Runtime Version:2.0.50727.4927
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -678,8 +678,9 @@ namespace OpenIdProviderWebForms.Code {
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public NonceRow FindByCodeContext(string Code, string Context) {
+ public NonceRow FindByIssuedCodeContext(System.DateTime Issued, string Code, string Context) {
return ((NonceRow)(this.Rows.Find(new object[] {
+ Issued,
Code,
Context})));
}
@@ -715,6 +716,7 @@ namespace OpenIdProviderWebForms.Code {
this.columnExpires = new global::System.Data.DataColumn("Expires", typeof(global::System.DateTime), null, global::System.Data.MappingType.Element);
base.Columns.Add(this.columnExpires);
this.Constraints.Add(new global::System.Data.UniqueConstraint("Constraint1", new global::System.Data.DataColumn[] {
+ this.columnIssued,
this.columnCode,
this.columnContext}, true));
this.columnContext.AllowDBNull = false;
diff --git a/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xsd b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xsd
index 295fe74..04a96eb 100644
--- a/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xsd
+++ b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xsd
@@ -15,20 +15,20 @@
<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:element name="DistinguishingFactor" msprop:Generator_UserColumnName="DistinguishingFactor" msprop:Generator_ColumnVarNameInTable="columnDistinguishingFactor" msprop:Generator_ColumnPropNameInRow="DistinguishingFactor" msprop:Generator_ColumnPropNameInTable="DistinguishingFactorColumn" type="xs:string" />
+ <xs:element name="Handle" msprop:Generator_UserColumnName="Handle" msprop:Generator_ColumnVarNameInTable="columnHandle" msprop:Generator_ColumnPropNameInRow="Handle" msprop:Generator_ColumnPropNameInTable="HandleColumn" type="xs:string" />
+ <xs:element name="Expires" msprop:Generator_UserColumnName="Expires" msprop:Generator_ColumnVarNameInTable="columnExpires" msprop:Generator_ColumnPropNameInRow="Expires" msprop:Generator_ColumnPropNameInTable="ExpiresColumn" type="xs:dateTime" />
+ <xs:element name="PrivateData" msprop:Generator_UserColumnName="PrivateData" msprop:Generator_ColumnVarNameInTable="columnPrivateData" msprop:Generator_ColumnPropNameInRow="PrivateData" msprop:Generator_ColumnPropNameInTable="PrivateDataColumn" type="xs:base64Binary" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Nonce" msprop:Generator_UserTableName="Nonce" msprop:Generator_RowDeletedName="NonceRowDeleted" msprop:Generator_RowChangedName="NonceRowChanged" msprop:Generator_RowClassName="NonceRow" msprop:Generator_RowChangingName="NonceRowChanging" msprop:Generator_RowEvArgName="NonceRowChangeEvent" msprop:Generator_RowEvHandlerName="NonceRowChangeEventHandler" msprop:Generator_TableClassName="NonceDataTable" msprop:Generator_TableVarName="tableNonce" msprop:Generator_RowDeletingName="NonceRowDeleting" msprop:Generator_TablePropName="Nonce">
<xs:complexType>
<xs:sequence>
- <xs:element name="Context" msprop:Generator_UserColumnName="Context" msprop:Generator_ColumnPropNameInRow="Context" msprop:Generator_ColumnVarNameInTable="columnContext" msprop:Generator_ColumnPropNameInTable="ContextColumn" type="xs:string" />
- <xs:element name="Code" msprop:Generator_UserColumnName="Code" msprop:Generator_ColumnVarNameInTable="columnCode" msprop:Generator_ColumnPropNameInRow="Code" msprop:Generator_ColumnPropNameInTable="CodeColumn" type="xs:string" />
- <xs:element name="Issued" msprop:Generator_UserColumnName="Issued" msprop:Generator_ColumnVarNameInTable="columnIssued" msprop:Generator_ColumnPropNameInRow="Issued" msprop:Generator_ColumnPropNameInTable="IssuedColumn" type="xs:dateTime" />
- <xs:element name="Expires" msprop:Generator_UserColumnName="Expires" msprop:Generator_ColumnVarNameInTable="columnExpires" msprop:Generator_ColumnPropNameInRow="Expires" msprop:Generator_ColumnPropNameInTable="ExpiresColumn" type="xs:dateTime" />
+ <xs:element name="Context" msprop:Generator_UserColumnName="Context" msprop:Generator_ColumnVarNameInTable="columnContext" msprop:Generator_ColumnPropNameInRow="Context" msprop:Generator_ColumnPropNameInTable="ContextColumn" type="xs:string" />
+ <xs:element name="Code" msprop:Generator_UserColumnName="Code" msprop:Generator_ColumnPropNameInRow="Code" msprop:Generator_ColumnVarNameInTable="columnCode" msprop:Generator_ColumnPropNameInTable="CodeColumn" type="xs:string" />
+ <xs:element name="Issued" msprop:Generator_UserColumnName="Issued" msprop:Generator_ColumnPropNameInRow="Issued" msprop:Generator_ColumnVarNameInTable="columnIssued" msprop:Generator_ColumnPropNameInTable="IssuedColumn" type="xs:dateTime" />
+ <xs:element name="Expires" msprop:Generator_UserColumnName="Expires" msprop:Generator_ColumnPropNameInRow="Expires" msprop:Generator_ColumnVarNameInTable="columnExpires" msprop:Generator_ColumnPropNameInTable="ExpiresColumn" type="xs:dateTime" />
</xs:sequence>
</xs:complexType>
</xs:element>
@@ -41,6 +41,7 @@
</xs:unique>
<xs:unique name="Constraint1" msdata:PrimaryKey="true">
<xs:selector xpath=".//mstns:Nonce" />
+ <xs:field xpath="mstns:Issued" />
<xs:field xpath="mstns:Code" />
<xs:field xpath="mstns:Context" />
</xs:unique>
diff --git a/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xss b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xss
index ede3b42..b19f728 100644
--- a/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xss
+++ b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xss
@@ -7,7 +7,7 @@
<DiagramLayout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ex:showrelationlabel="False" ViewPortX="-10" ViewPortY="-10" xmlns:ex="urn:schemas-microsoft-com:xml-msdatasource-layout-extended" xmlns="urn:schemas-microsoft-com:xml-msdatasource-layout">
<Shapes>
<Shape ID="DesignTable:Association" ZOrder="2" X="349" Y="83" Height="105" Width="154" AdapterExpanded="true" DataTableExpanded="true" OldAdapterHeight="0" OldDataTableHeight="0" SplitterPosition="101" />
- <Shape ID="DesignTable:Nonce" ZOrder="1" X="567" Y="77" Height="86" Width="150" AdapterExpanded="true" DataTableExpanded="true" OldAdapterHeight="0" OldDataTableHeight="0" SplitterPosition="86" />
+ <Shape ID="DesignTable:Nonce" ZOrder="1" X="567" Y="77" Height="125" Width="150" AdapterExpanded="true" DataTableExpanded="true" OldAdapterHeight="0" OldDataTableHeight="0" SplitterPosition="121" />
</Shapes>
<Connectors />
</DiagramLayout> \ No newline at end of file
diff --git a/samples/OpenIdRelyingPartyWebForms/Code/CustomStore.cs b/samples/OpenIdRelyingPartyWebForms/Code/CustomStore.cs
index 2363aec..07f209b 100644
--- a/samples/OpenIdRelyingPartyWebForms/Code/CustomStore.cs
+++ b/samples/OpenIdRelyingPartyWebForms/Code/CustomStore.cs
@@ -64,13 +64,14 @@
// at you in the result of a race condition somewhere in your web site UI code
// and display some message to have the user try to log in again, and possibly
// warn them about a replay attack.
+ timestamp = timestamp.ToLocalTime();
lock (this) {
- if (dataSet.Nonce.FindByCodeContext(nonce, context) != null) {
+ if (dataSet.Nonce.FindByIssuedCodeContext(timestamp, nonce, context) != null) {
return false;
}
TimeSpan maxMessageAge = DotNetOpenAuth.Configuration.DotNetOpenAuthSection.Configuration.Messaging.MaximumMessageLifetime;
- dataSet.Nonce.AddNonceRow(context, nonce, timestamp.ToLocalTime(), (timestamp + maxMessageAge).ToLocalTime());
+ dataSet.Nonce.AddNonceRow(context, nonce, timestamp, timestamp + maxMessageAge);
return true;
}
}
diff --git a/samples/OpenIdRelyingPartyWebForms/Code/CustomStoreDataSet.xsd b/samples/OpenIdRelyingPartyWebForms/Code/CustomStoreDataSet.xsd
index b80310e..fa161fd 100644
--- a/samples/OpenIdRelyingPartyWebForms/Code/CustomStoreDataSet.xsd
+++ b/samples/OpenIdRelyingPartyWebForms/Code/CustomStoreDataSet.xsd
@@ -15,20 +15,20 @@
<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_ColumnVarNameInTable="columnDistinguishingFactor" msprop:Generator_ColumnPropNameInRow="DistinguishingFactor" msprop:Generator_ColumnPropNameInTable="DistinguishingFactorColumn" type="xs:string" />
- <xs:element name="Handle" msprop:Generator_UserColumnName="Handle" msprop:Generator_ColumnVarNameInTable="columnHandle" msprop:Generator_ColumnPropNameInRow="Handle" msprop:Generator_ColumnPropNameInTable="HandleColumn" type="xs:string" />
- <xs:element name="Expires" msprop:Generator_UserColumnName="Expires" msprop:Generator_ColumnVarNameInTable="columnExpires" msprop:Generator_ColumnPropNameInRow="Expires" msprop:Generator_ColumnPropNameInTable="ExpiresColumn" type="xs:dateTime" />
- <xs:element name="PrivateData" msprop:Generator_UserColumnName="PrivateData" msprop:Generator_ColumnVarNameInTable="columnPrivateData" msprop:Generator_ColumnPropNameInRow="PrivateData" msprop:Generator_ColumnPropNameInTable="PrivateDataColumn" type="xs:base64Binary" />
+ <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:element name="Nonce" msprop:Generator_UserTableName="Nonce" msprop:Generator_RowDeletedName="NonceRowDeleted" msprop:Generator_RowChangedName="NonceRowChanged" msprop:Generator_RowClassName="NonceRow" msprop:Generator_RowChangingName="NonceRowChanging" msprop:Generator_RowEvArgName="NonceRowChangeEvent" msprop:Generator_RowEvHandlerName="NonceRowChangeEventHandler" msprop:Generator_TableClassName="NonceDataTable" msprop:Generator_TableVarName="tableNonce" msprop:Generator_RowDeletingName="NonceRowDeleting" msprop:Generator_TablePropName="Nonce">
<xs:complexType>
<xs:sequence>
- <xs:element name="Context" msprop:Generator_UserColumnName="Context" msprop:Generator_ColumnPropNameInRow="Context" msprop:Generator_ColumnVarNameInTable="columnContext" msprop:Generator_ColumnPropNameInTable="ContextColumn" type="xs:string" />
- <xs:element name="Code" msprop:Generator_UserColumnName="Code" msprop:Generator_ColumnPropNameInRow="Code" msprop:Generator_ColumnVarNameInTable="columnCode" msprop:Generator_ColumnPropNameInTable="CodeColumn" type="xs:string" />
- <xs:element name="Issued" msprop:Generator_UserColumnName="Issued" msprop:Generator_ColumnPropNameInRow="Issued" msprop:Generator_ColumnVarNameInTable="columnIssued" msprop:Generator_ColumnPropNameInTable="IssuedColumn" type="xs:dateTime" />
- <xs:element name="Expires" msprop:Generator_UserColumnName="Expires" msprop:Generator_ColumnVarNameInTable="columnExpires" msprop:Generator_ColumnPropNameInRow="Expires" msprop:Generator_ColumnPropNameInTable="ExpiresColumn" type="xs:dateTime" />
+ <xs:element name="Context" msprop:Generator_UserColumnName="Context" msprop:Generator_ColumnVarNameInTable="columnContext" msprop:Generator_ColumnPropNameInRow="Context" msprop:Generator_ColumnPropNameInTable="ContextColumn" type="xs:string" />
+ <xs:element name="Code" msprop:Generator_UserColumnName="Code" msprop:Generator_ColumnVarNameInTable="columnCode" msprop:Generator_ColumnPropNameInRow="Code" msprop:Generator_ColumnPropNameInTable="CodeColumn" type="xs:string" />
+ <xs:element name="Issued" msprop:Generator_UserColumnName="Issued" msprop:Generator_ColumnVarNameInTable="columnIssued" msprop:Generator_ColumnPropNameInRow="Issued" msprop:Generator_ColumnPropNameInTable="IssuedColumn" type="xs:dateTime" />
+ <xs:element name="Expires" msprop:Generator_UserColumnName="Expires" msprop:Generator_ColumnPropNameInRow="Expires" msprop:Generator_ColumnVarNameInTable="columnExpires" msprop:Generator_ColumnPropNameInTable="ExpiresColumn" type="xs:dateTime" />
</xs:sequence>
</xs:complexType>
</xs:element>
@@ -41,6 +41,7 @@
</xs:unique>
<xs:unique name="Constraint1" msdata:PrimaryKey="true">
<xs:selector xpath=".//mstns:Nonce" />
+ <xs:field xpath="mstns:Issued" />
<xs:field xpath="mstns:Code" />
<xs:field xpath="mstns:Context" />
</xs:unique>
diff --git a/samples/OpenIdRelyingPartyWebForms/Code/CustomStoreDataSet.xss b/samples/OpenIdRelyingPartyWebForms/Code/CustomStoreDataSet.xss
index 483a137..ab8f226 100644
--- a/samples/OpenIdRelyingPartyWebForms/Code/CustomStoreDataSet.xss
+++ b/samples/OpenIdRelyingPartyWebForms/Code/CustomStoreDataSet.xss
@@ -7,7 +7,7 @@
<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="2" X="349" Y="83" Height="105" Width="154" AdapterExpanded="true" DataTableExpanded="true" OldAdapterHeight="0" OldDataTableHeight="0" SplitterPosition="101" />
- <Shape ID="DesignTable:Nonce" ZOrder="1" X="604" Y="86" Height="86" Width="150" AdapterExpanded="true" DataTableExpanded="true" OldAdapterHeight="0" OldDataTableHeight="0" SplitterPosition="82" />
+ <Shape ID="DesignTable:Nonce" ZOrder="1" X="604" Y="86" Height="125" Width="150" AdapterExpanded="true" DataTableExpanded="true" OldAdapterHeight="0" OldDataTableHeight="0" SplitterPosition="121" />
</Shapes>
<Connectors />
</DiagramLayout> \ No newline at end of file
diff --git a/samples/OpenIdRelyingPartyWebForms/Code/CustomStoreDataSet1.Designer.cs b/samples/OpenIdRelyingPartyWebForms/Code/CustomStoreDataSet1.Designer.cs
index 580b1fa..0c0e194 100644
--- a/samples/OpenIdRelyingPartyWebForms/Code/CustomStoreDataSet1.Designer.cs
+++ b/samples/OpenIdRelyingPartyWebForms/Code/CustomStoreDataSet1.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
-// Runtime Version:2.0.50727.4912
+// Runtime Version:2.0.50727.4927
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -678,8 +678,9 @@ namespace OpenIdRelyingPartyWebForms.Code {
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public NonceRow FindByCodeContext(string Code, string Context) {
+ public NonceRow FindByIssuedCodeContext(System.DateTime Issued, string Code, string Context) {
return ((NonceRow)(this.Rows.Find(new object[] {
+ Issued,
Code,
Context})));
}
@@ -715,6 +716,7 @@ namespace OpenIdRelyingPartyWebForms.Code {
this.columnExpires = new global::System.Data.DataColumn("Expires", typeof(global::System.DateTime), null, global::System.Data.MappingType.Element);
base.Columns.Add(this.columnExpires);
this.Constraints.Add(new global::System.Data.UniqueConstraint("Constraint1", new global::System.Data.DataColumn[] {
+ this.columnIssued,
this.columnCode,
this.columnContext}, true));
this.columnContext.AllowDBNull = false;
diff --git a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
index bd317af..7212008 100644
--- a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
+++ b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
@@ -135,6 +135,7 @@
<Compile Include="Messaging\EnumerableCacheTests.cs" />
<Compile Include="Messaging\ErrorUtilitiesTests.cs" />
<Compile Include="Messaging\MessageSerializerTests.cs" />
+ <Compile Include="Messaging\OutgoingWebResponseTests.cs" />
<Compile Include="Messaging\Reflection\MessageDescriptionTests.cs" />
<Compile Include="Messaging\Reflection\MessageDictionaryTests.cs" />
<Compile Include="Messaging\MessagingTestBase.cs" />
diff --git a/src/DotNetOpenAuth.Test/Messaging/OutgoingWebResponseTests.cs b/src/DotNetOpenAuth.Test/Messaging/OutgoingWebResponseTests.cs
new file mode 100644
index 0000000..35f9259
--- /dev/null
+++ b/src/DotNetOpenAuth.Test/Messaging/OutgoingWebResponseTests.cs
@@ -0,0 +1,36 @@
+//-----------------------------------------------------------------------
+// <copyright file="OutgoingWebResponseTests.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Test.Messaging {
+ using System.Net;
+ using System.Text;
+ using DotNetOpenAuth.Messaging;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ [TestClass]
+ public class OutgoingWebResponseTests {
+ /// <summary>
+ /// Verifies that setting the Body property correctly converts to a byte stream.
+ /// </summary>
+ [TestMethod]
+ public void SetBodyToByteStream() {
+ var response = new OutgoingWebResponse();
+ string stringValue = "abc";
+ response.Body = stringValue;
+ Assert.AreEqual(stringValue.Length, response.ResponseStream.Length);
+
+ // Verify that the actual bytes are correct.
+ Encoding encoding = new UTF8Encoding(false); // avoid emitting a byte-order mark
+ var expectedBuffer = encoding.GetBytes(stringValue);
+ var actualBuffer = new byte[stringValue.Length];
+ Assert.AreEqual(stringValue.Length, response.ResponseStream.Read(actualBuffer, 0, stringValue.Length));
+ CollectionAssert.AreEqual(expectedBuffer, actualBuffer);
+
+ // Verify that the header was set correctly.
+ Assert.AreEqual(encoding.HeaderName, response.Headers[HttpResponseHeader.ContentEncoding]);
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.sln b/src/DotNetOpenAuth.sln
index f8d9b8f..e6aff81 100644
--- a/src/DotNetOpenAuth.sln
+++ b/src/DotNetOpenAuth.sln
@@ -8,6 +8,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{20B5E173-C3C4-49F8-BD25-E69044075B4D}"
ProjectSection(SolutionItems) = preProject
DotNetOpenAuth.vsmdi = DotNetOpenAuth.vsmdi
+ ..\LICENSE.txt = ..\LICENSE.txt
LocalTestRun.testrunconfig = LocalTestRun.testrunconfig
..\doc\README.Bin.html = ..\doc\README.Bin.html
..\doc\README.html = ..\doc\README.html
diff --git a/src/DotNetOpenAuth/InfoCard/InfoCardSelector.cs b/src/DotNetOpenAuth/InfoCard/InfoCardSelector.cs
index 21911fa..fe2c2a2 100644
--- a/src/DotNetOpenAuth/InfoCard/InfoCardSelector.cs
+++ b/src/DotNetOpenAuth/InfoCard/InfoCardSelector.cs
@@ -5,7 +5,7 @@
// </copyright>
//-----------------------------------------------------------------------
-[assembly: System.Web.UI.WebResource("DotNetOpenAuth.InfoCard.SupportingScript.js", "text/javascript")]
+[assembly: System.Web.UI.WebResource(DotNetOpenAuth.InfoCard.InfoCardSelector.ScriptResourceName, "text/javascript")]
namespace DotNetOpenAuth.InfoCard {
using System;
@@ -48,6 +48,11 @@ namespace DotNetOpenAuth.InfoCard {
[ToolboxData("<{0}:InfoCardSelector runat=\"server\"><ClaimsRequested><{0}:ClaimType Name=\"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier\" /></ClaimsRequested><UnsupportedTemplate><p>Your browser does not support Information Cards.</p></UnsupportedTemplate></{0}:InfoCardSelector>")]
[ContractVerification(true)]
public class InfoCardSelector : CompositeControl, IPostBackEventHandler {
+ /// <summary>
+ /// The resource name for getting at the SupportingScript.js embedded manifest stream.
+ /// </summary>
+ internal const string ScriptResourceName = "DotNetOpenAuth.InfoCard.SupportingScript.js";
+
#region Property constants
/// <summary>
@@ -172,11 +177,6 @@ namespace DotNetOpenAuth.InfoCard {
#endregion
/// <summary>
- /// The resource name for getting at the SupportingScript.js embedded manifest stream.
- /// </summary>
- private const string ScriptResourceName = "DotNetOpenAuth.InfoCard.SupportingScript.js";
-
- /// <summary>
/// The panel containing the controls to display if InfoCard is supported in the user agent.
/// </summary>
private Panel infoCardSupportedPanel;
@@ -413,7 +413,16 @@ namespace DotNetOpenAuth.InfoCard {
/// When implemented by a class, enables a server control to process an event raised when a form is posted to the server.
/// </summary>
/// <param name="eventArgument">A <see cref="T:System.String"/> that represents an optional event argument to be passed to the event handler.</param>
- public void RaisePostBackEvent(string eventArgument) {
+ void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) {
+ this.RaisePostBackEvent(eventArgument);
+ }
+
+ /// <summary>
+ /// When implemented by a class, enables a server control to process an event raised when a form is posted to the server.
+ /// </summary>
+ /// <param name="eventArgument">A <see cref="T:System.String"/> that represents an optional event argument to be passed to the event handler.</param>
+ [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "Predefined signature.")]
+ protected virtual void RaisePostBackEvent(string eventArgument) {
if (!string.IsNullOrEmpty(this.TokenXml)) {
try {
ReceivingTokenEventArgs receivingArgs = this.OnReceivingToken(this.TokenXml);
diff --git a/src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs b/src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs
index 14666f2..0693926 100644
--- a/src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs
+++ b/src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs
@@ -366,7 +366,16 @@ namespace DotNetOpenAuth.Messaging {
WebHeaderCollection headers = new WebHeaderCollection();
foreach (string key in pairs) {
- headers.Add(key, pairs[key]);
+ try {
+ headers.Add(key, pairs[key]);
+ } catch (ArgumentException ex) {
+ Logger.Messaging.WarnFormat(
+ "{0} thrown when trying to add web header \"{1}: {2}\". {3}",
+ ex.GetType().Name,
+ key,
+ pairs[key],
+ ex.Message);
+ }
}
return headers;
diff --git a/src/DotNetOpenAuth/Messaging/IncomingWebResponse.cs b/src/DotNetOpenAuth/Messaging/IncomingWebResponse.cs
index dee81dc..e471a06 100644
--- a/src/DotNetOpenAuth/Messaging/IncomingWebResponse.cs
+++ b/src/DotNetOpenAuth/Messaging/IncomingWebResponse.cs
@@ -101,7 +101,7 @@ namespace DotNetOpenAuth.Messaging {
/// This can be different from the <see cref="RequestUri"/> in cases of
/// redirection during the request.
/// </remarks>
- public Uri FinalUri { get; private set; }
+ public Uri FinalUri { get; internal set; }
/// <summary>
/// Gets the headers that must be included in the response to the user agent.
diff --git a/src/DotNetOpenAuth/Messaging/OutgoingWebResponse.cs b/src/DotNetOpenAuth/Messaging/OutgoingWebResponse.cs
index bad582c..147cd66 100644
--- a/src/DotNetOpenAuth/Messaging/OutgoingWebResponse.cs
+++ b/src/DotNetOpenAuth/Messaging/OutgoingWebResponse.cs
@@ -30,6 +30,11 @@ namespace DotNetOpenAuth.Messaging {
/// </remarks>
public class OutgoingWebResponse {
/// <summary>
+ /// The encoder to use for serializing the response body.
+ /// </summary>
+ private static Encoding bodyStringEncoder = new UTF8Encoding(false);
+
+ /// <summary>
/// Initializes a new instance of the <see cref="OutgoingWebResponse"/> class.
/// </summary>
internal OutgoingWebResponse() {
@@ -210,10 +215,9 @@ namespace DotNetOpenAuth.Messaging {
return;
}
- Encoding encoding = Encoding.UTF8;
- this.Headers[HttpResponseHeader.ContentEncoding] = encoding.HeaderName;
+ this.Headers[HttpResponseHeader.ContentEncoding] = bodyStringEncoder.HeaderName;
this.ResponseStream = new MemoryStream();
- StreamWriter writer = new StreamWriter(this.ResponseStream, encoding);
+ StreamWriter writer = new StreamWriter(this.ResponseStream, bodyStringEncoder);
writer.Write(body);
writer.Flush();
this.ResponseStream.Seek(0, SeekOrigin.Begin);
diff --git a/src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs b/src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs
index 733b698..1656155 100644
--- a/src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs
+++ b/src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs
@@ -259,6 +259,15 @@ namespace DotNetOpenAuth.Messaging {
Uri redirectUri = new Uri(response.FinalUri, response.Headers[HttpResponseHeader.Location]);
request = request.Clone(redirectUri);
} else {
+ if (response.FinalUri != request.RequestUri) {
+ // Since we don't automatically follow redirects, there's only one scenario where this
+ // can happen: when the server sends a (non-redirecting) Content-Location header in the response.
+ // It's imperative that we do not trust that header though, so coerce the FinalUri to be
+ // what we just requested.
+ Logger.Http.WarnFormat("The response from {0} included an HTTP header indicating it's the same as {1}, but it's not a redirect so we won't trust that.", request.RequestUri, response.FinalUri);
+ response.FinalUri = request.RequestUri;
+ }
+
return response;
}
}
@@ -455,12 +464,14 @@ namespace DotNetOpenAuth.Messaging {
request.ReadWriteTimeout = (int)this.ReadWriteTimeout.TotalMilliseconds;
request.Timeout = (int)this.Timeout.TotalMilliseconds;
request.KeepAlive = false;
-
- // If SSL is required throughout, we cannot allow auto redirects because
- // it may include a pass through an unprotected HTTP request.
- // We have to follow redirects manually.
- request.AllowAutoRedirect = false;
}
+
+ // If SSL is required throughout, we cannot allow auto redirects because
+ // it may include a pass through an unprotected HTTP request.
+ // We have to follow redirects manually.
+ // It also allows us to ignore HttpWebResponse.FinalUri since that can be affected by
+ // the Content-Location header and open security holes.
+ request.AllowAutoRedirect = false;
}
}
}
diff --git a/src/DotNetOpenAuth/OAuth/WebConsumer.cs b/src/DotNetOpenAuth/OAuth/WebConsumer.cs
index 56d3029..d86444d 100644
--- a/src/DotNetOpenAuth/OAuth/WebConsumer.cs
+++ b/src/DotNetOpenAuth/OAuth/WebConsumer.cs
@@ -120,7 +120,8 @@ namespace DotNetOpenAuth.OAuth {
}
// Prepare a message to exchange the request token for an access token.
- var requestAccess = new AuthorizedTokenRequest(this.ServiceProvider.AccessTokenEndpoint, this.ServiceProvider.Version) {
+ // We are careful to use a v1.0 message version so that the oauth_verifier is not required.
+ var requestAccess = new AuthorizedTokenRequest(this.ServiceProvider.AccessTokenEndpoint, Protocol.V10.Version) {
RequestToken = positiveAuthorization.RequestToken,
ConsumerKey = this.ConsumerKey,
};