diff options
Diffstat (limited to 'samples/OAuthServiceProvider/Code')
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 |