summaryrefslogtreecommitdiffstats
path: root/src/OAuth/OAuthResourceServer
diff options
context:
space:
mode:
Diffstat (limited to 'src/OAuth/OAuthResourceServer')
-rw-r--r--src/OAuth/OAuthResourceServer/Code/Global.cs106
-rw-r--r--src/OAuth/OAuthResourceServer/Code/IDataApi.cs21
-rw-r--r--src/OAuth/OAuthResourceServer/Code/OAuthAuthorizationManager.cs80
-rw-r--r--src/OAuth/OAuthResourceServer/Code/OAuthPrincipalAuthorizationPolicy.cs47
-rw-r--r--src/OAuth/OAuthResourceServer/Code/TracePageAppender.cs13
-rw-r--r--src/OAuth/OAuthResourceServer/DataApi.cs42
-rw-r--r--src/OAuth/OAuthResourceServer/DataApi.svc1
-rw-r--r--src/OAuth/OAuthResourceServer/Default.aspx4
-rw-r--r--src/OAuth/OAuthResourceServer/Default.aspx.cs10
-rw-r--r--src/OAuth/OAuthResourceServer/Default.aspx.designer.cs15
-rw-r--r--src/OAuth/OAuthResourceServer/Global.asax1
-rw-r--r--src/OAuth/OAuthResourceServer/Login.aspx11
-rw-r--r--src/OAuth/OAuthResourceServer/MasterPage.master23
-rw-r--r--src/OAuth/OAuthResourceServer/Members/Logoff.aspx8
-rw-r--r--src/OAuth/OAuthResourceServer/Members/Web.config8
-rw-r--r--src/OAuth/OAuthResourceServer/OAuthResourceServer.csproj156
-rw-r--r--src/OAuth/OAuthResourceServer/Properties/AssemblyInfo.cs35
-rw-r--r--src/OAuth/OAuthResourceServer/Settings.StyleCop1
-rw-r--r--src/OAuth/OAuthResourceServer/TracePage.aspx18
-rw-r--r--src/OAuth/OAuthResourceServer/TracePage.aspx.cs24
-rw-r--r--src/OAuth/OAuthResourceServer/TracePage.aspx.designer.cs42
-rw-r--r--src/OAuth/OAuthResourceServer/Web.config117
-rw-r--r--src/OAuth/OAuthResourceServer/favicon.icobin0 -> 1150 bytes
-rw-r--r--src/OAuth/OAuthResourceServer/packages.config9
24 files changed, 792 insertions, 0 deletions
diff --git a/src/OAuth/OAuthResourceServer/Code/Global.cs b/src/OAuth/OAuthResourceServer/Code/Global.cs
new file mode 100644
index 0000000..a48baff
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Code/Global.cs
@@ -0,0 +1,106 @@
+namespace OAuthResourceServer.Code {
+ using System;
+ using System.Linq;
+ using System.Security.Cryptography;
+ using System.ServiceModel;
+ using System.Text;
+ using System.Web;
+ using DotNetOpenAuth.OAuth2;
+ using DotNetOpenAuth.OAuth2.Messages;
+
+ /// <summary>
+ /// The web application global events and properties.
+ /// </summary>
+ public class Global : HttpApplication {
+#if SAMPLESONLY
+ /// <summary>
+ /// The FOR SAMPLE ONLY hard-coded public key of the authorization server that is used to verify the signature on access tokens.
+ /// </summary>
+ /// <remarks>
+ /// In a real app, the authorization server public key would likely come from the server's HTTPS certificate,
+ /// but in any case would be determined by the authorization server and its policies.
+ /// The hard-coded value used here is so this sample works well with the OAuthAuthorizationServer sample,
+ /// which has the corresponding sample private key.
+ /// </remarks>
+ public static readonly RSAParameters AuthorizationServerSigningPublicKey = 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 },
+ };
+#else
+ [Obsolete("You must use a real key for a real app.", true)]
+ public static readonly RSAParameters AuthorizationServerSigningPublicKey = new RSAParameters();
+#endif
+
+ /// <summary>
+ /// An application memory cache of recent log messages.
+ /// </summary>
+ public static StringBuilder LogMessages = new StringBuilder();
+
+ /// <summary>
+ /// The logger for this sample to use.
+ /// </summary>
+ public static log4net.ILog Logger = log4net.LogManager.GetLogger("DotNetOpenAuth.OAuthResourceServer");
+
+#if SAMPLESONLY
+ /// <summary>
+ /// The FOR SAMPLE ONLY hard-coded private key used to decrypt access tokens intended for this resource server.
+ /// </summary>
+ /// <remarks>
+ /// In a real app, the resource server would likely use its own HTTPS certificate or some other certificate stored securely
+ /// on the server rather than hard-coded in compiled code for security and ease of changing the certificate in case it was compromised.
+ /// </remarks>
+ internal static readonly RSAParameters ResourceServerEncryptionPrivateKey = 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 },
+ P = new byte[] { 227, 25, 96, 71, 220, 99, 11, 55, 15, 241, 153, 20, 32, 213, 68, 127, 246, 162, 153, 204, 98, 26, 10, 99, 46, 189, 35, 18, 162, 180, 184, 134, 230, 198, 156, 87, 52, 174, 74, 155, 163, 204, 252, 51, 232, 189, 135, 172, 88, 24, 52, 174, 72, 157, 81, 90, 118, 59, 142, 154, 152, 201, 62, 177 },
+ Q = new byte[] { 187, 229, 223, 233, 118, 20, 5, 251, 85, 8, 196, 3, 220, 232, 38, 159, 15, 95, 174, 162, 36, 13, 138, 239, 16, 85, 220, 104, 4, 162, 174, 160, 234, 133, 156, 33, 117, 139, 22, 112, 108, 214, 97, 178, 100, 191, 13, 177, 164, 30, 124, 48, 33, 118, 21, 137, 38, 59, 191, 13, 183, 5, 16, 245 },
+ DP = new byte[] { 225, 112, 117, 117, 160, 191, 233, 136, 53, 153, 158, 94, 174, 225, 71, 104, 200, 75, 77, 229, 232, 148, 245, 46, 212, 93, 9, 142, 28, 90, 206, 187, 140, 40, 41, 87, 32, 130, 204, 169, 136, 135, 154, 237, 100, 227, 144, 229, 115, 102, 68, 21, 167, 28, 20, 128, 122, 210, 80, 148, 3, 139, 243, 97 },
+ DQ = new byte[] { 133, 252, 100, 207, 232, 184, 92, 143, 157, 82, 115, 220, 65, 81, 118, 0, 228, 136, 153, 81, 219, 157, 160, 157, 218, 171, 47, 81, 41, 69, 12, 123, 136, 224, 159, 182, 40, 72, 119, 70, 210, 5, 137, 131, 25, 94, 55, 152, 157, 236, 115, 40, 43, 36, 54, 53, 39, 131, 97, 56, 153, 114, 206, 101 },
+ InverseQ = new byte[] { 129, 119, 84, 118, 29, 35, 194, 186, 96, 169, 7, 7, 200, 22, 187, 34, 72, 131, 200, 246, 79, 120, 49, 242, 8, 220, 74, 114, 195, 95, 90, 108, 80, 2, 212, 71, 125, 100, 184, 77, 203, 236, 64, 122, 108, 212, 150, 129, 66, 248, 218, 3, 186, 71, 213, 236, 142, 66, 33, 196, 150, 216, 138, 114 },
+ D = new byte[] { 94, 20, 94, 119, 18, 92, 141, 13, 17, 238, 92, 80, 22, 96, 232, 82, 128, 164, 115, 195, 191, 119, 142, 202, 135, 210, 103, 8, 10, 11, 51, 60, 208, 207, 168, 179, 253, 164, 250, 80, 245, 42, 201, 128, 97, 123, 108, 161, 69, 63, 47, 49, 24, 150, 165, 139, 105, 214, 154, 104, 172, 159, 86, 208, 64, 134, 158, 156, 234, 125, 140, 210, 3, 32, 60, 28, 62, 154, 198, 21, 132, 191, 236, 10, 158, 12, 247, 159, 177, 77, 178, 53, 238, 95, 165, 9, 200, 28, 148, 242, 35, 70, 189, 121, 169, 248, 97, 91, 111, 45, 103, 1, 167, 220, 67, 250, 175, 89, 122, 238, 192, 144, 142, 248, 198, 101, 96, 129 },
+ };
+#else
+ [Obsolete("You must use a real key for a real app.", true)]
+ internal static readonly RSAParameters ResourceServerEncryptionPrivateKey = new RSAParameters();
+#endif
+
+ /// <summary>
+ /// Creates the crypto service provider for this resource server that contains the private key used to decrypt an access token.
+ /// </summary>
+ /// <returns>An RSA crypto service provider.</returns>
+ internal static RSACryptoServiceProvider CreateResourceServerEncryptionServiceProvider() {
+ var resourceServerEncryptionServiceProvider = new RSACryptoServiceProvider();
+ resourceServerEncryptionServiceProvider.ImportParameters(ResourceServerEncryptionPrivateKey);
+ return resourceServerEncryptionServiceProvider;
+ }
+
+ /// <summary>
+ /// Creates the crypto service provider for the authorization server that contains the public key used to verify an access token signature.
+ /// </summary>
+ /// <returns>An RSA crypto service provider.</returns>
+ internal static RSACryptoServiceProvider CreateAuthorizationServerSigningServiceProvider() {
+ var authorizationServerSigningServiceProvider = new RSACryptoServiceProvider();
+ authorizationServerSigningServiceProvider.ImportParameters(AuthorizationServerSigningPublicKey);
+ return authorizationServerSigningServiceProvider;
+ }
+
+ private void Application_Start(object sender, EventArgs e) {
+ log4net.Config.XmlConfigurator.Configure();
+ Logger.Info("Sample starting...");
+ }
+
+ private void Application_End(object sender, EventArgs e) {
+ Logger.Info("Sample shutting down...");
+
+ // this would be automatic, but in partial trust scenarios it is not.
+ log4net.LogManager.Shutdown();
+ }
+
+ private void Application_Error(object sender, EventArgs e) {
+ Logger.Error("An unhandled exception occurred in ASP.NET processing: " + Server.GetLastError(), Server.GetLastError());
+ }
+
+ private void Application_EndRequest(object sender, EventArgs e) {
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/Code/IDataApi.cs b/src/OAuth/OAuthResourceServer/Code/IDataApi.cs
new file mode 100644
index 0000000..7ba189d
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Code/IDataApi.cs
@@ -0,0 +1,21 @@
+namespace OAuthResourceServer.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Runtime.Serialization;
+ using System.ServiceModel;
+ using System.ServiceModel.Web;
+ using System.Text;
+
+ [ServiceContract]
+ public interface IDataApi {
+ [OperationContract, WebGet(UriTemplate = "/age", ResponseFormat = WebMessageFormat.Json)]
+ int? GetAge();
+
+ [OperationContract, WebGet(UriTemplate = "/name", ResponseFormat = WebMessageFormat.Json)]
+ string GetName();
+
+ [OperationContract, WebGet(UriTemplate = "/favoritesites", ResponseFormat = WebMessageFormat.Json)]
+ string[] GetFavoriteSites();
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/Code/OAuthAuthorizationManager.cs b/src/OAuth/OAuthResourceServer/Code/OAuthAuthorizationManager.cs
new file mode 100644
index 0000000..8d0c13d
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Code/OAuthAuthorizationManager.cs
@@ -0,0 +1,80 @@
+namespace OAuthResourceServer.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.IdentityModel.Policy;
+ using System.Linq;
+ using System.Security.Principal;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+ using System.ServiceModel.Security;
+
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth2;
+
+ using ProtocolException = System.ServiceModel.ProtocolException;
+
+ /// <summary>
+ /// A WCF extension to authenticate incoming messages using OAuth.
+ /// </summary>
+ public class OAuthAuthorizationManager : ServiceAuthorizationManager {
+ public OAuthAuthorizationManager() {
+ }
+
+ protected override bool CheckAccessCore(OperationContext operationContext) {
+ if (!base.CheckAccessCore(operationContext)) {
+ return false;
+ }
+
+ var httpDetails = operationContext.RequestContext.RequestMessage.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
+ var requestUri = operationContext.RequestContext.RequestMessage.Properties.Via;
+
+ try {
+ var principal = VerifyOAuth2(httpDetails, requestUri);
+ if (principal != null) {
+ var policy = new OAuthPrincipalAuthorizationPolicy(principal);
+ var policies = new List<IAuthorizationPolicy> {
+ policy,
+ };
+
+ var securityContext = new ServiceSecurityContext(policies.AsReadOnly());
+ if (operationContext.IncomingMessageProperties.Security != null) {
+ operationContext.IncomingMessageProperties.Security.ServiceSecurityContext = securityContext;
+ } else {
+ operationContext.IncomingMessageProperties.Security = new SecurityMessageProperty {
+ ServiceSecurityContext = securityContext,
+ };
+ }
+
+ securityContext.AuthorizationContext.Properties["Identities"] = new List<IIdentity> {
+ principal.Identity,
+ };
+
+ // Only allow this method call if the access token scope permits it.
+ return principal.IsInRole(operationContext.IncomingMessageHeaders.Action ?? operationContext.IncomingMessageHeaders.To.AbsolutePath);
+ } else {
+ return false;
+ }
+ } catch (ProtocolException ex) {
+ Global.Logger.Error("Error processing OAuth messages.", ex);
+ }
+
+ return false;
+ }
+
+ private static IPrincipal VerifyOAuth2(HttpRequestMessageProperty httpDetails, Uri requestUri) {
+ // for this sample where the auth server and resource server are the same site,
+ // we use the same public/private key.
+ using (var signing = Global.CreateAuthorizationServerSigningServiceProvider()) {
+ using (var encrypting = Global.CreateResourceServerEncryptionServiceProvider()) {
+ var resourceServer = new ResourceServer(new StandardAccessTokenAnalyzer(signing, encrypting));
+
+ IPrincipal result;
+ var error = resourceServer.VerifyAccess(HttpRequestInfo.Create(httpDetails, requestUri), out result);
+
+ // TODO: return the prepared error code.
+ return error != null ? null : result;
+ }
+ }
+ }
+ }
+}
diff --git a/src/OAuth/OAuthResourceServer/Code/OAuthPrincipalAuthorizationPolicy.cs b/src/OAuth/OAuthResourceServer/Code/OAuthPrincipalAuthorizationPolicy.cs
new file mode 100644
index 0000000..ac01c4d
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Code/OAuthPrincipalAuthorizationPolicy.cs
@@ -0,0 +1,47 @@
+namespace OAuthResourceServer.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.IdentityModel.Claims;
+ using System.IdentityModel.Policy;
+ using System.Linq;
+ using System.Security.Principal;
+ using System.Web;
+
+ public class OAuthPrincipalAuthorizationPolicy : IAuthorizationPolicy {
+ private readonly Guid uniqueId = Guid.NewGuid();
+ private readonly IPrincipal principal;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="OAuthPrincipalAuthorizationPolicy"/> class.
+ /// </summary>
+ /// <param name="principal">The principal.</param>
+ public OAuthPrincipalAuthorizationPolicy(IPrincipal principal) {
+ this.principal = principal;
+ }
+
+ #region IAuthorizationComponent Members
+
+ /// <summary>
+ /// Gets a unique ID for this instance.
+ /// </summary>
+ public string Id {
+ get { return this.uniqueId.ToString(); }
+ }
+
+ #endregion
+
+ #region IAuthorizationPolicy Members
+
+ public ClaimSet Issuer {
+ get { return ClaimSet.System; }
+ }
+
+ public bool Evaluate(EvaluationContext evaluationContext, ref object state) {
+ evaluationContext.AddClaimSet(this, new DefaultClaimSet(Claim.CreateNameClaim(this.principal.Identity.Name)));
+ evaluationContext.Properties["Principal"] = this.principal;
+ return true;
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/Code/TracePageAppender.cs b/src/OAuth/OAuthResourceServer/Code/TracePageAppender.cs
new file mode 100644
index 0000000..4dc543f
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Code/TracePageAppender.cs
@@ -0,0 +1,13 @@
+namespace OAuthResourceServer.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Web;
+
+ public class TracePageAppender : log4net.Appender.AppenderSkeleton {
+ protected override void Append(log4net.Core.LoggingEvent loggingEvent) {
+ StringWriter sw = new StringWriter(Global.LogMessages);
+ Layout.Format(sw, loggingEvent);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/DataApi.cs b/src/OAuth/OAuthResourceServer/DataApi.cs
new file mode 100644
index 0000000..f1ac19e
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/DataApi.cs
@@ -0,0 +1,42 @@
+namespace OAuthResourceServer {
+ using System.Linq;
+ using System.Security.Principal;
+ using System.ServiceModel;
+
+ using Code;
+
+ /// <summary>
+ /// The WCF service API.
+ /// </summary>
+ /// <remarks>
+ /// Note how there is no code here that is bound to OAuth or any other
+ /// credential/authorization scheme. That's all part of the channel/binding elsewhere.
+ /// And the reference to OperationContext.Current.ServiceSecurityContext.PrimaryIdentity
+ /// is the user being impersonated by the WCF client.
+ /// In the OAuth case, it is the user who authorized the OAuth access token that was used
+ /// to gain access to the service.
+ /// </remarks>
+ public class DataApi : IDataApi {
+ private IIdentity User {
+ get { return OperationContext.Current.ServiceSecurityContext.PrimaryIdentity; }
+ }
+
+ public int? GetAge() {
+ // We'll just make up an age personalized to the user by counting the length of the username.
+ return this.User.Name.Length;
+ }
+
+ public string GetName() {
+ return this.User.Name;
+ }
+
+ public string[] GetFavoriteSites() {
+ // Just return a hard-coded list, to avoid having to have a database in a sample.
+ return new string[] {
+ "http://www.dotnetopenauth.net/",
+ "http://www.oauth.net/",
+ "http://www.openid.net/",
+ };
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/DataApi.svc b/src/OAuth/OAuthResourceServer/DataApi.svc
new file mode 100644
index 0000000..9a36ef6
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/DataApi.svc
@@ -0,0 +1 @@
+<%@ ServiceHost Language="C#" Debug="true" Service="OAuthResourceServer.DataApi" CodeBehind="DataApi.cs" %>
diff --git a/src/OAuth/OAuthResourceServer/Default.aspx b/src/OAuth/OAuthResourceServer/Default.aspx
new file mode 100644
index 0000000..a333313
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Default.aspx
@@ -0,0 +1,4 @@
+<%@ Page Title="DotNetOpenAuth Service Provider Sample" Language="C#" MasterPageFile="~/MasterPage.master" CodeBehind="~/Default.aspx.cs" Inherits="OAuthResourceServer._Default" AutoEventWireup="True" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+</asp:Content>
diff --git a/src/OAuth/OAuthResourceServer/Default.aspx.cs b/src/OAuth/OAuthResourceServer/Default.aspx.cs
new file mode 100644
index 0000000..46ca65e
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Default.aspx.cs
@@ -0,0 +1,10 @@
+namespace OAuthResourceServer {
+ using System;
+ using System.Configuration;
+ using System.IO;
+
+ using Code;
+
+ public partial class _Default : System.Web.UI.Page {
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/Default.aspx.designer.cs b/src/OAuth/OAuthResourceServer/Default.aspx.designer.cs
new file mode 100644
index 0000000..4fa5152
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Default.aspx.designer.cs
@@ -0,0 +1,15 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthResourceServer {
+
+
+ public partial class _Default {
+ }
+}
diff --git a/src/OAuth/OAuthResourceServer/Global.asax b/src/OAuth/OAuthResourceServer/Global.asax
new file mode 100644
index 0000000..0f290d5
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Global.asax
@@ -0,0 +1 @@
+<%@ Application Inherits="OAuthResourceServer.Code.Global" CodeBehind="Code\Global.cs" %>
diff --git a/src/OAuth/OAuthResourceServer/Login.aspx b/src/OAuth/OAuthResourceServer/Login.aspx
new file mode 100644
index 0000000..9593faa
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Login.aspx
@@ -0,0 +1,11 @@
+<%@ Page Title="Login" Language="C#" MasterPageFile="~/MasterPage.master" %>
+
+<%@ Register Assembly="DotNetOpenAuth.OpenId.RelyingParty.UI" Namespace="DotNetOpenAuth.OpenId.RelyingParty" TagPrefix="rp" %>
+<script runat="server">
+ protected void Page_Load(object sender, EventArgs e) {
+ OpenIdLogin1.Focus();
+ }
+</script>
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <rp:OpenIdLogin runat="server" TabIndex='1' ID="OpenIdLogin1" />
+</asp:Content>
diff --git a/src/OAuth/OAuthResourceServer/MasterPage.master b/src/OAuth/OAuthResourceServer/MasterPage.master
new file mode 100644
index 0000000..3147153
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/MasterPage.master
@@ -0,0 +1,23 @@
+<%@ Master Language="C#" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<script runat="server">
+
+</script>
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title>DotNetOpenAuth OAuth 2.0 Resource Server sample</title>
+ <asp:ContentPlaceHolder ID="head" runat="server"/>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <h1>DotNetOpenAuth OAuth 2.0 Resource Server sample</h1>
+ <div>
+ <asp:ContentPlaceHolder ID="Body" runat="server">
+ </asp:ContentPlaceHolder>
+ </div>
+ </form>
+</body>
+</html>
diff --git a/src/OAuth/OAuthResourceServer/Members/Logoff.aspx b/src/OAuth/OAuthResourceServer/Members/Logoff.aspx
new file mode 100644
index 0000000..afa9dd9
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Members/Logoff.aspx
@@ -0,0 +1,8 @@
+<%@ Page Title="Log off" Language="C#" MasterPageFile="~/MasterPage.master" %>
+
+<script runat="server">
+ private void Page_Load(object sender, EventArgs e) {
+ FormsAuthentication.SignOut();
+ Response.Redirect("~/");
+ }
+</script>
diff --git a/src/OAuth/OAuthResourceServer/Members/Web.config b/src/OAuth/OAuthResourceServer/Members/Web.config
new file mode 100644
index 0000000..50fab27
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Members/Web.config
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<configuration>
+ <system.web>
+ <authorization>
+ <deny users="?"/>
+ </authorization>
+ </system.web>
+</configuration>
diff --git a/src/OAuth/OAuthResourceServer/OAuthResourceServer.csproj b/src/OAuth/OAuthResourceServer/OAuthResourceServer.csproj
new file mode 100644
index 0000000..38cc9c8
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/OAuthResourceServer.csproj
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))\EnlistmentInfo.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))' != '' " />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>
+ </ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{E135F455-0669-49F8-9207-07FCA8C8FC79}</ProjectGuid>
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>OAuthResourceServer</RootNamespace>
+ <AssemblyName>OAuthResourceServer</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <UseIISExpress>false</UseIISExpress>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\</SolutionDir>
+ <RestorePackages>true</RestorePackages>
+ <TargetFrameworkProfile />
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>TRACE;DEBUG;SAMPLESONLY</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>TRACE;SAMPLESONLY</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="DotNetOpenAuth.Core">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.Core.4.0.0-RC1\lib\net40-full\DotNetOpenAuth.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth.Common">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth.Common.4.0.0-RC1\lib\net40-full\DotNetOpenAuth.OAuth.Common.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth2">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth2.Core.0.23.0-draft\lib\net40-full\DotNetOpenAuth.OAuth2.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth2.ResourceServer">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth2.ResourceServer.0.23.0-draft\lib\net40-full\DotNetOpenAuth.OAuth2.ResourceServer.dll</HintPath>
+ </Reference>
+ <Reference Include="log4net">
+ <HintPath>..\..\..\packages\log4net.2.0.0\lib\net40-full\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Data.Linq" />
+ <Reference Include="System.IdentityModel" />
+ <Reference Include="System.ServiceModel" />
+ <Reference Include="System.ServiceModel.Web" />
+ <Reference Include="System.Web.Abstractions" />
+ <Reference Include="System.Web.ApplicationServices" />
+ <Reference Include="System.Web.DynamicData" />
+ <Reference Include="System.Web.Entity" />
+ <Reference Include="System.Web.Extensions" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Web.Services" />
+ <Reference Include="System.EnterpriseServices" />
+ <Reference Include="System.Web.Mobile" />
+ <Reference Include="System.Xml.Linq" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="DataApi.svc" />
+ <Content Include="Default.aspx" />
+ <Content Include="favicon.ico" />
+ <Content Include="Global.asax" />
+ <Content Include="Login.aspx" />
+ <Content Include="Members\Logoff.aspx" />
+ <Content Include="TracePage.aspx" />
+ <Content Include="Web.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Default.aspx.designer.cs">
+ <DependentUpon>Default.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="DataApi.cs">
+ <DependentUpon>DataApi.svc</DependentUpon>
+ </Compile>
+ <Compile Include="Code\Global.cs" />
+ <Compile Include="Code\IDataApi.cs" />
+ <Compile Include="Code\OAuthAuthorizationManager.cs" />
+ <Compile Include="Code\OAuthPrincipalAuthorizationPolicy.cs" />
+ <Compile Include="Code\TracePageAppender.cs" />
+ <Compile Include="Default.aspx.cs">
+ <DependentUpon>Default.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="TracePage.aspx.cs">
+ <DependentUpon>TracePage.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="TracePage.aspx.designer.cs">
+ <DependentUpon>TracePage.aspx</DependentUpon>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="App_Data\" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="MasterPage.master" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Members\Web.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{3259AA49-8AA1-44D3-9025-A0B520596A8C}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
+ <ProjectExtensions>
+ <VisualStudio>
+ <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
+ <WebProjectProperties>
+ <UseIIS>False</UseIIS>
+ <AutoAssignPort>False</AutoAssignPort>
+ <DevelopmentServerPort>65169</DevelopmentServerPort>
+ <DevelopmentServerVPath>/</DevelopmentServerVPath>
+ <IISUrl>
+ </IISUrl>
+ <NTLMAuthentication>False</NTLMAuthentication>
+ <UseCustomServer>False</UseCustomServer>
+ <CustomServerUrl>
+ </CustomServerUrl>
+ <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
+ </WebProjectProperties>
+ </FlavorProperties>
+ </VisualStudio>
+ </ProjectExtensions>
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))\EnlistmentInfo.targets" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))' != '' " />
+ <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
+</Project> \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/Properties/AssemblyInfo.cs b/src/OAuth/OAuthResourceServer/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..c553ba4
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("OAuthResourceServer")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("OAuthResourceServer")]
+[assembly: AssemblyCopyright("Copyright © 2010")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("B6206451-6557-4568-8D25-84AF93EC8B7B")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/OAuth/OAuthResourceServer/Settings.StyleCop b/src/OAuth/OAuthResourceServer/Settings.StyleCop
new file mode 100644
index 0000000..7f55ce6
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Settings.StyleCop
@@ -0,0 +1 @@
+<StyleCopSettings Version="4.3" /> \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/TracePage.aspx b/src/OAuth/OAuthResourceServer/TracePage.aspx
new file mode 100644
index 0000000..c347830
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/TracePage.aspx
@@ -0,0 +1,18 @@
+<%@ Page Language="C#" AutoEventWireup="true" Inherits="OAuthResourceServer.TracePage" Codebehind="TracePage.aspx.cs" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title></title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <p align="right">
+ <asp:Button runat="server" Text="Clear log" ID="clearLogButton" OnClick="clearLogButton_Click" />
+ </p>
+ <pre>
+ <asp:PlaceHolder runat="server" ID="placeHolder1" />
+ </pre>
+ </form>
+</body>
+</html>
diff --git a/src/OAuth/OAuthResourceServer/TracePage.aspx.cs b/src/OAuth/OAuthResourceServer/TracePage.aspx.cs
new file mode 100644
index 0000000..4841c89
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/TracePage.aspx.cs
@@ -0,0 +1,24 @@
+namespace OAuthResourceServer {
+ using System;
+ using System.Collections.Generic;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using Code;
+
+ /// <summary>
+ /// A page to display recent log messages.
+ /// </summary>
+ public partial class TracePage : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ this.placeHolder1.Controls.Add(new Label { Text = HttpUtility.HtmlEncode(Global.LogMessages.ToString()) });
+ }
+
+ protected void clearLogButton_Click(object sender, EventArgs e) {
+ Global.LogMessages.Length = 0;
+
+ // clear the page immediately, and allow for F5 without a Postback warning.
+ Response.Redirect(Request.Url.AbsoluteUri);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/TracePage.aspx.designer.cs b/src/OAuth/OAuthResourceServer/TracePage.aspx.designer.cs
new file mode 100644
index 0000000..58dc5d1
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/TracePage.aspx.designer.cs
@@ -0,0 +1,42 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthResourceServer {
+
+
+ public partial class TracePage {
+
+ /// <summary>
+ /// form1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlForm form1;
+
+ /// <summary>
+ /// clearLogButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button clearLogButton;
+
+ /// <summary>
+ /// placeHolder1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.PlaceHolder placeHolder1;
+ }
+}
diff --git a/src/OAuth/OAuthResourceServer/Web.config b/src/OAuth/OAuthResourceServer/Web.config
new file mode 100644
index 0000000..d5d9d24
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Web.config
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <configSections>
+ <section name="uri" type="System.Configuration.UriSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler" requirePermission="false" />
+ <sectionGroup name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection, DotNetOpenAuth.Core">
+ <section name="openid" type="DotNetOpenAuth.Configuration.OpenIdElement, DotNetOpenAuth.OpenId" requirePermission="false" allowLocation="true" />
+ <section name="oauth" type="DotNetOpenAuth.Configuration.OAuthElement, DotNetOpenAuth.OAuth" requirePermission="false" allowLocation="true" />
+ <section name="messaging" type="DotNetOpenAuth.Configuration.MessagingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" />
+ <section name="reporting" type="DotNetOpenAuth.Configuration.ReportingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" />
+ </sectionGroup>
+ </configSections>
+ <!-- The uri section is necessary to turn on .NET 3.5 support for IDN (international domain names),
+ which is necessary for OpenID urls with unicode characters in the domain/host name.
+ It is also required to put the Uri class into RFC 3986 escaping mode, which OpenID and OAuth require. -->
+ <uri>
+ <idn enabled="All" />
+ <iriParsing enabled="true" />
+ </uri>
+ <system.net>
+ <defaultProxy enabled="true" />
+ <settings>
+ <!-- This setting causes .NET to check certificate revocation lists (CRL)
+ before trusting HTTPS certificates. But this setting tends to not
+ be allowed in shared hosting environments. -->
+ <!--<servicePointManager checkCertificateRevocationList="true"/>-->
+ </settings>
+ </system.net>
+ <!-- this is an optional configuration section where aspects of dotnetopenauth can be customized -->
+ <dotNetOpenAuth>
+ <!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. -->
+ <reporting enabled="true" />
+ <!-- Relaxing SSL requirements is useful for simple samples, but NOT a good idea in production. -->
+ <messaging relaxSslRequirements="true">
+ <untrustedWebRequest>
+ <whitelistHosts>
+ <!-- Uncomment to enable communication with localhost (should generally not activate in production!) -->
+ <!--<add name="localhost" />-->
+ </whitelistHosts>
+ </untrustedWebRequest>
+ </messaging>
+ </dotNetOpenAuth>
+ <appSettings />
+ <connectionStrings>
+ <add name="DatabaseConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True" providerName="System.Data.SqlClient" />
+ </connectionStrings>
+ <system.web>
+ <!--
+ Set compilation debug="true" to insert debugging
+ symbols into the compiled page. Because this
+ affects performance, set this value to true only
+ during development.
+ -->
+ <compilation debug="true" targetFramework="4.0">
+ <assemblies>
+ <remove assembly="DotNetOpenAuth.Contracts" />
+ <add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
+ </assemblies>
+ </compilation>
+ <authentication mode="Forms">
+ <forms name="oauthSP" />
+ </authentication>
+ <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID" />
+ </system.web>
+ <!--
+ The system.webServer section is required for running ASP.NET AJAX under Internet
+ Information Services 7.0. It is not necessary for previous version of IIS.
+ -->
+ <log4net>
+ <appender name="TracePageAppender" type="OAuthResourceServer.Code.TracePageAppender, OAuthResourceServer">
+ <layout type="log4net.Layout.PatternLayout">
+ <conversionPattern value="%date (GMT%date{%z}) [%thread] %-5level %logger - %message%newline" />
+ </layout>
+ </appender>
+ <!-- Setup the root category, add the appenders and set the default level -->
+ <root>
+ <level value="INFO" />
+ <!--<appender-ref ref="RollingFileAppender" />-->
+ <appender-ref ref="TracePageAppender" />
+ </root>
+ <!-- Specify the level for some specific categories -->
+ <logger name="DotNetOpenAuth">
+ <level value="ALL" />
+ </logger>
+ </log4net>
+ <system.serviceModel>
+ <behaviors>
+ <serviceBehaviors>
+ <behavior name="DataApiBehavior">
+ <serviceMetadata httpGetEnabled="true" />
+ <serviceDebug includeExceptionDetailInFaults="true" />
+ <serviceAuthorization serviceAuthorizationManagerType="OAuthResourceServer.Code.OAuthAuthorizationManager, OAuthResourceServer" principalPermissionMode="Custom" />
+ </behavior>
+ </serviceBehaviors>
+ <endpointBehaviors>
+ <behavior name="DataApiWebBehavior">
+ <webHttp />
+ </behavior>
+ </endpointBehaviors>
+ </behaviors>
+ <services>
+ <service behaviorConfiguration="DataApiBehavior" name="OAuthResourceServer.DataApi">
+ <endpoint address="" binding="wsHttpBinding" contract="OAuthResourceServer.Code.IDataApi">
+ <identity>
+ <dns value="localhost" />
+ </identity>
+ </endpoint>
+ <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
+ <endpoint address="web" binding="webHttpBinding" contract="OAuthResourceServer.Code.IDataApi" behaviorConfiguration="DataApiWebBehavior" />
+ </service>
+ </services>
+ </system.serviceModel>
+ <runtime>
+ <!-- This prevents the Windows Event Log from frequently logging that HMAC1 is being used (when the other party needs it). -->
+ <legacyHMACWarning enabled="0" />
+ </runtime>
+</configuration> \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/favicon.ico b/src/OAuth/OAuthResourceServer/favicon.ico
new file mode 100644
index 0000000..e227dbe
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/favicon.ico
Binary files differ
diff --git a/src/OAuth/OAuthResourceServer/packages.config b/src/OAuth/OAuthResourceServer/packages.config
new file mode 100644
index 0000000..e651ea5
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/packages.config
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="CodeContracts.Unofficial" version="1.0.0.2" />
+ <package id="DotNetOpenAuth.Core" version="4.0.0-RC1" />
+ <package id="DotNetOpenAuth.OAuth.Common" version="4.0.0-RC1" />
+ <package id="DotNetOpenAuth.OAuth2.Core" version="0.23.0-draft" />
+ <package id="DotNetOpenAuth.OAuth2.ResourceServer" version="0.23.0-draft" />
+ <package id="log4net" version="2.0.0" />
+</packages> \ No newline at end of file