diff options
Diffstat (limited to 'samples/OAuthAuthorizationServer/Code')
6 files changed, 1116 insertions, 0 deletions
diff --git a/samples/OAuthAuthorizationServer/Code/Client.cs b/samples/OAuthAuthorizationServer/Code/Client.cs new file mode 100644 index 0000000..8669c19 --- /dev/null +++ b/samples/OAuthAuthorizationServer/Code/Client.cs @@ -0,0 +1,36 @@ +namespace OAuthAuthorizationServer.Code { + using System; + using System.Collections.Generic; + + using DotNetOpenAuth.OAuth2; + + /// <summary> + /// An OAuth 2.0 Client that has registered with this Authorization Server. + /// </summary> + public partial class Client : IConsumerDescription { + #region IConsumerDescription Members + + /// <summary> + /// Gets the client secret. + /// </summary> + string IConsumerDescription.Secret { + get { return this.ClientSecret; } + } + + /// <summary> + /// Gets the allowed callback URIs that this client has pre-registered with the service provider, if any. + /// </summary> + /// <value> + /// The URIs that user authorization responses may be directed to; must not be <c>null</c>, but may be empty. + /// </value> + /// <remarks> + /// The first element in this list (if any) will be used as the default client redirect URL if the client sends an authorization request without a redirect URL. + /// If the list is empty, any callback is allowed for this client. + /// </remarks> + List<Uri> IConsumerDescription.AllowedCallbacks { + get { return string.IsNullOrEmpty(this.Callback) ? new List<Uri>() : new List<Uri>(new Uri[] { new Uri(this.Callback) }); } + } + + #endregion + } +}
\ No newline at end of file diff --git a/samples/OAuthAuthorizationServer/Code/DataClasses.dbml b/samples/OAuthAuthorizationServer/Code/DataClasses.dbml new file mode 100644 index 0000000..b9b4677 --- /dev/null +++ b/samples/OAuthAuthorizationServer/Code/DataClasses.dbml @@ -0,0 +1,40 @@ +<?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|\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" /> + <Column Name="OpenIDClaimedIdentifier" Type="System.String" DbType="NVarChar(150) NOT NULL" CanBeNull="false" /> + <Column Name="OpenIDFriendlyIdentifier" Type="System.String" DbType="NVarChar(150)" CanBeNull="true" /> + <Association Name="User_ClientAuthorization" Member="ClientAuthorizations" Storage="_OAuthTokens" ThisKey="UserId" OtherKey="UserId" Type="ClientAuthorization" /> + </Type> + </Table> + <Table Name="dbo.Client" Member="Clients"> + <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="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" /> + </Type> + </Table> + <Table Name="dbo.ClientAuthorization" Member="ClientAuthorizations"> + <Type Name="ClientAuthorization"> + <Column Name="AuthorizationId" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" /> + <Column Name="CreatedOnUtc" Storage="_IssueDate" Type="System.DateTime" DbType="DateTime NOT NULL" CanBeNull="false" /> + <Column Name="ClientId" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" /> + <Column Name="UserId" Type="System.Int32" DbType="Int" CanBeNull="true" /> + <Column Name="Scope" Type="System.String" DbType="nvarchar(MAX)" CanBeNull="false" /> + <Column Name="ExpirationDateUtc" Type="System.DateTime" DbType="DateTime NULL" CanBeNull="true" /> + <Association Name="Client_ClientAuthorization" Member="Client" ThisKey="ClientId" OtherKey="ClientId" Type="Client" IsForeignKey="true" DeleteRule="CASCADE" DeleteOnNull="true" /> + <Association Name="User_ClientAuthorization" Member="User" ThisKey="UserId" OtherKey="UserId" Type="User" IsForeignKey="true" DeleteRule="CASCADE" /> + </Type> + </Table> + <Table Name="dbo.Nonce" Member="Nonces"> + <Type Name="Nonce"> + <Column Name="Context" Type="System.String" IsPrimaryKey="true" CanBeNull="false" /> + <Column Name="Code" Type="System.String" IsPrimaryKey="true" CanBeNull="false" /> + <Column Name="Timestamp" Type="System.DateTime" IsPrimaryKey="true" CanBeNull="false" /> + </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 new file mode 100644 index 0000000..e2982ce --- /dev/null +++ b/samples/OAuthAuthorizationServer/Code/DataClasses.dbml.layout @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> +<ordesignerObjectsDiagram dslVersion="1.0.0.0" absoluteBounds="0, 0, 11, 8.5" name="DataClasses"> + <DataContextMoniker Name="/DataClassesDataContext" /> + <nestedChildShapes> + <classShape Id="696d2c69-040e-411d-9257-bb664b743834" absoluteBounds="0.5, 0.5, 2.125, 1.3862939453125"> + <DataClassMoniker Name="/DataClassesDataContext/User" /> + <nestedChildShapes> + <elementListCompartment Id="cd90aeff-476c-44a9-897f-a986e4a8305b" absoluteBounds="0.515, 0.96, 2.0949999999999998, 0.8262939453125" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" /> + </nestedChildShapes> + </classShape> + <classShape Id="f909becb-85b1-4fe6-bb16-3feb3e4fe3ee" absoluteBounds="0.5, 3.5, 2, 1.7708968098958327"> + <DataClassMoniker Name="/DataClassesDataContext/Client" /> + <nestedChildShapes> + <elementListCompartment Id="464308c4-d112-4448-b0c9-d9b82fb0ca4e" absoluteBounds="0.515, 3.96, 1.9700000000000002, 1.2108968098958333" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" /> + </nestedChildShapes> + </classShape> + <classShape Id="895ebbc8-8352-4c04-9e53-b8e6c8302d36" absoluteBounds="3.5, 3.125, 2, 1.9631982421874996"> + <DataClassMoniker Name="/DataClassesDataContext/ClientAuthorization" /> + <nestedChildShapes> + <elementListCompartment Id="403126d0-3d2a-4af4-b0b8-c489a830bbd4" absoluteBounds="3.515, 3.585, 1.9700000000000002, 1.4031982421875" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" /> + </nestedChildShapes> + </classShape> + <classShape Id="a63562a7-acf2-4ed9-9686-52a1ad85633e" absoluteBounds="1.375, 6.375, 2, 1.3862939453124996"> + <DataClassMoniker Name="/DataClassesDataContext/Nonce" /> + <nestedChildShapes> + <elementListCompartment Id="9e4514ef-bc7b-4179-88e6-05363bf6ee5e" absoluteBounds="1.39, 6.835, 1.9700000000000002, 0.8262939453125" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" /> + </nestedChildShapes> + </classShape> + <associationConnector edgePoints="[(2.5 : 4.29409912109375); (3.5 : 4.29409912109375)]" fixedFrom="NotFixed" fixedTo="NotFixed"> + <AssociationMoniker Name="/DataClassesDataContext/Client/Client_ClientAuthorization" /> + <nodes> + <classShapeMoniker Id="f909becb-85b1-4fe6-bb16-3feb3e4fe3ee" /> + <classShapeMoniker Id="895ebbc8-8352-4c04-9e53-b8e6c8302d36" /> + </nodes> + </associationConnector> + <associationConnector edgePoints="[(2.59375 : 1.8862939453125); (2.59375 : 3.28125); (3.5 : 3.28125)]" fixedFrom="NotFixed" fixedTo="NotFixed"> + <AssociationMoniker Name="/DataClassesDataContext/User/User_ClientAuthorization" /> + <nodes> + <classShapeMoniker Id="696d2c69-040e-411d-9257-bb664b743834" /> + <classShapeMoniker Id="895ebbc8-8352-4c04-9e53-b8e6c8302d36" /> + </nodes> + </associationConnector> + </nestedChildShapes> +</ordesignerObjectsDiagram>
\ No newline at end of file diff --git a/samples/OAuthAuthorizationServer/Code/DataClasses.designer.cs b/samples/OAuthAuthorizationServer/Code/DataClasses.designer.cs new file mode 100644 index 0000000..940162f --- /dev/null +++ b/samples/OAuthAuthorizationServer/Code/DataClasses.designer.cs @@ -0,0 +1,808 @@ +#pragma warning disable 1591 +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:4.0.30319.1 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace OAuthAuthorizationServer.Code +{ + using System.Data.Linq; + using System.Data.Linq.Mapping; + using System.Data; + using System.Collections.Generic; + using System.Reflection; + using System.Linq; + using System.Linq.Expressions; + using System.ComponentModel; + using System; + + + [global::System.Data.Linq.Mapping.DatabaseAttribute(Name="Database")] + public partial class DataClassesDataContext : System.Data.Linq.DataContext + { + + private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource(); + + #region Extensibility Method Definitions + partial void OnCreated(); + partial void InsertUser(User instance); + partial void UpdateUser(User instance); + partial void DeleteUser(User instance); + partial void InsertClient(Client instance); + partial void UpdateClient(Client instance); + partial void DeleteClient(Client instance); + partial void InsertClientAuthorization(ClientAuthorization instance); + partial void UpdateClientAuthorization(ClientAuthorization instance); + partial void DeleteClientAuthorization(ClientAuthorization instance); + partial void InsertNonce(Nonce instance); + partial void UpdateNonce(Nonce instance); + partial void DeleteNonce(Nonce instance); + #endregion + + public DataClassesDataContext() : + base(global::System.Configuration.ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString, mappingSource) + { + OnCreated(); + } + + public DataClassesDataContext(string connection) : + base(connection, mappingSource) + { + OnCreated(); + } + + public DataClassesDataContext(System.Data.IDbConnection connection) : + base(connection, mappingSource) + { + OnCreated(); + } + + public DataClassesDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) : + base(connection, mappingSource) + { + OnCreated(); + } + + public DataClassesDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) : + base(connection, mappingSource) + { + OnCreated(); + } + + public System.Data.Linq.Table<User> Users + { + get + { + return this.GetTable<User>(); + } + } + + public System.Data.Linq.Table<Client> Clients + { + get + { + return this.GetTable<Client>(); + } + } + + public System.Data.Linq.Table<ClientAuthorization> ClientAuthorizations + { + get + { + return this.GetTable<ClientAuthorization>(); + } + } + + public System.Data.Linq.Table<Nonce> Nonces + { + get + { + return this.GetTable<Nonce>(); + } + } + } + + [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[User]")] + public partial class User : INotifyPropertyChanging, INotifyPropertyChanged + { + + private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty); + + private int _UserId; + + private string _OpenIDClaimedIdentifier; + + private string _OpenIDFriendlyIdentifier; + + private EntitySet<ClientAuthorization> _OAuthTokens; + + #region Extensibility Method Definitions + partial void OnLoaded(); + partial void OnValidate(System.Data.Linq.ChangeAction action); + partial void OnCreated(); + partial void OnUserIdChanging(int value); + partial void OnUserIdChanged(); + partial void OnOpenIDClaimedIdentifierChanging(string value); + partial void OnOpenIDClaimedIdentifierChanged(); + partial void OnOpenIDFriendlyIdentifierChanging(string value); + partial void OnOpenIDFriendlyIdentifierChanged(); + #endregion + + public User() + { + this._OAuthTokens = new EntitySet<ClientAuthorization>(new Action<ClientAuthorization>(this.attach_OAuthTokens), new Action<ClientAuthorization>(this.detach_OAuthTokens)); + OnCreated(); + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UserId", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)] + public int UserId + { + get + { + return this._UserId; + } + set + { + if ((this._UserId != value)) + { + this.OnUserIdChanging(value); + this.SendPropertyChanging(); + this._UserId = value; + this.SendPropertyChanged("UserId"); + this.OnUserIdChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OpenIDClaimedIdentifier", DbType="NVarChar(150) NOT NULL", CanBeNull=false)] + public string OpenIDClaimedIdentifier + { + get + { + return this._OpenIDClaimedIdentifier; + } + set + { + if ((this._OpenIDClaimedIdentifier != value)) + { + this.OnOpenIDClaimedIdentifierChanging(value); + this.SendPropertyChanging(); + this._OpenIDClaimedIdentifier = value; + this.SendPropertyChanged("OpenIDClaimedIdentifier"); + this.OnOpenIDClaimedIdentifierChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OpenIDFriendlyIdentifier", DbType="NVarChar(150)")] + public string OpenIDFriendlyIdentifier + { + get + { + return this._OpenIDFriendlyIdentifier; + } + set + { + if ((this._OpenIDFriendlyIdentifier != value)) + { + this.OnOpenIDFriendlyIdentifierChanging(value); + this.SendPropertyChanging(); + this._OpenIDFriendlyIdentifier = value; + this.SendPropertyChanged("OpenIDFriendlyIdentifier"); + this.OnOpenIDFriendlyIdentifierChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.AssociationAttribute(Name="User_ClientAuthorization", Storage="_OAuthTokens", ThisKey="UserId", OtherKey="UserId")] + public EntitySet<ClientAuthorization> ClientAuthorizations + { + get + { + return this._OAuthTokens; + } + set + { + this._OAuthTokens.Assign(value); + } + } + + 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)); + } + } + + private void attach_OAuthTokens(ClientAuthorization entity) + { + this.SendPropertyChanging(); + entity.User = this; + } + + private void detach_OAuthTokens(ClientAuthorization entity) + { + this.SendPropertyChanging(); + entity.User = null; + } + } + + [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Client")] + public partial class Client : INotifyPropertyChanging, INotifyPropertyChanged + { + + private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty); + + private int _ClientId; + + private string _ClientIdentifier; + + private string _ClientSecret; + + private string _Callback; + + private string _Name; + + private EntitySet<ClientAuthorization> _OAuthTokens; + + #region Extensibility Method Definitions + partial void OnLoaded(); + partial void OnValidate(System.Data.Linq.ChangeAction action); + partial void OnCreated(); + partial void OnClientIdChanging(int value); + partial void OnClientIdChanged(); + partial void OnClientIdentifierChanging(string value); + partial void OnClientIdentifierChanged(); + partial void OnClientSecretChanging(string value); + partial void OnClientSecretChanged(); + partial void OnCallbackChanging(string value); + partial void OnCallbackChanged(); + partial void OnNameChanging(string value); + partial void OnNameChanged(); + #endregion + + public Client() + { + this._OAuthTokens = new EntitySet<ClientAuthorization>(new Action<ClientAuthorization>(this.attach_OAuthTokens), new Action<ClientAuthorization>(this.detach_OAuthTokens)); + OnCreated(); + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ClientId", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)] + public int ClientId + { + get + { + return this._ClientId; + } + set + { + if ((this._ClientId != value)) + { + this.OnClientIdChanging(value); + this.SendPropertyChanging(); + this._ClientId = value; + this.SendPropertyChanged("ClientId"); + this.OnClientIdChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ClientIdentifier", DbType="NVarChar(50) NOT NULL", CanBeNull=false)] + public string ClientIdentifier + { + get + { + return this._ClientIdentifier; + } + set + { + if ((this._ClientIdentifier != value)) + { + this.OnClientIdentifierChanging(value); + this.SendPropertyChanging(); + this._ClientIdentifier = value; + this.SendPropertyChanged("ClientIdentifier"); + this.OnClientIdentifierChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ClientSecret", DbType="NVarChar(50) NOT NULL", CanBeNull=false)] + public string ClientSecret + { + get + { + return this._ClientSecret; + } + set + { + if ((this._ClientSecret != value)) + { + this.OnClientSecretChanging(value); + this.SendPropertyChanging(); + this._ClientSecret = value; + this.SendPropertyChanged("ClientSecret"); + this.OnClientSecretChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Callback")] + public string Callback + { + get + { + return this._Callback; + } + set + { + if ((this._Callback != value)) + { + this.OnCallbackChanging(value); + this.SendPropertyChanging(); + this._Callback = value; + this.SendPropertyChanged("Callback"); + this.OnCallbackChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Name", CanBeNull=false)] + public string Name + { + get + { + return this._Name; + } + set + { + if ((this._Name != value)) + { + this.OnNameChanging(value); + this.SendPropertyChanging(); + this._Name = value; + this.SendPropertyChanged("Name"); + this.OnNameChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.AssociationAttribute(Name="Client_ClientAuthorization", Storage="_OAuthTokens", ThisKey="ClientId", OtherKey="ClientId")] + public EntitySet<ClientAuthorization> ClientAuthorizations + { + get + { + return this._OAuthTokens; + } + set + { + this._OAuthTokens.Assign(value); + } + } + + 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)); + } + } + + private void attach_OAuthTokens(ClientAuthorization entity) + { + this.SendPropertyChanging(); + entity.Client = this; + } + + private void detach_OAuthTokens(ClientAuthorization entity) + { + this.SendPropertyChanging(); + entity.Client = null; + } + } + + [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.ClientAuthorization")] + public partial class ClientAuthorization : INotifyPropertyChanging, INotifyPropertyChanged + { + + private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty); + + private int _AuthorizationId; + + private System.DateTime _IssueDate; + + private int _ClientId; + + private System.Nullable<int> _UserId; + + private string _Scope; + + private System.Nullable<System.DateTime> _ExpirationDateUtc; + + private EntityRef<Client> _Client; + + private EntityRef<User> _User; + + #region Extensibility Method Definitions + partial void OnLoaded(); + partial void OnValidate(System.Data.Linq.ChangeAction action); + partial void OnCreated(); + partial void OnAuthorizationIdChanging(int value); + partial void OnAuthorizationIdChanged(); + partial void OnCreatedOnUtcChanging(System.DateTime value); + partial void OnCreatedOnUtcChanged(); + partial void OnClientIdChanging(int value); + partial void OnClientIdChanged(); + partial void OnUserIdChanging(System.Nullable<int> value); + partial void OnUserIdChanged(); + partial void OnScopeChanging(string value); + partial void OnScopeChanged(); + partial void OnExpirationDateUtcChanging(System.Nullable<System.DateTime> value); + partial void OnExpirationDateUtcChanged(); + #endregion + + public ClientAuthorization() + { + this._Client = default(EntityRef<Client>); + this._User = default(EntityRef<User>); + OnCreated(); + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_AuthorizationId", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)] + public int AuthorizationId + { + get + { + return this._AuthorizationId; + } + set + { + if ((this._AuthorizationId != value)) + { + this.OnAuthorizationIdChanging(value); + this.SendPropertyChanging(); + this._AuthorizationId = value; + this.SendPropertyChanged("AuthorizationId"); + this.OnAuthorizationIdChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_IssueDate", DbType="DateTime NOT NULL")] + public System.DateTime CreatedOnUtc + { + get + { + return this._IssueDate; + } + set + { + if ((this._IssueDate != value)) + { + this.OnCreatedOnUtcChanging(value); + this.SendPropertyChanging(); + this._IssueDate = value; + this.SendPropertyChanged("CreatedOnUtc"); + this.OnCreatedOnUtcChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ClientId", DbType="Int NOT NULL")] + public int ClientId + { + get + { + return this._ClientId; + } + set + { + if ((this._ClientId != value)) + { + if (this._Client.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnClientIdChanging(value); + this.SendPropertyChanging(); + this._ClientId = value; + this.SendPropertyChanged("ClientId"); + this.OnClientIdChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UserId", DbType="Int")] + public System.Nullable<int> UserId + { + get + { + return this._UserId; + } + set + { + if ((this._UserId != value)) + { + if (this._User.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnUserIdChanging(value); + this.SendPropertyChanging(); + this._UserId = value; + this.SendPropertyChanged("UserId"); + this.OnUserIdChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Scope", DbType="nvarchar(MAX)", CanBeNull=false)] + public string Scope + { + get + { + return this._Scope; + } + set + { + if ((this._Scope != value)) + { + this.OnScopeChanging(value); + this.SendPropertyChanging(); + this._Scope = value; + this.SendPropertyChanged("Scope"); + this.OnScopeChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ExpirationDateUtc", DbType="DateTime NULL")] + public System.Nullable<System.DateTime> ExpirationDateUtc + { + get + { + return this._ExpirationDateUtc; + } + set + { + if ((this._ExpirationDateUtc != value)) + { + this.OnExpirationDateUtcChanging(value); + this.SendPropertyChanging(); + this._ExpirationDateUtc = value; + this.SendPropertyChanged("ExpirationDateUtc"); + this.OnExpirationDateUtcChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.AssociationAttribute(Name="Client_ClientAuthorization", Storage="_Client", ThisKey="ClientId", OtherKey="ClientId", IsForeignKey=true, DeleteOnNull=true, DeleteRule="CASCADE")] + public Client Client + { + get + { + return this._Client.Entity; + } + set + { + Client previousValue = this._Client.Entity; + if (((previousValue != value) + || (this._Client.HasLoadedOrAssignedValue == false))) + { + this.SendPropertyChanging(); + if ((previousValue != null)) + { + this._Client.Entity = null; + previousValue.ClientAuthorizations.Remove(this); + } + this._Client.Entity = value; + if ((value != null)) + { + value.ClientAuthorizations.Add(this); + this._ClientId = value.ClientId; + } + else + { + this._ClientId = default(int); + } + this.SendPropertyChanged("Client"); + } + } + } + + [global::System.Data.Linq.Mapping.AssociationAttribute(Name="User_ClientAuthorization", Storage="_User", ThisKey="UserId", OtherKey="UserId", IsForeignKey=true, DeleteRule="CASCADE")] + public User User + { + get + { + return this._User.Entity; + } + set + { + User previousValue = this._User.Entity; + if (((previousValue != value) + || (this._User.HasLoadedOrAssignedValue == false))) + { + this.SendPropertyChanging(); + if ((previousValue != null)) + { + this._User.Entity = null; + previousValue.ClientAuthorizations.Remove(this); + } + this._User.Entity = value; + if ((value != null)) + { + value.ClientAuthorizations.Add(this); + this._UserId = value.UserId; + } + else + { + this._UserId = default(Nullable<int>); + } + this.SendPropertyChanged("User"); + } + } + } + + 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)); + } + } + } + + [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Nonce")] + public partial class Nonce : INotifyPropertyChanging, INotifyPropertyChanged + { + + private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty); + + private string _Context; + + private string _Code; + + private System.DateTime _Timestamp; + + #region Extensibility Method Definitions + partial void OnLoaded(); + partial void OnValidate(System.Data.Linq.ChangeAction action); + partial void OnCreated(); + partial void OnContextChanging(string value); + partial void OnContextChanged(); + partial void OnCodeChanging(string value); + partial void OnCodeChanged(); + partial void OnTimestampChanging(System.DateTime value); + partial void OnTimestampChanged(); + #endregion + + public Nonce() + { + OnCreated(); + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Context", CanBeNull=false, IsPrimaryKey=true)] + public string Context + { + get + { + return this._Context; + } + set + { + if ((this._Context != value)) + { + this.OnContextChanging(value); + this.SendPropertyChanging(); + this._Context = value; + this.SendPropertyChanged("Context"); + this.OnContextChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Code", CanBeNull=false, IsPrimaryKey=true)] + public string Code + { + get + { + return this._Code; + } + set + { + if ((this._Code != value)) + { + this.OnCodeChanging(value); + this.SendPropertyChanging(); + this._Code = value; + this.SendPropertyChanged("Code"); + this.OnCodeChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Timestamp", IsPrimaryKey=true)] + public System.DateTime Timestamp + { + get + { + return this._Timestamp; + } + set + { + if ((this._Timestamp != value)) + { + this.OnTimestampChanging(value); + this.SendPropertyChanging(); + this._Timestamp = value; + this.SendPropertyChanged("Timestamp"); + this.OnTimestampChanged(); + } + } + } + + 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/DatabaseNonceStore.cs new file mode 100644 index 0000000..a0ce19e --- /dev/null +++ b/samples/OAuthAuthorizationServer/Code/DatabaseNonceStore.cs @@ -0,0 +1,55 @@ +namespace OAuthAuthorizationServer.Code { + using System; + using System.Data.SqlClient; + using DotNetOpenAuth.Messaging.Bindings; + + /// <summary> + /// A database-persisted nonce store. + /// </summary> + public class DatabaseNonceStore : INonceStore { + /// <summary> + /// Initializes a new instance of the <see cref="DatabaseNonceStore"/> class. + /// </summary> + public DatabaseNonceStore() { + } + + #region INonceStore Members + + /// <summary> + /// Stores a given nonce and timestamp. + /// </summary> + /// <param name="context">The context, or namespace, within which the + /// <paramref name="nonce"/> must be unique. + /// The context SHOULD be treated as case-sensitive. + /// The value will never be <c>null</c> but may be the empty string.</param> + /// <param name="nonce">A series of random characters.</param> + /// <param name="timestampUtc">The UTC timestamp that together with the nonce string make it unique + /// within the given <paramref name="context"/>. + /// The timestamp may also be used by the data store to clear out old nonces.</param> + /// <returns> + /// True if the context+nonce+timestamp (combination) was not previously in the database. + /// False if the nonce was stored previously with the same timestamp and context. + /// </returns> + /// <remarks> + /// The nonce must be stored for no less than the maximum time window a message may + /// be processed within before being discarded as an expired message. + /// This maximum message age can be looked up via the + /// <see cref="DotNetOpenAuth.Configuration.MessagingElement.MaximumMessageLifetime"/> + /// property, accessible via the <see cref="DotNetOpenAuth.Configuration.DotNetOpenAuthSection.Configuration"/> + /// property. + /// </remarks> + public bool StoreNonce(string context, string nonce, DateTime timestampUtc) { + MvcApplication.DataContext.Nonces.InsertOnSubmit(new Nonce { Context = context, Code = nonce, Timestamp = timestampUtc }); + try { + MvcApplication.DataContext.SubmitChanges(); + return true; + } catch (System.Data.Linq.DuplicateKeyException) { + return false; + } catch (SqlException) { + return false; + } + } + + #endregion + } +}
\ No newline at end of file diff --git a/samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs b/samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs new file mode 100644 index 0000000..34118a3 --- /dev/null +++ b/samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs @@ -0,0 +1,133 @@ +namespace OAuthAuthorizationServer.Code { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Security.Cryptography; + using System.Web; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.Messaging.Bindings; + using DotNetOpenAuth.OAuth2; + using DotNetOpenAuth.OAuth2.ChannelElements; + using DotNetOpenAuth.OAuth2.Messages; + + internal class OAuth2AuthorizationServer : IAuthorizationServer { + internal static readonly RSAParameters AsymmetricTokenSigningPrivateKey; + + private static readonly byte[] secret; + + private readonly INonceStore nonceStore = new DatabaseNonceStore(); + + static OAuth2AuthorizationServer() { + // For this sample, we just generate random secrets. + RandomNumberGenerator crypto = new RNGCryptoServiceProvider(); + secret = new byte[16]; + crypto.GetBytes(secret); + +#if SAMPLESONLY + // Since the sample authorization server and the sample resource server must work together, + // we hard-code a FOR SAMPLE USE ONLY key pair. The matching public key information is hard-coded into the OAuthResourceServer sample. + // In a real app, the RSA parameters would typically come from a certificate that may already exist. It may simply be the HTTPS certificate for the auth server. + AsymmetricTokenSigningPrivateKey = new RSAParameters { + Exponent = new byte[] { 1, 0, 1 }, + Modulus = new byte[] { 210, 95, 53, 12, 203, 114, 150, 23, 23, 88, 4, 200, 47, 219, 73, 54, 146, 253, 126, 121, 105, 91, 118, 217, 182, 167, 140, 6, 67, 112, 97, 183, 66, 112, 245, 103, 136, 222, 205, 28, 196, 45, 6, 223, 192, 76, 56, 180, 90, 120, 144, 19, 31, 193, 37, 129, 186, 214, 36, 53, 204, 53, 108, 133, 112, 17, 133, 244, 3, 12, 230, 29, 243, 51, 79, 253, 10, 111, 185, 23, 74, 230, 99, 94, 78, 49, 209, 39, 95, 213, 248, 212, 22, 4, 222, 145, 77, 190, 136, 230, 134, 70, 228, 241, 194, 216, 163, 234, 52, 1, 64, 181, 139, 128, 90, 255, 214, 60, 168, 233, 254, 110, 31, 102, 58, 67, 201, 33 }, + P = new byte[] { 237, 238, 79, 75, 29, 57, 145, 201, 57, 177, 215, 108, 40, 77, 232, 237, 113, 38, 157, 195, 174, 134, 188, 175, 121, 28, 11, 236, 80, 146, 12, 38, 8, 12, 104, 46, 6, 247, 14, 149, 196, 23, 130, 116, 141, 137, 225, 74, 84, 111, 44, 163, 55, 10, 246, 154, 195, 158, 186, 241, 162, 11, 217, 77 }, + Q = new byte[] { 226, 89, 29, 67, 178, 205, 30, 152, 184, 165, 15, 152, 131, 245, 141, 80, 150, 3, 224, 136, 188, 248, 149, 36, 200, 250, 207, 156, 224, 79, 150, 191, 84, 214, 233, 173, 95, 192, 55, 123, 124, 255, 53, 85, 11, 233, 156, 66, 14, 27, 27, 163, 108, 199, 90, 37, 118, 38, 78, 171, 80, 26, 101, 37 }, + DP = new byte[] { 108, 176, 122, 132, 131, 187, 50, 191, 203, 157, 84, 29, 82, 100, 20, 205, 178, 236, 195, 17, 10, 254, 253, 222, 226, 226, 79, 8, 10, 222, 76, 178, 106, 230, 208, 8, 134, 162, 1, 133, 164, 232, 96, 109, 193, 226, 132, 138, 33, 252, 15, 86, 23, 228, 232, 54, 86, 186, 130, 7, 179, 208, 217, 217 }, + DQ = new byte[] { 175, 63, 252, 46, 140, 99, 208, 138, 194, 123, 218, 101, 101, 214, 91, 65, 199, 196, 220, 182, 66, 73, 221, 128, 11, 180, 85, 198, 202, 206, 20, 147, 179, 102, 106, 170, 247, 245, 229, 127, 81, 58, 111, 218, 151, 76, 154, 213, 114, 2, 127, 21, 187, 133, 102, 64, 151, 7, 245, 229, 34, 50, 45, 153 }, + InverseQ = new byte[] { 137, 156, 11, 248, 118, 201, 135, 145, 134, 121, 14, 162, 149, 14, 98, 84, 108, 160, 27, 91, 230, 116, 216, 181, 200, 49, 34, 254, 119, 153, 179, 52, 231, 234, 36, 148, 71, 161, 182, 171, 35, 182, 46, 164, 179, 100, 226, 71, 119, 23, 0, 16, 240, 4, 30, 57, 76, 109, 89, 131, 56, 219, 71, 206 }, + D = new byte[] { 108, 15, 123, 176, 150, 208, 197, 72, 23, 53, 159, 63, 53, 85, 238, 197, 153, 187, 156, 187, 192, 226, 186, 170, 26, 168, 245, 196, 65, 223, 248, 81, 170, 79, 91, 191, 83, 15, 31, 77, 39, 119, 249, 143, 245, 183, 49, 105, 115, 15, 122, 242, 87, 221, 94, 230, 196, 146, 59, 7, 103, 94, 9, 223, 146, 180, 189, 86, 190, 94, 242, 59, 32, 54, 23, 181, 124, 170, 63, 172, 90, 158, 169, 140, 6, 102, 170, 0, 135, 199, 35, 196, 212, 238, 196, 56, 14, 0, 140, 197, 169, 240, 156, 43, 182, 123, 102, 79, 89, 20, 120, 171, 43, 223, 58, 190, 230, 166, 185, 162, 186, 226, 31, 206, 196, 188, 104, 1 }, + }; +#else + // This is how you could generate your own public/private key pair. + var keyPair = new RSACryptoServiceProvider(); + + // After exporting the private/public key information, read the information out and store it somewhere + var privateKey = keyPair.ExportParameters(true); + var publicKey = keyPair.ExportParameters(false); + + // Ultimately the private key information must be what is returned bout the AccessTokenSigningPrivateKey property. + AsymmetricTokenSigningPrivateKey = privateKey; +#endif + } + + #region Implementation of IAuthorizationServer + + public byte[] Secret { + get { return secret; } + } + + public INonceStore VerificationCodeNonceStore { + get { return this.nonceStore; } + } + + public RSAParameters AccessTokenSigningPrivateKey { + get { return AsymmetricTokenSigningPrivateKey; } + } + + public IConsumerDescription GetClient(string clientIdentifier) { + var consumerRow = MvcApplication.DataContext.Clients.SingleOrDefault( + consumerCandidate => consumerCandidate.ClientIdentifier == clientIdentifier); + if (consumerRow == null) { + throw new ArgumentOutOfRangeException("clientIdentifier"); + } + + return consumerRow; + } + + #endregion + + public bool IsAuthorizationValid(IAuthorizationDescription authorization) { + return this.IsAuthorizationValid(authorization.Scope, authorization.ClientIdentifier, authorization.UtcIssued, authorization.User); + } + + public bool CanBeAutoApproved(EndUserAuthorizationRequest authorizationRequest) { + if (authorizationRequest == null) { + throw new ArgumentNullException("authorizationRequest"); + } + + // 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 + // 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 + // a client's identity and obtain unauthorized access. + var requestingClient = MvcApplication.DataContext.Clients.First(c => c.ClientIdentifier == authorizationRequest.ClientIdentifier); + if (!string.IsNullOrEmpty(requestingClient.ClientSecret)) { + return this.IsAuthorizationValid( + authorizationRequest.Scope, + authorizationRequest.ClientIdentifier, + DateTime.UtcNow, + HttpContext.Current.User.Identity.Name); + } + } + + // Default to not auto-approving. + return false; + } + + 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; + + if (!grantedScopeStrings.Any()) { + // No granted authorizations prior to the issuance of this token, so it must have been revoked. + // Even if later authorizations restore this client's ability to call in, we can't allow + // access tokens issued before the re-authorization because the revoked authorization should + // effectively and permanently revoke all access and refresh tokens. + return false; + } + + var grantedScopes = new HashSet<string>(OAuthUtilities.ScopeStringComparer); + foreach (string scope in grantedScopeStrings) { + grantedScopes.UnionWith(OAuthUtilities.SplitScopes(scope)); + } + + return requestedScopes.IsSubsetOf(grantedScopes); + } + } +}
\ No newline at end of file |