/// <summary> /// Prepares a message for sending based on the rules of this channel binding element. /// </summary> /// <param name="message">The message to prepare for sending.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// The protections (if any) that this binding element applied to the message. /// Null if this binding element did not even apply to this binding element. /// </returns> /// <remarks> /// Implementations that provide message protection must honor the /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable. /// </remarks> public override Task<MessageProtections?> ProcessOutgoingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) { var directResponse = message as IDirectResponseProtocolMessage; var request = directResponse != null ? directResponse.OriginatingRequest as IAccessTokenRequestInternal : null; // Serialize the authorization code, if there is one. var authCodeCarrier = message as IAuthorizationCodeCarryingRequest; if (authCodeCarrier != null) { var codeFormatter = AuthorizationCode.CreateFormatter(this.AuthorizationServer); var code = authCodeCarrier.AuthorizationDescription; authCodeCarrier.Code = codeFormatter.Serialize(code); return MessageProtectionTasks.None; } // Serialize the refresh token, if applicable. var refreshTokenResponse = message as AccessTokenSuccessResponse; if (refreshTokenResponse != null && refreshTokenResponse.HasRefreshToken) { var refreshTokenCarrier = (IAuthorizationCarryingRequest)message; var refreshToken = new RefreshToken(refreshTokenCarrier.AuthorizationDescription); var refreshTokenFormatter = RefreshToken.CreateFormatter(this.AuthorizationServer.CryptoKeyStore); refreshTokenResponse.RefreshToken = refreshTokenFormatter.Serialize(refreshToken); } // Serialize the access token, if applicable. var accessTokenResponse = message as IAccessTokenIssuingResponse; if (accessTokenResponse != null && accessTokenResponse.AuthorizationDescription != null) { ErrorUtilities.VerifyInternal(request != null, "We should always have a direct request message for this case."); accessTokenResponse.AccessToken = accessTokenResponse.AuthorizationDescription.Serialize(); } return MessageProtectionTasks.Null; }
/// <summary> /// Prepares a message for sending based on the rules of this channel binding element. /// </summary> /// <param name="message">The message to prepare for sending.</param> /// <returns> /// The protections (if any) that this binding element applied to the message. /// Null if this binding element did not even apply to this binding element. /// </returns> public override MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) { var directResponse = message as IDirectResponseProtocolMessage; IAccessTokenRequest request = directResponse != null ? directResponse.OriginatingRequest as IAccessTokenRequest : null; var implicitGrantResponse = message as EndUserAuthorizationSuccessAccessTokenResponse; if (implicitGrantResponse != null) { IAuthorizationCarryingRequest tokenCarryingResponse = implicitGrantResponse; tokenCarryingResponse.AuthorizationDescription = new AccessToken(request.ClientIdentifier, implicitGrantResponse.Scope, implicitGrantResponse.AuthorizingUsername, implicitGrantResponse.Lifetime); return MessageProtections.None; } var accessTokenResponse = message as AccessTokenSuccessResponse; if (accessTokenResponse != null) { var authCarryingRequest = (IAuthorizationCarryingRequest)request; var accessToken = new AccessToken(authCarryingRequest.AuthorizationDescription, accessTokenResponse.Lifetime); using (var resourceServerEncryptionKey = this.AuthorizationServer.GetResourceServerEncryptionKey(request)) { var accessTokenFormatter = AccessToken.CreateFormatter(this.AuthorizationServer.AccessTokenSigningKey, resourceServerEncryptionKey); accessTokenResponse.AccessToken = accessTokenFormatter.Serialize(accessToken); } if (accessTokenResponse.HasRefreshToken) { var refreshToken = new RefreshToken(authCarryingRequest.AuthorizationDescription); var refreshTokenFormatter = RefreshToken.CreateFormatter(this.AuthorizationServer.CryptoKeyStore); accessTokenResponse.RefreshToken = refreshTokenFormatter.Serialize(refreshToken); } } return null; }
/// <summary> /// Decodes a refresh token into its authorization details. /// </summary> /// <param name="refreshToken">The encoded refresh token as it would appear to the client.</param> /// <returns>A description of the authorization represented by the refresh token.</returns> /// <exception cref="ProtocolException">Thrown if the refresh token is not valid due to expiration, corruption or not being authentic.</exception> /// <remarks> /// This can be useful if the authorization server supports the client revoking its own access (on uninstall, for example). /// Outside the scope of the OAuth 2 spec, the client may contact the authorization server host requesting that its refresh /// token be revoked. The authorization server would need to decode the refresh token so it knows which authorization in /// the database to delete. /// </remarks> public IAuthorizationDescription DecodeRefreshToken(string refreshToken) { var refreshTokenFormatter = RefreshToken.CreateFormatter(this.AuthorizationServerServices.CryptoKeyStore); var token = new RefreshToken(); refreshTokenFormatter.Deserialize(token, refreshToken); return token; }
public override Task<MessageProtections?> ProcessIncomingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) { var authCodeCarrier = message as IAuthorizationCodeCarryingRequest; if (authCodeCarrier != null) { var authorizationCodeFormatter = AuthorizationCode.CreateFormatter(this.AuthorizationServer); var authorizationCode = new AuthorizationCode(); authorizationCodeFormatter.Deserialize(authorizationCode, authCodeCarrier.Code, message, Protocol.code); authCodeCarrier.AuthorizationDescription = authorizationCode; } var refreshTokenCarrier = message as IRefreshTokenCarryingRequest; if (refreshTokenCarrier != null) { var refreshTokenFormatter = RefreshToken.CreateFormatter(this.AuthorizationServer.CryptoKeyStore); var refreshToken = new RefreshToken(); refreshTokenFormatter.Deserialize(refreshToken, refreshTokenCarrier.RefreshToken, message, Protocol.refresh_token); refreshTokenCarrier.AuthorizationDescription = refreshToken; } return MessageProtectionTasks.Null; }
/// <summary> /// Prepares the response to an access token request. /// </summary> /// <param name="request">The request for an access token.</param> /// <param name="accessTokenEncryptingPublicKey">The crypto service provider with the public key to encrypt the access token to, such that the resource server will be able to decrypt it.</param> /// <param name="accessTokenLifetime">The access token's lifetime.</param> /// <param name="includeRefreshToken">If set to <c>true</c>, the response will include a long-lived refresh token.</param> /// <returns>The response message to send to the client.</returns> public virtual IDirectResponseProtocolMessage PrepareAccessTokenResponse(AccessTokenRequestBase request, RSACryptoServiceProvider accessTokenEncryptingPublicKey, TimeSpan? accessTokenLifetime = null, bool includeRefreshToken = true) { Contract.Requires<ArgumentNullException>(request != null); Contract.Requires<ArgumentNullException>(accessTokenEncryptingPublicKey != null); var tokenRequest = (IAuthorizationCarryingRequest)request; using (var crypto = this.AuthorizationServerServices.CreateAccessTokenSigningCryptoServiceProvider()) { var accessTokenFormatter = AccessToken.CreateFormatter(crypto, accessTokenEncryptingPublicKey); var accessToken = new AccessToken(tokenRequest.AuthorizationDescription, accessTokenLifetime); var response = new AccessTokenSuccessResponse(request) { AccessToken = accessTokenFormatter.Serialize(accessToken), Lifetime = accessToken.Lifetime, }; response.Scope.ResetContents(tokenRequest.AuthorizationDescription.Scope); if (includeRefreshToken) { var refreshTokenFormatter = RefreshToken.CreateFormatter(this.AuthorizationServerServices.CryptoKeyStore); var refreshToken = new RefreshToken(tokenRequest.AuthorizationDescription); response.RefreshToken = refreshTokenFormatter.Serialize(refreshToken); } return response; } }