//----------------------------------------------------------------------- // // Copyright (c) Andrew Arnott. All rights reserved. // //----------------------------------------------------------------------- namespace WebFormsRelyingParty.Code { using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography.X509Certificates; using System.Web; using DotNetOpenAuth.OAuth; using DotNetOpenAuth.OAuth.ChannelElements; using DotNetOpenAuth.OAuth.Messages; /// /// The token manager this web site uses in its roles both as /// a consumer and as a service provider. /// public class OAuthTokenManager : ITokenManager { /// /// Initializes a new instance of the class. /// protected OAuthTokenManager() { } #region ITokenManager Members /// /// Gets the Token Secret given a request or access token. /// /// The request or access token. /// /// The secret associated with the given token. /// /// Thrown if the secret cannot be found for the given token. public string GetTokenSecret(string token) { try { return Global.DataContext.IssuedToken.First(t => t.Token == token).TokenSecret; } catch (InvalidOperationException) { throw new ArgumentOutOfRangeException(); } } /// /// Stores a newly generated unauthorized request token, secret, and optional /// application-specific parameters for later recall. /// /// The request message that resulted in the generation of a new unauthorized request token. /// The response message that includes the unauthorized request token. /// Thrown if the consumer key is not registered, or a required parameter was not found in the parameters collection. /// /// Request tokens stored by this method SHOULD NOT associate any user account with this token. /// It usually opens up security holes in your application to do so. Instead, you associate a user /// account with access tokens (not request tokens) in the /// method. /// public void StoreNewRequestToken(UnauthorizedTokenRequest request, ITokenSecretContainingMessage response) { Consumer consumer; try { consumer = Global.DataContext.Consumer.First(c => c.ConsumerKey == request.ConsumerKey); } catch (InvalidOperationException) { throw new ArgumentOutOfRangeException(); } var token = new IssuedRequestToken { Callback = request.Callback, Consumer = consumer, CreatedOn = DateTime.Now, Token = response.Token, TokenSecret = response.TokenSecret, }; string scope; if (request.ExtraData.TryGetValue("scope", out scope)) { token.Scope = scope; } Global.DataContext.AddToIssuedToken(token); Global.DataContext.SaveChanges(); } /// /// Deletes a request token and its associated secret and stores a new access token and secret. /// /// The Consumer that is exchanging its request token for an access token. /// The Consumer's request token that should be deleted/expired. /// The new access token that is being issued to the Consumer. /// The secret associated with the newly issued access token. /// /// /// Any scope of granted privileges associated with the request token from the /// original call to should be carried over /// to the new Access Token. /// /// /// To associate a user account with the new access token, /// HttpContext.Current.User may be /// useful in an ASP.NET web application within the implementation of this method. /// Alternatively you may store the access token here without associating with a user account, /// and wait until or /// return the access /// token to associate the access token with a user account at that point. /// /// public void ExpireRequestTokenAndStoreNewAccessToken(string consumerKey, string requestToken, string accessToken, string accessTokenSecret) { var requestTokenEntity = Global.DataContext.IssuedToken.OfType().First( t => t.Consumer.ConsumerKey == consumerKey && t.Token == requestToken); var accessTokenEntity = new IssuedAccessToken { Token = accessToken, TokenSecret = accessTokenSecret, ExpirationDate = null, // currently, our access tokens don't expire CreatedOn = DateTime.Now, User = requestTokenEntity.User, Scope = requestTokenEntity.Scope, }; Global.DataContext.DeleteObject(requestTokenEntity); Global.DataContext.AddToIssuedToken(accessTokenEntity); Global.DataContext.SaveChanges(); } /// /// Classifies a token as a request token or an access token. /// /// The token to classify. /// /// Request or Access token, or invalid if the token is not recognized. /// public TokenType GetTokenType(string token) { IssuedToken tok = Global.DataContext.IssuedToken.FirstOrDefault(t => t.Token == token); if (tok == null) { return TokenType.InvalidToken; } else { return tok is IssuedAccessToken ? TokenType.AccessToken : TokenType.RequestToken; } } #endregion } }