summaryrefslogtreecommitdiffstats
path: root/samples/OAuthServiceProvider/Code
diff options
context:
space:
mode:
Diffstat (limited to 'samples/OAuthServiceProvider/Code')
-rw-r--r--samples/OAuthServiceProvider/Code/Global.cs10
-rw-r--r--samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs60
-rw-r--r--samples/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs58
3 files changed, 113 insertions, 15 deletions
diff --git a/samples/OAuthServiceProvider/Code/Global.cs b/samples/OAuthServiceProvider/Code/Global.cs
index ceaeac8..fd7d475 100644
--- a/samples/OAuthServiceProvider/Code/Global.cs
+++ b/samples/OAuthServiceProvider/Code/Global.cs
@@ -5,6 +5,8 @@
using System.Text;
using System.Web;
using DotNetOpenAuth.OAuth.Messages;
+ using DotNetOpenAuth.OAuthWrap;
+ using DotNetOpenAuth.OAuthWrap.Messages;
/// <summary>
/// The web application global events and properties.
@@ -20,6 +22,8 @@
/// </summary>
public static log4net.ILog Logger = log4net.LogManager.GetLogger("DotNetOpenAuth.OAuthServiceProvider");
+ public static WebServerAuthorizationServer AuthorizationServer = new WebServerAuthorizationServer(new OAuth2AuthorizationServer());
+
/// <summary>
/// Gets the transaction-protected database connection for the current request.
/// </summary>
@@ -50,6 +54,12 @@
set { HttpContext.Current.Session["authrequest"] = value; }
}
+ public static WebServerRequest PendingOAuth2Authorization
+ {
+ get { return HttpContext.Current.Session["authrequest"] as WebServerRequest; }
+ set { HttpContext.Current.Session["authrequest"] = value; }
+ }
+
private static DataClassesDataContext dataContextSimple {
get {
if (HttpContext.Current != null) {
diff --git a/samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs b/samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs
new file mode 100644
index 0000000..e281b07
--- /dev/null
+++ b/samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs
@@ -0,0 +1,60 @@
+namespace OAuthServiceProvider.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.OAuth.ChannelElements;
+ using DotNetOpenAuth.OAuthWrap;
+ using DotNetOpenAuth.OAuthWrap.ChannelElements;
+
+ internal class OAuth2AuthorizationServer : IAuthorizationServer {
+ internal static readonly RSAParameters AsymmetricKey;
+
+ 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);
+
+ AsymmetricKey = new RSACryptoServiceProvider().ExportParameters(true);
+ }
+
+ #region Implementation of IAuthorizationServer
+
+ public byte[] Secret {
+ get { return secret; }
+ }
+
+ public DotNetOpenAuth.Messaging.Bindings.INonceStore VerificationCodeNonceStore {
+ get { return this.nonceStore; }
+ }
+
+ public RSAParameters AccessTokenSigningPrivateKey {
+ get { return AsymmetricKey; }
+ }
+
+ public IConsumerDescription GetClient(string clientIdentifier) {
+ var consumerRow = Global.DataContext.OAuthConsumers.SingleOrDefault(
+ consumerCandidate => consumerCandidate.ConsumerKey == clientIdentifier);
+ if (consumerRow == null) {
+ throw new ArgumentOutOfRangeException("clientIdentifier");
+ }
+
+ return consumerRow;
+ }
+
+ #endregion
+
+ public bool IsAuthorizationValid(IAuthorizationDescription authorization) {
+ // We don't support revoking tokens yet.
+ return true;
+ }
+ }
+} \ No newline at end of file
diff --git a/samples/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs b/samples/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs
index 6d5bfff..92038bd 100644
--- a/samples/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs
+++ b/samples/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs
@@ -7,8 +7,9 @@
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Security;
- using DotNetOpenAuth;
using DotNetOpenAuth.OAuth;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+ using DotNetOpenAuth.OAuthWrap;
/// <summary>
/// A WCF extension to authenticate incoming messages using OAuth.
@@ -24,17 +25,14 @@
HttpRequestMessageProperty httpDetails = operationContext.RequestContext.RequestMessage.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
Uri requestUri = operationContext.RequestContext.RequestMessage.Properties["OriginalHttpRequestUri"] as Uri;
- ServiceProvider sp = Constants.CreateServiceProvider();
- try {
- var auth = sp.ReadProtectedResourceAuthorization(httpDetails, requestUri);
- if (auth != null) {
- var accessToken = Global.DataContext.OAuthTokens.Single(token => token.Token == auth.AccessToken);
- var principal = sp.CreatePrincipal(auth);
+ try {
+ var principal = this.VerifyOAuth2(httpDetails, requestUri);
+ if (principal != null) {
var policy = new OAuthPrincipalAuthorizationPolicy(principal);
var policies = new List<IAuthorizationPolicy> {
- policy,
- };
+ policy,
+ };
var securityContext = new ServiceSecurityContext(policies.AsReadOnly());
if (operationContext.IncomingMessageProperties.Security != null) {
@@ -46,14 +44,13 @@
}
securityContext.AuthorizationContext.Properties["Identities"] = new List<IIdentity> {
- principal.Identity,
- };
+ principal.Identity,
+ };
// Only allow this method call if the access token scope permits it.
- string[] scopes = accessToken.Scope.Split('|');
- if (scopes.Contains(operationContext.IncomingMessageHeaders.Action)) {
- return true;
- }
+ return principal.IsInRole(operationContext.IncomingMessageHeaders.Action);
+ } else {
+ return false;
}
} catch (ProtocolException ex) {
Global.Logger.Error("Error processing OAuth messages.", ex);
@@ -61,5 +58,36 @@
return false;
}
+
+ private OAuthPrincipal VerifyOAuth1(HttpRequestMessageProperty httpDetails, Uri requestUri) {
+ ServiceProvider sp = Constants.CreateServiceProvider();
+ var auth = sp.ReadProtectedResourceAuthorization(httpDetails, requestUri);
+ if (auth != null) {
+ var accessToken = Global.DataContext.OAuthTokens.Single(token => token.Token == auth.AccessToken);
+ var principal = sp.CreatePrincipal(auth);
+ return principal;
+ }
+
+ return null;
+ }
+
+ private OAuthPrincipal 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.
+ var resourceServer = new ResourceServer(
+ new StandardAccessTokenAnalyzer(
+ OAuth2AuthorizationServer.AsymmetricKey,
+ OAuth2AuthorizationServer.AsymmetricKey));
+
+ string username, scope;
+ var error = resourceServer.VerifyAccess(new DotNetOpenAuth.Messaging.HttpRequestInfo(httpDetails, requestUri), out username, out scope);
+ if (error == null) {
+ string[] scopes = scope.Split(new char[] { ' ' });
+ var principal = new OAuthPrincipal(username, scopes);
+ return principal;
+ } else {
+ return null;
+ }
+ }
}
} \ No newline at end of file