Example #1
0
        /// <summary>
        /// Prepares a request for user authorization from an authorization server.
        /// </summary>
        /// <param name="authorization">The authorization state to associate with this particular request.</param>
        /// <returns>The authorization request.</returns>
        public OutgoingWebResponse PrepareRequestUserAuthorization(IAuthorizationState authorization)
        {
            if (authorization.Callback == null)
            {
                authorization.Callback = this.Channel.GetRequestFromContext().GetPublicFacingUrl()
                                         .StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(typeof(EndUserAuthorizationSuccessResponseBase), Protocol.Default.Version))
                                         .StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(typeof(EndUserAuthorizationFailedResponse), Protocol.Default.Version));
                authorization.SaveChanges();
            }

            var request = new EndUserAuthorizationRequestC(this.AuthorizationServer)
            {
                ClientIdentifier = this.ClientIdentifier,
                Callback         = authorization.Callback,
            };

            request.Scope.ResetContents(authorization.Scope);

            // Mitigate XSRF attacks by including a state value that would be unpredictable between users, but
            // verifiable for the same user/session.
            // If the host is implementing the authorization tracker though, they're handling this protection themselves.
            if (this.AuthorizationTracker == null)
            {
                var context = this.Channel.GetHttpContext();
                if (context.Session != null)
                {
                    request.ClientState = context.Session.SessionID;
                }
                else
                {
                }
            }

            return(this.Channel.PrepareResponse(request));
        }
        /// <summary>
        /// Updates the authorization state maintained by the client with the content of an outgoing response.
        /// </summary>
        /// <param name="authorizationState">The authorization state maintained by the client.</param>
        /// <param name="accessTokenSuccess">The access token containing response message.</param>
        internal static void UpdateAuthorizationWithResponse(IAuthorizationState authorizationState, AccessTokenSuccessResponse accessTokenSuccess)
        {
            Requires.NotNull(authorizationState, "authorizationState");
            Requires.NotNull(accessTokenSuccess, "accessTokenSuccess");

            authorizationState.AccessToken = accessTokenSuccess.AccessToken;
            authorizationState.AccessTokenExpirationUtc = DateTime.UtcNow + accessTokenSuccess.Lifetime;
            authorizationState.AccessTokenIssueDateUtc  = DateTime.UtcNow;

            // The authorization server MAY choose to renew the refresh token itself.
            if (accessTokenSuccess.RefreshToken != null)
            {
                authorizationState.RefreshToken = accessTokenSuccess.RefreshToken;
            }

            // An included scope parameter in the response only describes the access token's scope.
            // Don't update the whole authorization state object with that scope because that represents
            // the refresh token's original scope.
            if ((authorizationState.Scope == null || authorizationState.Scope.Count == 0) && accessTokenSuccess.Scope != null)
            {
                authorizationState.Scope.ResetContents(accessTokenSuccess.Scope);
            }

            authorizationState.SaveChanges();
        }
		/// <summary>
		/// Prepares a request for user authorization from an authorization server.
		/// </summary>
		/// <param name="authorization">The authorization state to associate with this particular request.</param>
		/// <returns>The authorization request.</returns>
		public OutgoingWebResponse PrepareRequestUserAuthorization(IAuthorizationState authorization) {
			Requires.NotNull(authorization, "authorization");
			Requires.ValidState(authorization.Callback != null || (HttpContext.Current != null && HttpContext.Current.Request != null), MessagingStrings.HttpContextRequired);
			Requires.ValidState(!string.IsNullOrEmpty(this.ClientIdentifier), OAuth2Strings.RequiredPropertyNotYetPreset, "ClientIdentifier");
			Contract.Ensures(Contract.Result<OutgoingWebResponse>() != null);

			if (authorization.Callback == null) {
				authorization.Callback = this.Channel.GetRequestFromContext().GetPublicFacingUrl()
					.StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(typeof(EndUserAuthorizationSuccessResponseBase), Protocol.Default.Version))
					.StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(typeof(EndUserAuthorizationFailedResponse), Protocol.Default.Version));
				authorization.SaveChanges();
			}

			var request = new EndUserAuthorizationRequest(this.AuthorizationServer) {
				ClientIdentifier = this.ClientIdentifier,
				Callback = authorization.Callback,
			};
			request.Scope.ResetContents(authorization.Scope);

			// Mitigate XSRF attacks by including a state value that would be unpredictable between users, but
			// verifiable for the same user/session.
			// If the host is implementing the authorization tracker though, they're handling this protection themselves.
			if (this.AuthorizationTracker == null) {
				var context = this.Channel.GetHttpContext();
				if (context.Session != null) {
					request.ClientState = context.Session.SessionID;
				} else {
					Logger.OAuth.WarnFormat("No request context discovered, so no client state parameter could be set to mitigate XSRF attacks.");
				}
			}

			return this.Channel.PrepareResponse(request);
		}
        /// <summary>
        /// Prepares a request for user authorization from an authorization server.
        /// </summary>
        /// <param name="authorization">The authorization state to associate with this particular request.</param>
        /// <returns>The authorization request.</returns>
        public OutgoingWebResponse PrepareRequestUserAuthorization(IAuthorizationState authorization)
        {
            Requires.NotNull(authorization, "authorization");
            RequiresEx.ValidState(authorization.Callback != null || (HttpContext.Current != null && HttpContext.Current.Request != null), MessagingStrings.HttpContextRequired);
            RequiresEx.ValidState(!string.IsNullOrEmpty(this.ClientIdentifier), Strings.RequiredPropertyNotYetPreset, "ClientIdentifier");

            if (authorization.Callback == null)
            {
                authorization.Callback = this.Channel.GetRequestFromContext().GetPublicFacingUrl()
                                         .StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(typeof(EndUserAuthorizationSuccessResponseBase), Protocol.Default.Version))
                                         .StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(typeof(EndUserAuthorizationFailedResponse), Protocol.Default.Version));
                authorization.SaveChanges();
            }

            var request = new EndUserAuthorizationRequestC(this.AuthorizationServer)
            {
                ClientIdentifier = this.ClientIdentifier,
                Callback         = authorization.Callback,
            };

            request.Scope.ResetContents(authorization.Scope);

            // Mitigate XSRF attacks by including a state value that would be unpredictable between users, but
            // verifiable for the same user/session.
            // If the host is implementing the authorization tracker though, they're handling this protection themselves.
            HttpCookie cookie = null;

            if (this.AuthorizationTracker == null)
            {
                var context = this.Channel.GetHttpContext();

                string xsrfKey = MessagingUtilities.GetNonCryptoRandomDataAsBase64(16);
                cookie = new HttpCookie(XsrfCookieName, xsrfKey)
                {
                    HttpOnly = true,
                    Secure   = FormsAuthentication.RequireSSL,
                    ////Expires = DateTime.Now.Add(OAuth2ClientSection.Configuration.MaxAuthorizationTime), // we prefer session cookies to persistent ones
                };
                request.ClientState = xsrfKey;
            }

            var response = this.Channel.PrepareResponse(request);

            if (cookie != null)
            {
                response.Cookies.Add(cookie);
            }

            return(response);
        }
Example #5
0
        public static void UpdateAuthorizationWithResponse(IAuthorizationState authorizationState, AccessTokenSuccessResponse accessTokenSuccess)
        {
            authorizationState.AccessToken = accessTokenSuccess.AccessToken;
            authorizationState.AccessTokenExpirationUtc = DateTime.UtcNow + accessTokenSuccess.Lifetime;
            authorizationState.AccessTokenIssueDateUtc  = DateTime.UtcNow;
            if (accessTokenSuccess.RefreshToken != null)
            {
                authorizationState.RefreshToken = accessTokenSuccess.RefreshToken;
            }
            if ((authorizationState.Scope == null || authorizationState.Scope.Count == 0) && accessTokenSuccess.Scope != null)
            {
                authorizationState.Scope.ResetContents(accessTokenSuccess.Scope);
            }

            authorizationState.SaveChanges();
        }
Example #6
0
        /// <summary>
        /// Updates the authorization state maintained by the client with the content of an outgoing response.
        /// </summary>
        /// <param name="authorizationState">The authorization state maintained by the client.</param>
        /// <param name="accessTokenSuccess">The access token containing response message.</param>
        internal static void UpdateAuthorizationWithResponse(IAuthorizationState authorizationState, EndUserAuthorizationSuccessAccessTokenResponse accessTokenSuccess)
        {
            authorizationState.AccessToken = accessTokenSuccess.AccessToken;
            authorizationState.AccessTokenExpirationUtc = DateTime.UtcNow + accessTokenSuccess.Lifetime;
            authorizationState.AccessTokenIssueDateUtc  = DateTime.UtcNow;
            if (accessTokenSuccess.Scope != null && accessTokenSuccess.Scope != authorizationState.Scope)
            {
                if (authorizationState.Scope != null)
                {
                }

                authorizationState.Scope.ResetContents(accessTokenSuccess.Scope);
            }

            authorizationState.SaveChanges();
        }
Example #7
0
 public static void UpdateAuthorizationWithResponse(IAuthorizationState authorizationState, EndUserAuthorizationSuccessAccessTokenResponse accessTokenSuccess)
 {
     authorizationState.AccessToken = accessTokenSuccess.AccessToken;
     authorizationState.AccessTokenExpirationUtc = DateTime.UtcNow + accessTokenSuccess.Lifetime;
     authorizationState.AccessTokenIssueDateUtc  = DateTime.UtcNow;
     if (accessTokenSuccess.Scope != null && accessTokenSuccess.Scope != authorizationState.Scope)
     {
         if (authorizationState.Scope != null)
         {
             Logger.OAuth.InfoFormat(
                 "Requested scope of \"{0}\" changed to \"{1}\" by authorization server.",
                 authorizationState.Scope,
                 accessTokenSuccess.Scope);
         }
         authorizationState.Scope.ResetContents(accessTokenSuccess.Scope);
     }
     authorizationState.SaveChanges();
 }
Example #8
0
        /// <summary>
        /// Prepares a request for user authorization from an authorization server.
        /// </summary>
        /// <param name="authorization">The authorization state to associate with this particular request.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>
        /// The authorization request.
        /// </returns>
        public async Task <HttpResponseMessage> PrepareRequestUserAuthorizationAsync(IAuthorizationState authorization, CancellationToken cancellationToken = default(CancellationToken))
        {
            Requires.NotNull(authorization, "authorization");
            RequiresEx.ValidState(authorization.Callback != null || (HttpContext.Current != null && HttpContext.Current.Request != null), MessagingStrings.HttpContextRequired);
            RequiresEx.ValidState(!string.IsNullOrEmpty(this.ClientIdentifier), Strings.RequiredPropertyNotYetPreset, "ClientIdentifier");

            if (authorization.Callback == null)
            {
                authorization.Callback = this.Channel.GetRequestFromContext().GetPublicFacingUrl()
                                         .StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(typeof(EndUserAuthorizationSuccessResponseBase), Protocol.Default.Version))
                                         .StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(typeof(EndUserAuthorizationFailedResponse), Protocol.Default.Version));
                authorization.SaveChanges();
            }

            var request = new EndUserAuthorizationRequestC(this.AuthorizationServer)
            {
                ClientIdentifier = this.ClientIdentifier,
                Callback         = authorization.Callback,
            };

            request.Scope.ResetContents(authorization.Scope);

            // Mitigate XSRF attacks by including a state value that would be unpredictable between users, but
            // verifiable for the same user/session.
            // If the host is implementing the authorization tracker though, they're handling this protection themselves.
            var cookies = new List <CookieHeaderValue>();

            if (this.AuthorizationTracker == null)
            {
                string xsrfKey = MessagingUtilities.GetNonCryptoRandomDataAsBase64(16, useWeb64: true);
                cookies.Add(new CookieHeaderValue(XsrfCookieName, xsrfKey)
                {
                    HttpOnly = true,
                    Secure   = FormsAuthentication.RequireSSL,
                });
                request.ClientState = xsrfKey;
            }

            var response = await this.Channel.PrepareResponseAsync(request, cancellationToken);

            response.Headers.AddCookies(cookies);

            return(response);
        }
Example #9
0
        /// <summary>
        /// Prepares a request for user authorization from an authorization server.
        /// </summary>
        /// <param name="authorization">The authorization state to associate with this particular request.</param>
        /// <returns>The authorization request.</returns>
        public OutgoingWebResponse PrepareRequestUserAuthorization(IAuthorizationState authorization)
        {
            Requires.NotNull(authorization, "authorization");
            Requires.ValidState(authorization.Callback != null || (HttpContext.Current != null && HttpContext.Current.Request != null), MessagingStrings.HttpContextRequired);
            Requires.ValidState(!string.IsNullOrEmpty(this.ClientIdentifier), Strings.RequiredPropertyNotYetPreset, "ClientIdentifier");
            Contract.Ensures(Contract.Result <OutgoingWebResponse>() != null);

            if (authorization.Callback == null)
            {
                authorization.Callback = this.Channel.GetRequestFromContext().GetPublicFacingUrl()
                                         .StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(typeof(EndUserAuthorizationSuccessResponseBase), Protocol.Default.Version))
                                         .StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(typeof(EndUserAuthorizationFailedResponse), Protocol.Default.Version));
                authorization.SaveChanges();
            }

            var request = new EndUserAuthorizationRequestC(this.AuthorizationServer)
            {
                ClientIdentifier = this.ClientIdentifier,
                Callback         = authorization.Callback,
            };

            request.Scope.ResetContents(authorization.Scope);

            // Mitigate XSRF attacks by including a state value that would be unpredictable between users, but
            // verifiable for the same user/session.
            // If the host is implementing the authorization tracker though, they're handling this protection themselves.
            if (this.AuthorizationTracker == null)
            {
                var context = this.Channel.GetHttpContext();
                if (context.Session != null)
                {
                    request.ClientState = context.Session.SessionID;
                }
                else
                {
                    Logger.OAuth.WarnFormat("No request context discovered, so no client state parameter could be set to mitigate XSRF attacks.");
                }
            }

            return(this.Channel.PrepareResponse(request));
        }
        public bool RefreshToken(IAuthorizationState authorization, TimeSpan?skipIfUsefulLifeExceeds,
                                 Func <IDirectedProtocolMessage, IProtocolMessage> requestProvider)
        {
            authorization.ThrowIfNull("authorization");
            Certificate.ThrowIfNull("certificate");
            bool result = false;

            // Check if the token is still valid.
            if (skipIfUsefulLifeExceeds.HasValue && authorization.AccessTokenExpirationUtc.HasValue)
            {
                TimeSpan timeSpan = authorization.AccessTokenExpirationUtc.Value - DateTime.UtcNow;
                if (timeSpan > skipIfUsefulLifeExceeds.Value)
                {
                    return(result);
                }
            }

            var requestMessage = GenerateMessage();
            var response       = requestProvider(requestMessage);

            // Response is not strongly-typed to an AccessTokenSuccessResponse because DotNetOpenAuth can't infer the
            // type from the request message type. The only way to get access to the result data is through the
            // resulting Dictionary.
            if (response.ExtraData.ContainsKey("access_token") && response.ExtraData.ContainsKey("expires_in"))
            {
                result = true;
                authorization.AccessToken = response.ExtraData["access_token"];
                long     expiresIn = long.Parse(response.ExtraData["expires_in"]);
                DateTime utcNow    = DateTime.UtcNow;
                authorization.AccessTokenExpirationUtc = new DateTime? (utcNow.AddSeconds(expiresIn));
                authorization.AccessTokenIssueDateUtc  = new DateTime? (utcNow);
                authorization.SaveChanges();
            }
            else
            {
                result = false;
            }
            return(result);
        }
Example #11
0
		/// <summary>
		/// Prepares a request for user authorization from an authorization server.
		/// </summary>
		/// <param name="authorization">The authorization state to associate with this particular request.</param>
		/// <param name="state">The state of the client that should be sent back with the authorization response.</param>
		/// <returns>The authorization request.</returns>
		public OutgoingWebResponse PrepareRequestUserAuthorization(IAuthorizationState authorization, string state = null) {
			Contract.Requires<ArgumentNullException>(authorization != null);
			Contract.Requires<InvalidOperationException>(authorization.Callback != null || (HttpContext.Current != null && HttpContext.Current.Request != null), MessagingStrings.HttpContextRequired);
			Contract.Requires<InvalidOperationException>(!string.IsNullOrEmpty(this.ClientIdentifier));
			Contract.Ensures(Contract.Result<OutgoingWebResponse>() != null);

			if (authorization.Callback == null) {
				authorization.Callback = this.Channel.GetRequestFromContext().UrlBeforeRewriting
					.StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(typeof(EndUserAuthorizationSuccessResponseBase), Protocol.Default.Version))
					.StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(typeof(EndUserAuthorizationFailedResponse), Protocol.Default.Version));
				authorization.SaveChanges();
			}

			var request = new EndUserAuthorizationRequest(this.AuthorizationServer) {
				ClientIdentifier = this.ClientIdentifier,
				Callback = authorization.Callback,
				ClientState = state,
			};
			request.Scope.ResetContents(authorization.Scope);

			return this.Channel.PrepareResponse(request);
		}
Example #12
0
        /// <summary>
        /// 用户授权请求
        /// </summary>
        /// <param name="authorization">授权状态</param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public HttpResponseMessage PrepareRequestUserAuthorizationAsync(IAuthorizationState authorization, CancellationToken cancellationToken = default(CancellationToken))
        {
            // 设置回调地址
            if (authorization.Callback == null)
            {
                authorization.Callback = this.Channel.GetRequestFromContext().GetPublicFacingUrl()
                                         .StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(typeof(EndUserAuthorizationSuccessResponseBase), Protocol.Default.Version))
                                         .StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(typeof(EndUserAuthorizationFailedResponse), Protocol.Default.Version));
                authorization.SaveChanges();
            }

            //授权请求
            var request = new EndUserAuthorizationRequestC(this.AuthorizationServer)
            {
                ClientIdentifier = this.ClientIdentifier,
                Callback         = authorization.Callback
            };

            request.Scope.ResetContents(authorization.Scope);
            var cookies = new List <CookieHeaderValue>();

            if (this.AuthorizationTracker == null)
            {
                string xsrfKey = MessagingUtilities.GetNonCryptoRandomDataAsBase64(16, useWeb64: true);
                cookies.Add(new CookieHeaderValue(XsrfCookieName, xsrfKey)
                {
                    HttpOnly = true,
                    Secure   = FormsAuthentication.RequireSSL,
                });
                request.ClientState = xsrfKey;
            }
            var response = this.Channel.PrepareResponseAsync(request, cancellationToken);

            response.Headers.AddCookies(cookies);

            return(response);
        }
Example #13
0
		/// <summary>
		/// Updates the authorization state maintained by the client with the content of an outgoing response.
		/// </summary>
		/// <param name="authorizationState">The authorization state maintained by the client.</param>
		/// <param name="accessTokenSuccess">The access token containing response message.</param>
		internal static void UpdateAuthorizationWithResponse(IAuthorizationState authorizationState, EndUserAuthorizationSuccessAccessTokenResponse accessTokenSuccess) {
			Requires.NotNull(authorizationState, "authorizationState");
			Requires.NotNull(accessTokenSuccess, "accessTokenSuccess");

			authorizationState.AccessToken = accessTokenSuccess.AccessToken;
			authorizationState.AccessTokenExpirationUtc = DateTime.UtcNow + accessTokenSuccess.Lifetime;
			authorizationState.AccessTokenIssueDateUtc = DateTime.UtcNow;
			if (accessTokenSuccess.Scope != null && accessTokenSuccess.Scope != authorizationState.Scope) {
				if (authorizationState.Scope != null) {
					Logger.OAuth.InfoFormat(
										   "Requested scope of \"{0}\" changed to \"{1}\" by authorization server.",
										   authorizationState.Scope,
										   accessTokenSuccess.Scope);
				}

				authorizationState.Scope.ResetContents(accessTokenSuccess.Scope);
			}

			authorizationState.SaveChanges();
		}
Example #14
0
		/// <summary>
		/// Updates the authorization state maintained by the client with the content of an outgoing response.
		/// </summary>
		/// <param name="authorizationState">The authorization state maintained by the client.</param>
		/// <param name="accessTokenSuccess">The access token containing response message.</param>
		internal static void UpdateAuthorizationWithResponse(IAuthorizationState authorizationState, AccessTokenSuccessResponse accessTokenSuccess) {
			Requires.NotNull(authorizationState, "authorizationState");
			Requires.NotNull(accessTokenSuccess, "accessTokenSuccess");

			authorizationState.ExtraData = accessTokenSuccess.ExtraData;
			authorizationState.AccessToken = accessTokenSuccess.AccessToken;
			authorizationState.AccessTokenExpirationUtc = DateTime.UtcNow + accessTokenSuccess.Lifetime;
			authorizationState.AccessTokenIssueDateUtc = DateTime.UtcNow;

			// The authorization server MAY choose to renew the refresh token itself.
			if (accessTokenSuccess.RefreshToken != null) {
				authorizationState.RefreshToken = accessTokenSuccess.RefreshToken;
			}

			// An included scope parameter in the response only describes the access token's scope.
			// Don't update the whole authorization state object with that scope because that represents
			// the refresh token's original scope.
			if ((authorizationState.Scope == null || authorizationState.Scope.Count == 0) && accessTokenSuccess.Scope != null) {
				authorizationState.Scope.ResetContents(accessTokenSuccess.Scope);
			}

			authorizationState.SaveChanges();
		}
Example #15
0
		/// <summary>
		/// Prepares a request for user authorization from an authorization server.
		/// </summary>
		/// <param name="authorization">The authorization state to associate with this particular request.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <returns>
		/// The authorization request.
		/// </returns>
		public async Task<HttpResponseMessage> PrepareRequestUserAuthorizationAsync(IAuthorizationState authorization, CancellationToken cancellationToken = default(CancellationToken)) {
			Requires.NotNull(authorization, "authorization");
			RequiresEx.ValidState(authorization.Callback != null || (HttpContext.Current != null && HttpContext.Current.Request != null), MessagingStrings.HttpContextRequired);
			RequiresEx.ValidState(!string.IsNullOrEmpty(this.ClientIdentifier), Strings.RequiredPropertyNotYetPreset, "ClientIdentifier");

			if (authorization.Callback == null) {
				authorization.Callback = this.Channel.GetRequestFromContext().GetPublicFacingUrl()
					.StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(typeof(EndUserAuthorizationSuccessResponseBase), Protocol.Default.Version))
					.StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(typeof(EndUserAuthorizationFailedResponse), Protocol.Default.Version));
				authorization.SaveChanges();
			}

			var request = new EndUserAuthorizationRequestC(this.AuthorizationServer) {
				ClientIdentifier = this.ClientIdentifier,
				Callback = authorization.Callback,
			};
			request.Scope.ResetContents(authorization.Scope);

			// Mitigate XSRF attacks by including a state value that would be unpredictable between users, but
			// verifiable for the same user/session.
			// If the host is implementing the authorization tracker though, they're handling this protection themselves.
			var cookies = new List<CookieHeaderValue>();
			if (this.AuthorizationTracker == null) {
				string xsrfKey = MessagingUtilities.GetNonCryptoRandomDataAsBase64(16, useWeb64: true);
				cookies.Add(new CookieHeaderValue(XsrfCookieName, xsrfKey) {
					HttpOnly = true,
					Secure = FormsAuthentication.RequireSSL,
				});
				request.ClientState = xsrfKey;
			}

			var response = await this.Channel.PrepareResponseAsync(request, cancellationToken);
			response.Headers.AddCookies(cookies);

			return response;
		}
		/// <summary>
		/// Prepares a request for user authorization from an authorization server.
		/// </summary>
		/// <param name="authorization">The authorization state to associate with this particular request.</param>
		/// <returns>The authorization request.</returns>
		public OutgoingWebResponse PrepareRequestUserAuthorization(IAuthorizationState authorization) {
			Requires.NotNull(authorization, "authorization");
			RequiresEx.ValidState(authorization.Callback != null || (HttpContext.Current != null && HttpContext.Current.Request != null), MessagingStrings.HttpContextRequired);
			RequiresEx.ValidState(!string.IsNullOrEmpty(this.ClientIdentifier), Strings.RequiredPropertyNotYetPreset, "ClientIdentifier");

			if (authorization.Callback == null) {
				authorization.Callback = this.Channel.GetRequestFromContext().GetPublicFacingUrl()
					.StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(typeof(EndUserAuthorizationSuccessResponseBase), Protocol.Default.Version))
					.StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(typeof(EndUserAuthorizationFailedResponse), Protocol.Default.Version));
				authorization.SaveChanges();
			}

			var request = new EndUserAuthorizationRequestC(this.AuthorizationServer) {
				ClientIdentifier = this.ClientIdentifier,
				Callback = authorization.Callback,
			};
			request.Scope.ResetContents(authorization.Scope);

			// Mitigate XSRF attacks by including a state value that would be unpredictable between users, but
			// verifiable for the same user/session.
			// If the host is implementing the authorization tracker though, they're handling this protection themselves.
			HttpCookie cookie = null;
			if (this.AuthorizationTracker == null) {
				var context = this.Channel.GetHttpContext();

				string xsrfKey = MessagingUtilities.GetNonCryptoRandomDataAsBase64(16);
				cookie = new HttpCookie(XsrfCookieName, xsrfKey) {
					HttpOnly = true,
					Secure = FormsAuthentication.RequireSSL,
					////Expires = DateTime.Now.Add(OAuth2ClientSection.Configuration.MaxAuthorizationTime), // we prefer session cookies to persistent ones
				};
				request.ClientState = xsrfKey;
			}

			var response = this.Channel.PrepareResponse(request);
			if (cookie != null) {
				response.Cookies.Add(cookie);
			}

			return response;
		}
Example #17
0
		/// <summary>
		/// Refreshes a short-lived access token using a longer-lived refresh token.
		/// </summary>
		/// <param name="authorization">The authorization to update.</param>
		/// <param name="skipIfUsefulLifeExceeds">If given, the access token will <em>not</em> be refreshed if its remaining lifetime exceeds this value.</param>
		/// <returns>A value indicating whether the access token was actually renewed; <c>true</c> if it was renewed, or <c>false</c> if it still had useful life remaining.</returns>
		public bool RefreshToken(IAuthorizationState authorization, TimeSpan? skipIfUsefulLifeExceeds = null) {
			Contract.Requires<ArgumentNullException>(authorization != null);
			Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(authorization.RefreshToken));

			if (skipIfUsefulLifeExceeds.HasValue && authorization.AccessTokenExpirationUtc.HasValue) {
				TimeSpan usefulLifeRemaining = authorization.AccessTokenExpirationUtc.Value - DateTime.UtcNow;
				if (usefulLifeRemaining > skipIfUsefulLifeExceeds.Value) {
					// There is useful life remaining in the access token.  Don't refresh.
					Logger.OAuth.DebugFormat("Skipping token refresh step because access token's remaining life is {0}, which exceeds {1}.", usefulLifeRemaining, skipIfUsefulLifeExceeds.Value);
					return false;
				}
			}

			var request = new AccessTokenRefreshRequest(this.AuthorizationServer) {
				ClientIdentifier = this.ClientIdentifier,
				ClientSecret = this.ClientSecret,
				RefreshToken = authorization.RefreshToken,
			};

			var response = this.Channel.Request<AccessTokenSuccessResponse>(request);
			authorization.AccessToken = response.AccessToken;
			authorization.AccessTokenExpirationUtc = DateTime.UtcNow + response.Lifetime;
			authorization.AccessTokenIssueDateUtc = DateTime.UtcNow;

			// Just in case the scope has changed...
			if (response.Scope != null) {
				authorization.Scope.ResetContents(response.Scope);
			}

			// The authorization server MAY choose to renew the refresh token itself.
			if (response.RefreshToken != null) {
				authorization.RefreshToken = response.RefreshToken;
			}

			authorization.SaveChanges();
			return true;
		}
Example #18
0
		/// <summary>
		/// Updates the authorization state maintained by the client with the content of an outgoing response.
		/// </summary>
		/// <param name="authorizationState">The authorization state maintained by the client.</param>
		/// <param name="accessTokenSuccess">The access token containing response message.</param>
		internal static void UpdateAuthorizationWithResponse(IAuthorizationState authorizationState, AccessTokenSuccessResponse accessTokenSuccess) {
			Contract.Requires<ArgumentNullException>(authorizationState != null);
			Contract.Requires<ArgumentNullException>(accessTokenSuccess != null);

			authorizationState.AccessToken = accessTokenSuccess.AccessToken;
			authorizationState.RefreshToken = accessTokenSuccess.RefreshToken;
			authorizationState.AccessTokenExpirationUtc = DateTime.UtcNow + accessTokenSuccess.Lifetime;
			authorizationState.AccessTokenIssueDateUtc = DateTime.UtcNow;
			if (accessTokenSuccess.Scope != null && accessTokenSuccess.Scope != authorizationState.Scope) {
				if (authorizationState.Scope != null) {
					Logger.OAuth.InfoFormat(
						"Requested scope of \"{0}\" changed to \"{1}\" by authorization server.",
						authorizationState.Scope,
						accessTokenSuccess.Scope);
				}

				authorizationState.Scope.ResetContents(accessTokenSuccess.Scope);
			}

			authorizationState.SaveChanges();
		}
Example #19
0
        public bool RefreshToken(IAuthorizationState authorization, TimeSpan? skipIfUsefulLifeExceeds,
                                 Func<IDirectedProtocolMessage, IProtocolMessage> requestProvider) {
            authorization.ThrowIfNull("authorization");
            Certificate.ThrowIfNull("certificate");
            bool result = false;

            // Check if the token is still valid.
            if (skipIfUsefulLifeExceeds.HasValue && authorization.AccessTokenExpirationUtc.HasValue)
            {
                TimeSpan timeSpan = authorization.AccessTokenExpirationUtc.Value - DateTime.UtcNow;
                if (timeSpan > skipIfUsefulLifeExceeds.Value)
                {
                    return result;
                }
            }

            var requestMessage = GenerateMessage();
            var response = requestProvider(requestMessage);

            // Response is not strongly-typed to an AccessTokenSuccessResponse because DotNetOpenAuth can't infer the
            // type from the request message type. The only way to get access to the result data is through the
            // resulting Dictionary.
            if (response.ExtraData.ContainsKey("access_token") && response.ExtraData.ContainsKey("expires_in")) {
                result = true;
                authorization.AccessToken = response.ExtraData["access_token"];
                long expiresIn = long.Parse(response.ExtraData["expires_in"]);
                DateTime utcNow = DateTime.UtcNow;
                authorization.AccessTokenExpirationUtc = new DateTime? (utcNow.AddSeconds(expiresIn));
                authorization.AccessTokenIssueDateUtc = new DateTime? (utcNow);
                authorization.SaveChanges();
            } else {
                result = false;
            }
            return result;
        }