summaryrefslogtreecommitdiffstats
path: root/samples/OAuthAuthorizationServer/Code
diff options
context:
space:
mode:
Diffstat (limited to 'samples/OAuthAuthorizationServer/Code')
-rw-r--r--samples/OAuthAuthorizationServer/Code/DataClasses.dbml8
-rw-r--r--samples/OAuthAuthorizationServer/Code/DataClasses.dbml.layout6
-rw-r--r--samples/OAuthAuthorizationServer/Code/DataClasses.designer.cs147
-rw-r--r--samples/OAuthAuthorizationServer/Code/DatabaseKeyNonceStore.cs (renamed from samples/OAuthAuthorizationServer/Code/DatabaseNonceStore.cs)46
-rw-r--r--samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs35
-rw-r--r--samples/OAuthAuthorizationServer/Code/Utilities.cs21
6 files changed, 233 insertions, 30 deletions
diff --git a/samples/OAuthAuthorizationServer/Code/DataClasses.dbml b/samples/OAuthAuthorizationServer/Code/DataClasses.dbml
index 33e6eda..0ef987d 100644
--- a/samples/OAuthAuthorizationServer/Code/DataClasses.dbml
+++ b/samples/OAuthAuthorizationServer/Code/DataClasses.dbml
@@ -37,4 +37,12 @@
<Column Name="Timestamp" Type="System.DateTime" IsPrimaryKey="true" CanBeNull="false" />
</Type>
</Table>
+ <Table Name="" Member="SymmetricCryptoKeys">
+ <Type Name="SymmetricCryptoKey">
+ <Column Name="Bucket" Type="System.String" IsPrimaryKey="true" CanBeNull="false" UpdateCheck="Never" />
+ <Column Name="Handle" Type="System.String" IsPrimaryKey="true" CanBeNull="false" UpdateCheck="Never" />
+ <Column Name="ExpiresUtc" Type="System.DateTime" CanBeNull="false" UpdateCheck="Never" />
+ <Column Name="Secret" Type="System.Byte[]" CanBeNull="false" UpdateCheck="Never" />
+ </Type>
+ </Table>
</Database> \ No newline at end of file
diff --git a/samples/OAuthAuthorizationServer/Code/DataClasses.dbml.layout b/samples/OAuthAuthorizationServer/Code/DataClasses.dbml.layout
index e2982ce..f4de725 100644
--- a/samples/OAuthAuthorizationServer/Code/DataClasses.dbml.layout
+++ b/samples/OAuthAuthorizationServer/Code/DataClasses.dbml.layout
@@ -40,5 +40,11 @@
<classShapeMoniker Id="895ebbc8-8352-4c04-9e53-b8e6c8302d36" />
</nodes>
</associationConnector>
+ <classShape Id="93df6fa9-cc66-44a9-8885-960b1e670dd7" absoluteBounds="4.125, 6.25, 2, 1.5785953776041666">
+ <DataClassMoniker Name="/DataClassesDataContext/SymmetricCryptoKey" />
+ <nestedChildShapes>
+ <elementListCompartment Id="0b486eb8-31a4-4f11-b58f-09540c56319b" absoluteBounds="4.14, 6.71, 1.9700000000000002, 1.0185953776041665" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+ </nestedChildShapes>
+ </classShape>
</nestedChildShapes>
</ordesignerObjectsDiagram> \ No newline at end of file
diff --git a/samples/OAuthAuthorizationServer/Code/DataClasses.designer.cs b/samples/OAuthAuthorizationServer/Code/DataClasses.designer.cs
index b6d070d..c8d1b19 100644
--- a/samples/OAuthAuthorizationServer/Code/DataClasses.designer.cs
+++ b/samples/OAuthAuthorizationServer/Code/DataClasses.designer.cs
@@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
-// Runtime Version:4.0.30319.1
+// Runtime Version:4.0.30319.225
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -42,6 +42,9 @@ namespace OAuthAuthorizationServer.Code
partial void InsertNonce(Nonce instance);
partial void UpdateNonce(Nonce instance);
partial void DeleteNonce(Nonce instance);
+ partial void InsertSymmetricCryptoKey(SymmetricCryptoKey instance);
+ partial void UpdateSymmetricCryptoKey(SymmetricCryptoKey instance);
+ partial void DeleteSymmetricCryptoKey(SymmetricCryptoKey instance);
#endregion
public DataClassesDataContext() :
@@ -105,6 +108,14 @@ namespace OAuthAuthorizationServer.Code
return this.GetTable<Nonce>();
}
}
+
+ public System.Data.Linq.Table<SymmetricCryptoKey> SymmetricCryptoKeys
+ {
+ get
+ {
+ return this.GetTable<SymmetricCryptoKey>();
+ }
+ }
}
[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[User]")]
@@ -804,5 +815,139 @@ namespace OAuthAuthorizationServer.Code
}
}
}
+
+ [global::System.Data.Linq.Mapping.TableAttribute(Name="")]
+ public partial class SymmetricCryptoKey : INotifyPropertyChanging, INotifyPropertyChanged
+ {
+
+ private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+
+ private string _Bucket;
+
+ private string _Handle;
+
+ private System.DateTime _ExpiresUtc;
+
+ private byte[] _Secret;
+
+ #region Extensibility Method Definitions
+ partial void OnLoaded();
+ partial void OnValidate(System.Data.Linq.ChangeAction action);
+ partial void OnCreated();
+ partial void OnBucketChanging(string value);
+ partial void OnBucketChanged();
+ partial void OnHandleChanging(string value);
+ partial void OnHandleChanged();
+ partial void OnExpiresUtcChanging(System.DateTime value);
+ partial void OnExpiresUtcChanged();
+ partial void OnSecretChanging(byte[] value);
+ partial void OnSecretChanged();
+ #endregion
+
+ public SymmetricCryptoKey()
+ {
+ OnCreated();
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Bucket", CanBeNull=false, IsPrimaryKey=true, UpdateCheck=UpdateCheck.Never)]
+ public string Bucket
+ {
+ get
+ {
+ return this._Bucket;
+ }
+ set
+ {
+ if ((this._Bucket != value))
+ {
+ this.OnBucketChanging(value);
+ this.SendPropertyChanging();
+ this._Bucket = value;
+ this.SendPropertyChanged("Bucket");
+ this.OnBucketChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Handle", CanBeNull=false, IsPrimaryKey=true, UpdateCheck=UpdateCheck.Never)]
+ public string Handle
+ {
+ get
+ {
+ return this._Handle;
+ }
+ set
+ {
+ if ((this._Handle != value))
+ {
+ this.OnHandleChanging(value);
+ this.SendPropertyChanging();
+ this._Handle = value;
+ this.SendPropertyChanged("Handle");
+ this.OnHandleChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ExpiresUtc", UpdateCheck=UpdateCheck.Never)]
+ public System.DateTime ExpiresUtc
+ {
+ get
+ {
+ return this._ExpiresUtc;
+ }
+ set
+ {
+ if ((this._ExpiresUtc != value))
+ {
+ this.OnExpiresUtcChanging(value);
+ this.SendPropertyChanging();
+ this._ExpiresUtc = value;
+ this.SendPropertyChanged("ExpiresUtc");
+ this.OnExpiresUtcChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Secret", CanBeNull=false, UpdateCheck=UpdateCheck.Never)]
+ public byte[] Secret
+ {
+ get
+ {
+ return this._Secret;
+ }
+ set
+ {
+ if ((this._Secret != value))
+ {
+ this.OnSecretChanging(value);
+ this.SendPropertyChanging();
+ this._Secret = value;
+ this.SendPropertyChanged("Secret");
+ this.OnSecretChanged();
+ }
+ }
+ }
+
+ public event PropertyChangingEventHandler PropertyChanging;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void SendPropertyChanging()
+ {
+ if ((this.PropertyChanging != null))
+ {
+ this.PropertyChanging(this, emptyChangingEventArgs);
+ }
+ }
+
+ protected virtual void SendPropertyChanged(String propertyName)
+ {
+ if ((this.PropertyChanged != null))
+ {
+ this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+ }
}
#pragma warning restore 1591
diff --git a/samples/OAuthAuthorizationServer/Code/DatabaseNonceStore.cs b/samples/OAuthAuthorizationServer/Code/DatabaseKeyNonceStore.cs
index a0ce19e..765696e 100644
--- a/samples/OAuthAuthorizationServer/Code/DatabaseNonceStore.cs
+++ b/samples/OAuthAuthorizationServer/Code/DatabaseKeyNonceStore.cs
@@ -1,16 +1,18 @@
namespace OAuthAuthorizationServer.Code {
using System;
+ using System.Collections.Generic;
using System.Data.SqlClient;
+ using System.Linq;
using DotNetOpenAuth.Messaging.Bindings;
/// <summary>
/// A database-persisted nonce store.
/// </summary>
- public class DatabaseNonceStore : INonceStore {
+ public class DatabaseKeyNonceStore : INonceStore, ICryptoKeyStore {
/// <summary>
- /// Initializes a new instance of the <see cref="DatabaseNonceStore"/> class.
+ /// Initializes a new instance of the <see cref="DatabaseKeyNonceStore"/> class.
/// </summary>
- public DatabaseNonceStore() {
+ public DatabaseKeyNonceStore() {
}
#region INonceStore Members
@@ -51,5 +53,43 @@
}
#endregion
+
+ #region ICryptoKeyStore Members
+
+ public CryptoKey GetKey(string bucket, string handle) {
+ // It is critical that this lookup be case-sensitive, which can only be configured at the database.
+ var matches = from key in MvcApplication.DataContext.SymmetricCryptoKeys
+ where key.Bucket == bucket && key.Handle == handle
+ select new CryptoKey(key.Secret, key.ExpiresUtc.AsUtc());
+
+ return matches.FirstOrDefault();
+ }
+
+ public IEnumerable<KeyValuePair<string, CryptoKey>> GetKeys(string bucket) {
+ return from key in MvcApplication.DataContext.SymmetricCryptoKeys
+ orderby key.ExpiresUtc descending
+ select new KeyValuePair<string, CryptoKey>(key.Handle, new CryptoKey(key.Secret, key.ExpiresUtc.AsUtc()));
+ }
+
+ public void StoreKey(string bucket, string handle, CryptoKey key) {
+ var keyRow = new SymmetricCryptoKey() {
+ Bucket = bucket,
+ Handle = handle,
+ Secret = key.Key,
+ ExpiresUtc = key.ExpiresUtc,
+ };
+
+ MvcApplication.DataContext.SymmetricCryptoKeys.InsertOnSubmit(keyRow);
+ MvcApplication.DataContext.SubmitChanges();
+ }
+
+ public void RemoveKey(string bucket, string handle) {
+ var match = MvcApplication.DataContext.SymmetricCryptoKeys.FirstOrDefault(k => k.Bucket == bucket && k.Handle == handle);
+ if (match != null) {
+ MvcApplication.DataContext.SymmetricCryptoKeys.DeleteOnSubmit(match);
+ }
+ }
+
+ #endregion
}
} \ No newline at end of file
diff --git a/samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs b/samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs
index 3be70f0..90f99f8 100644
--- a/samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs
+++ b/samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs
@@ -13,18 +13,14 @@
internal class OAuth2AuthorizationServer : IAuthorizationServer {
private static readonly RSAParameters AsymmetricTokenSigningPrivateKey = CreateRSAKey();
- private static readonly byte[] secret = CreateSecret();
-
- private readonly INonceStore nonceStore = new DatabaseNonceStore();
-
#region Implementation of IAuthorizationServer
- public byte[] Secret {
- get { return secret; }
+ public ICryptoKeyStore CryptoKeyStore {
+ get { return MvcApplication.KeyNonceStore; }
}
public INonceStore VerificationCodeNonceStore {
- get { return this.nonceStore; }
+ get { return MvcApplication.KeyNonceStore; }
}
public RSACryptoServiceProvider CreateAccessTokenSigningCryptoServiceProvider() {
@@ -75,19 +71,6 @@
}
/// <summary>
- /// Creates a symmetric secret used to sign and encrypt authorization server refresh tokens.
- /// </summary>
- /// <returns>A cryptographically strong symmetric key.</returns>
- private static byte[] CreateSecret() {
- // TODO: Replace this sample code with real code.
- // For this sample, we just generate random secrets.
- RandomNumberGenerator crypto = new RNGCryptoServiceProvider();
- var secret = new byte[32]; // 256-bit symmetric key to protect all protected resources.
- crypto.GetBytes(secret);
- return secret;
- }
-
- /// <summary>
/// Creates the RSA key used by all the crypto service provider instances we create.
/// </summary>
/// <returns>RSA data that includes the private key.</returns>
@@ -126,12 +109,12 @@
private bool IsAuthorizationValid(HashSet<string> requestedScopes, string clientIdentifier, DateTime issuedUtc, string username) {
var grantedScopeStrings = from auth in MvcApplication.DataContext.ClientAuthorizations
- where
- auth.Client.ClientIdentifier == clientIdentifier &&
- auth.CreatedOnUtc <= issuedUtc &&
- (!auth.ExpirationDateUtc.HasValue || auth.ExpirationDateUtc.Value >= DateTime.UtcNow) &&
- auth.User.OpenIDClaimedIdentifier == username
- select auth.Scope;
+ where
+ auth.Client.ClientIdentifier == clientIdentifier &&
+ auth.CreatedOnUtc <= issuedUtc &&
+ (!auth.ExpirationDateUtc.HasValue || auth.ExpirationDateUtc.Value >= DateTime.UtcNow) &&
+ auth.User.OpenIDClaimedIdentifier == username
+ select auth.Scope;
if (!grantedScopeStrings.Any()) {
// No granted authorizations prior to the issuance of this token, so it must have been revoked.
diff --git a/samples/OAuthAuthorizationServer/Code/Utilities.cs b/samples/OAuthAuthorizationServer/Code/Utilities.cs
new file mode 100644
index 0000000..c9109bd
--- /dev/null
+++ b/samples/OAuthAuthorizationServer/Code/Utilities.cs
@@ -0,0 +1,21 @@
+namespace OAuthAuthorizationServer.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+
+ internal static class Utilities {
+ /// <summary>
+ /// Ensures that local times are converted to UTC times. Unspecified kinds are recast to UTC with no conversion.
+ /// </summary>
+ /// <param name="value">The date-time to convert.</param>
+ /// <returns>The date-time in UTC time.</returns>
+ internal static DateTime AsUtc(this DateTime value) {
+ if (value.Kind == DateTimeKind.Unspecified) {
+ return new DateTime(value.Ticks, DateTimeKind.Utc);
+ }
+
+ return value.ToUniversalTime();
+ }
+ }
+} \ No newline at end of file