//----------------------------------------------------------------------- // // Copyright (c) Andrew Arnott. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOAuth { using System; using System.Globalization; using System.Web; using DotNetOAuth.ChannelElements; using DotNetOAuth.Messages; using DotNetOAuth.Messaging; using DotNetOAuth.Messaging.Bindings; using System.Collections.Generic; /// /// A web application that allows access via OAuth. /// /// /// The Service Provider’s documentation should include: /// /// The URLs (Request URLs) the Consumer will use when making OAuth requests, and the HTTP methods (i.e. GET, POST, etc.) used in the Request Token URL and Access Token URL. /// Signature methods supported by the Service Provider. /// Any additional request parameters that the Service Provider requires in order to obtain a Token. Service Provider specific parameters MUST NOT begin with oauth_. /// /// public class ServiceProvider { /// /// Initializes a new instance of the class. /// /// The endpoints and behavior on the Service Provider. /// The host's method of storing and recalling tokens and secrets. internal ServiceProvider(ServiceProviderDescription serviceDescription, ITokenManager tokenManager) { if (serviceDescription == null) { throw new ArgumentNullException("serviceDescription"); } if (tokenManager == null) { throw new ArgumentNullException("tokenManager"); } var signingElement = serviceDescription.CreateTamperProtectionElement(); signingElement.SignatureVerificationCallback = this.TokenSignatureVerificationCallback; INonceStore store = new NonceMemoryStore(StandardExpirationBindingElement.DefaultMaximumMessageAge); this.Description = serviceDescription; this.Channel = new OAuthChannel(signingElement, store, tokenManager, false); this.TokenGenerator = new StandardTokenGenerator(); this.TokenManager = tokenManager; } /// /// Gets the description of this Service Provider. /// public ServiceProviderDescription Description { get; private set; } /// /// Gets or sets the channel to use for sending/receiving messages. /// internal OAuthChannel Channel { get; set; } /// /// Gets or sets the generator responsible for generating new tokens and secrets. /// internal ITokenGenerator TokenGenerator { get; set; } /// /// Gets the persistence store for tokens and secrets. /// internal ITokenManager TokenManager { get; private set; } internal RequestTokenMessage ReadTokenRequest() { return this.Channel.ReadFromRequest(); } internal RequestTokenMessage ReadTokenRequest(HttpRequest request) { return this.ReadTokenRequest(new HttpRequestInfo(request)); } internal RequestTokenMessage ReadTokenRequest(HttpRequestInfo request) { return this.Channel.ReadFromRequest(request); } internal void SendUnauthorizedTokenResponse(RequestTokenMessage request, IDictionary extraParameters) { string token = this.TokenGenerator.GenerateRequestToken(request.ConsumerKey); string secret = this.TokenGenerator.GenerateSecret(); this.TokenManager.StoreNewRequestToken(request.ConsumerKey, token, secret, null/*add params*/); UnauthorizedRequestTokenMessage response = new UnauthorizedRequestTokenMessage { RequestToken = token, TokenSecret = secret, }; response.AddNonOAuthParameters(extraParameters); this.Channel.Send(response); } internal DirectUserToServiceProviderMessage ReadAuthorizationRequest() { return this.Channel.ReadFromRequest(); } internal DirectUserToServiceProviderMessage ReadAuthorizationRequest(HttpRequest request) { return this.ReadAuthorizationRequest(new HttpRequestInfo(request)); } internal DirectUserToServiceProviderMessage ReadAuthorizationRequest(HttpRequestInfo request) { return this.Channel.ReadFromRequest(request); } /// /// /// /// /// The pending user agent redirect based message to be sent as an HttpResponse. internal Response SendAuthorizationResponse(DirectUserToServiceProviderMessage request) { var authorization = new DirectUserToConsumerMessage(request.Callback) { RequestToken = request.RequestToken, }; return this.Channel.Send(authorization); } internal RequestAccessTokenMessage ReadAccessTokenRequest() { return this.Channel.ReadFromRequest(); } internal RequestAccessTokenMessage ReadAccessTokenRequest(HttpRequest request) { return this.ReadAccessTokenRequest(new HttpRequestInfo(request)); } internal RequestAccessTokenMessage ReadAccessTokenRequest(HttpRequestInfo request) { return this.Channel.ReadFromRequest(request); } internal void SendAccessToken(RequestAccessTokenMessage request, IDictionary extraParameters) { if (!this.TokenManager.IsRequestTokenAuthorized(request.RequestToken)) { throw new ProtocolException( string.Format( CultureInfo.CurrentCulture, Strings.AccessTokenNotAuthorized, request.RequestToken)); } string accessToken = this.TokenGenerator.GenerateAccessToken(request.ConsumerKey); string tokenSecret = this.TokenGenerator.GenerateSecret(); this.TokenManager.ExpireRequestTokenAndStoreNewAccessToken(request.ConsumerKey, request.RequestToken, accessToken, tokenSecret); var grantAccess = new GrantAccessTokenMessage { AccessToken = accessToken, TokenSecret = tokenSecret, }; grantAccess.AddNonOAuthParameters(extraParameters); this.Channel.Send(grantAccess); } internal string GetAccessTokenInRequest() { var accessMessage = this.Channel.ReadFromRequest(); if (this.TokenManager.GetTokenType(accessMessage.AccessToken) != TokenType.AccessToken) { throw new ProtocolException( string.Format( CultureInfo.CurrentCulture, Strings.BadAccessTokenInProtectedResourceRequest, accessMessage.AccessToken)); } return accessMessage.AccessToken; } private void TokenSignatureVerificationCallback(ITamperResistantOAuthMessage message) { message.ConsumerSecret = this.TokenManager.GetConsumerSecret(message.ConsumerKey); var tokenMessage = message as ITokenContainingMessage; if (tokenMessage != null) { message.TokenSecret = this.TokenManager.GetTokenSecret(tokenMessage.Token); } } } }