summaryrefslogtreecommitdiffstats
path: root/samples/OAuthAuthorizationServer/Code
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2011-06-23 19:55:32 -0700
committerAndrew Arnott <andrewarnott@gmail.com>2011-06-23 19:55:32 -0700
commit3769a926805bb896187c1a4f8848949c57dee819 (patch)
tree4319b92638fe292c8e3ce78a3cd3fef630df69eb /samples/OAuthAuthorizationServer/Code
parent2704b0fb445ab041f4f008bef8752e2828799b85 (diff)
parent7534febacfd0b85a8745cc99254610bebd745d86 (diff)
downloadDotNetOpenAuth-3769a926805bb896187c1a4f8848949c57dee819.zip
DotNetOpenAuth-3769a926805bb896187c1a4f8848949c57dee819.tar.gz
DotNetOpenAuth-3769a926805bb896187c1a4f8848949c57dee819.tar.bz2
Merging in support for and sample of implicit grants.
Diffstat (limited to 'samples/OAuthAuthorizationServer/Code')
-rw-r--r--samples/OAuthAuthorizationServer/Code/Client.cs14
-rw-r--r--samples/OAuthAuthorizationServer/Code/DataClasses.dbml4
-rw-r--r--samples/OAuthAuthorizationServer/Code/DataClasses.designer.cs4
-rw-r--r--samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs71
4 files changed, 76 insertions, 17 deletions
diff --git a/samples/OAuthAuthorizationServer/Code/Client.cs b/samples/OAuthAuthorizationServer/Code/Client.cs
index 62bc193..b32bb15 100644
--- a/samples/OAuthAuthorizationServer/Code/Client.cs
+++ b/samples/OAuthAuthorizationServer/Code/Client.cs
@@ -37,7 +37,19 @@
/// <c>true</c> if the callback URL is allowable for this client; otherwise, <c>false</c>.
/// </returns>
bool IConsumerDescription.IsCallbackAllowed(Uri callback) {
- return string.IsNullOrEmpty(this.Callback) || callback == new Uri(this.Callback);
+ if (string.IsNullOrEmpty(this.Callback)) {
+ // No callback rules have been set up for this client.
+ return true;
+ }
+
+ // In this sample, it's enough of a callback URL match if the scheme and host match.
+ // In a production app, it is advisable to require a match on the path as well.
+ Uri acceptableCallbackPattern = new Uri(this.Callback);
+ if (String.Equals(acceptableCallbackPattern.GetLeftPart(UriPartial.Authority), callback.GetLeftPart(UriPartial.Authority), StringComparison.Ordinal)) {
+ return true;
+ }
+
+ return false;
}
#endregion
diff --git a/samples/OAuthAuthorizationServer/Code/DataClasses.dbml b/samples/OAuthAuthorizationServer/Code/DataClasses.dbml
index 0ef987d..5536b6e 100644
--- a/samples/OAuthAuthorizationServer/Code/DataClasses.dbml
+++ b/samples/OAuthAuthorizationServer/Code/DataClasses.dbml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?><Database Name="Database" EntityNamespace="OAuthAuthorizationServer.Code" Class="DataClassesDataContext" xmlns="http://schemas.microsoft.com/linqtosql/dbml/2007">
- <Connection Mode="WebSettings" ConnectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\DatabaseABC.mdf;Integrated Security=True;User Instance=True" SettingsObjectName="System.Configuration.ConfigurationManager.ConnectionStrings" SettingsPropertyName="DatabaseConnectionString" Provider="System.Data.SqlClient" />
+ <Connection Mode="WebSettings" ConnectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True" SettingsObjectName="System.Configuration.ConfigurationManager.ConnectionStrings" SettingsPropertyName="DatabaseConnectionString" Provider="System.Data.SqlClient" />
<Table Name="dbo.[User]" Member="Users">
<Type Name="User">
<Column Name="UserId" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
@@ -12,7 +12,7 @@
<Type Name="Client">
<Column Name="ClientId" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
<Column Name="ClientIdentifier" Type="System.String" DbType="NVarChar(50) NOT NULL" CanBeNull="false" />
- <Column Name="ClientSecret" Type="System.String" DbType="NVarChar(50) NOT NULL" CanBeNull="false" />
+ <Column Name="ClientSecret" Type="System.String" DbType="NVarChar(50)" CanBeNull="true" />
<Column Name="Callback" Type="System.String" CanBeNull="true" />
<Column Name="Name" Type="System.String" CanBeNull="false" />
<Association Name="Client_ClientAuthorization" Member="ClientAuthorizations" Storage="_OAuthTokens" ThisKey="ClientId" OtherKey="ClientId" Type="ClientAuthorization" />
diff --git a/samples/OAuthAuthorizationServer/Code/DataClasses.designer.cs b/samples/OAuthAuthorizationServer/Code/DataClasses.designer.cs
index c8d1b19..5035753 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.225
+// Runtime Version:4.0.30319.235
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -336,7 +336,7 @@ namespace OAuthAuthorizationServer.Code
}
}
- [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ClientSecret", DbType="NVarChar(50) NOT NULL", CanBeNull=false)]
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ClientSecret", DbType="NVarChar(50)")]
public string ClientSecret
{
get
diff --git a/samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs b/samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs
index e2e4325..3899135 100644
--- a/samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs
+++ b/samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs
@@ -11,7 +11,25 @@
using DotNetOpenAuth.OAuth2.Messages;
internal class OAuth2AuthorizationServer : IAuthorizationServer {
- private static readonly RSAParameters AsymmetricTokenSigningPrivateKey = CreateRSAKey();
+ private static readonly RSACryptoServiceProvider AsymmetricTokenSigningPrivateKey = CreateRSA();
+
+#if SAMPLESONLY
+ /// <summary>
+ /// This is the FOR SAMPLE ONLY hard-coded public key of the complementary OAuthResourceServer sample.
+ /// </summary>
+ /// <remarks>
+ /// In a real app, the authorization server would need to determine which resource server the access token needs to be encoded for
+ /// based on the authorization request. It would then need to look up the public key for that resource server and use that in
+ /// preparing the access token for the client to use against that resource server.
+ /// </remarks>
+ private static readonly RSAParameters ResourceServerEncryptionPublicKey = new RSAParameters {
+ Exponent = new byte[] { 1, 0, 1 },
+ Modulus = new byte[] { 166, 175, 117, 169, 211, 251, 45, 215, 55, 53, 202, 65, 153, 155, 92, 219, 235, 243, 61, 170, 101, 250, 221, 214, 239, 175, 238, 175, 239, 20, 144, 72, 227, 221, 4, 219, 32, 225, 101, 96, 18, 33, 117, 176, 110, 123, 109, 23, 29, 85, 93, 50, 129, 163, 113, 57, 122, 212, 141, 145, 17, 31, 67, 165, 181, 91, 117, 23, 138, 251, 198, 132, 188, 213, 10, 157, 116, 229, 48, 168, 8, 127, 28, 156, 239, 124, 117, 36, 232, 100, 222, 23, 52, 186, 239, 5, 63, 207, 185, 16, 137, 73, 137, 147, 252, 71, 9, 239, 113, 27, 88, 255, 91, 56, 192, 142, 210, 21, 34, 81, 204, 239, 57, 60, 140, 249, 15, 101 },
+ };
+#else
+ [Obsolete("You must use a real key for a real app.", true)]
+ private static readonly RSAParameters ResourceServerEncryptionPublicKey;
+#endif
#region Implementation of IAuthorizationServer
@@ -23,10 +41,33 @@
get { return MvcApplication.KeyNonceStore; }
}
- public RSACryptoServiceProvider CreateAccessTokenSigningCryptoServiceProvider() {
- var asymmetricTokenSigningServiceProvider = new RSACryptoServiceProvider();
- asymmetricTokenSigningServiceProvider.ImportParameters(AsymmetricTokenSigningPrivateKey);
- return asymmetricTokenSigningServiceProvider;
+ public RSACryptoServiceProvider AccessTokenSigningKey {
+ get { return AsymmetricTokenSigningPrivateKey; }
+ }
+
+ public TimeSpan GetAccessTokenLifetime(IAccessTokenRequest accessTokenRequestMessage) {
+ // Just for the sake of the sample, we use a short-lived token. This can be useful to mitigate the security risks
+ // of access tokens that are used over standard HTTP.
+ // But this is just the lifetime of the access token. The client can still renew it using their refresh token until
+ // the authorization itself expires.
+ TimeSpan lifetime = TimeSpan.FromMinutes(2);
+
+ // Also take into account the remaining life of the authorization and artificially shorten the access token's lifetime
+ // to account for that if necessary.
+ // TODO: code here
+
+ return lifetime;
+ }
+
+ public RSACryptoServiceProvider GetResourceServerEncryptionKey(IAccessTokenRequest accessTokenRequestMessage) {
+ var resourceServerEncryptionKey = new RSACryptoServiceProvider();
+
+ // For this sample, we assume just one resource server.
+ // If this authorization server needs to mint access tokens for more than one resource server,
+ // we'd look at the request message passed to us and decide which public key to return.
+ resourceServerEncryptionKey.ImportParameters(ResourceServerEncryptionPublicKey);
+
+ return resourceServerEncryptionKey;
}
public IConsumerDescription GetClient(string clientIdentifier) {
@@ -51,7 +92,7 @@
}
// NEVER issue an auto-approval to a client that would end up getting an access token immediately
- // (without a client secret), as that would allow ANY client to spoof an approved client's identity
+ // (without a client secret), as that would allow arbitrary clients to masquarade as an approved client
// and obtain unauthorized access to user data.
if (authorizationRequest.ResponseType == EndUserAuthorizationResponseType.AuthorizationCode) {
// Never issue auto-approval if the client secret is blank, since that too makes it easy to spoof
@@ -107,18 +148,24 @@
#endif
}
+ private static RSACryptoServiceProvider CreateRSA() {
+ var rsa = new RSACryptoServiceProvider();
+ rsa.ImportParameters(CreateRSAKey());
+ return rsa;
+ }
+
private bool IsAuthorizationValid(HashSet<string> requestedScopes, string clientIdentifier, DateTime issuedUtc, string username) {
// If db precision exceeds token time precision (which is common), the following query would
// often disregard a token that is minted immediately after the authorization record is stored in the db.
// To compensate for this, we'll increase the timestamp on the token's issue date by 1 second.
issuedUtc += TimeSpan.FromSeconds(1);
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.