//----------------------------------------------------------------------- // // Copyright (c) Andrew Arnott. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOpenAuth.OAuth2.ChannelElements { using System; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Security.Cryptography; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Bindings; /// /// A short-lived token that accompanies HTTP requests to protected data to authorize the request. /// internal class AccessToken : AuthorizationDataBag { /// /// Initializes a new instance of the class. /// public AccessToken() { } /// /// Initializes a new instance of the class. /// /// The authorization to be described by the access token. /// The lifetime of the access token. internal AccessToken(IAuthorizationDescription authorization, TimeSpan? lifetime) { Requires.NotNull(authorization, "authorization"); this.ClientIdentifier = authorization.ClientIdentifier; this.UtcCreationDate = authorization.UtcIssued; this.User = authorization.User; this.Scope.ResetContents(authorization.Scope); this.Lifetime = lifetime; } /// /// Initializes a new instance of the class. /// /// The client identifier. /// The scopes. /// The username of the account that authorized this token. /// The lifetime for this access token. internal AccessToken(string clientIdentifier, IEnumerable scopes, string username, TimeSpan? lifetime) { Requires.NotNullOrEmpty(clientIdentifier, "clientIdentifier"); this.ClientIdentifier = clientIdentifier; this.Scope.ResetContents(scopes); this.User = username; this.Lifetime = lifetime; this.UtcCreationDate = DateTime.UtcNow; } /// /// Gets or sets the lifetime of the access token. /// /// The lifetime. [MessagePart(Encoder = typeof(TimespanSecondsEncoder))] internal TimeSpan? Lifetime { get; set; } /// /// Creates a formatter capable of serializing/deserializing an access token. /// /// The crypto service provider with the authorization server's private key used to asymmetrically sign the access token. /// The crypto service provider with the resource server's public key used to encrypt the access token. /// An access token serializer. internal static IDataBagFormatter CreateFormatter(RSACryptoServiceProvider signingKey, RSACryptoServiceProvider encryptingKey) { Contract.Requires(signingKey != null || !signingKey.PublicOnly); Contract.Requires(encryptingKey != null); Contract.Ensures(Contract.Result>() != null); return new UriStyleMessageFormatter(signingKey, encryptingKey); } /// /// Checks the message state for conformity to the protocol specification /// and throws an exception if the message is invalid. /// /// /// Some messages have required fields, or combinations of fields that must relate to each other /// in specialized ways. After deserializing a message, this method checks the state of the /// message to see if it conforms to the protocol. /// Note that this property should not check signatures or perform any state checks /// outside this scope of this particular message. /// /// Thrown if the message is invalid. protected override void EnsureValidMessage() { base.EnsureValidMessage(); // Has this token expired? if (this.Lifetime.HasValue) { DateTime expirationDate = this.UtcCreationDate + this.Lifetime.Value; if (expirationDate < DateTime.UtcNow) { throw new ExpiredMessageException(expirationDate, this.ContainingMessage); } } } } }