/// <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>
		/// Initializes a new instance of the <see cref="EndUserAuthorizationSuccessAccessTokenResponse"/> class.
		/// </summary>
		/// <param name="clientCallback">The URL to redirect to so the client receives the message. This may not be built into the request message if the client pre-registered the URL with the authorization server.</param>
		/// <param name="request">The authorization request from the user agent on behalf of the client.</param>
		internal EndUserAuthorizationSuccessAccessTokenResponse(Uri clientCallback, EndUserAuthorizationRequest request)
			: base(clientCallback, request) {
			Requires.NotNull(clientCallback, "clientCallback");
			Requires.NotNull(request, "request");
			((IMessageWithClientState)this).ClientState = request.ClientState;
			this.TokenType = Protocol.AccessTokenTypes.Bearer;
		}
 /// <summary>
 /// Initializes a new instance of the <see cref="EndUserAuthorizationSuccessAuthCodeResponse"/> class.
 /// </summary>
 /// <param name="clientCallback">The URL to redirect to so the client receives the message. This may not be built into the request message if the client pre-registered the URL with the authorization server.</param>
 /// <param name="request">The authorization request from the user agent on behalf of the client.</param>
 internal EndUserAuthorizationSuccessAuthCodeResponse(Uri clientCallback, EndUserAuthorizationRequest request)
     : base(clientCallback, request)
 {
     Requires.NotNull(clientCallback, "clientCallback");
     Requires.NotNull(request, "request");
     ((IMessageWithClientState)this).ClientState = request.ClientState;
 }
		/// <summary>
		/// Initializes a new instance of the <see cref="EndUserAuthorizationSuccessResponseBase"/> class.
		/// </summary>
		/// <param name="clientCallback">The URL to redirect to so the client receives the message. This may not be built into the request message if the client pre-registered the URL with the authorization server.</param>
		/// <param name="request">The authorization request from the user agent on behalf of the client.</param>
		internal EndUserAuthorizationSuccessResponseBase(Uri clientCallback, EndUserAuthorizationRequest request)
			: base(request, clientCallback) {
			Contract.Requires<ArgumentNullException>(clientCallback != null);
			Contract.Requires<ArgumentNullException>(request != null);
			((IMessageWithClientState)this).ClientState = request.ClientState;
			this.Scope = new HashSet<string>(OAuthUtilities.ScopeStringComparer);
		}
		/// <summary>
		/// Approves an authorization request and sends an HTTP response to the user agent to redirect the user back to the Client.
		/// </summary>
		/// <param name="authorizationRequest">The authorization request to approve.</param>
		/// <param name="userName">The username of the account that approved the request (or whose data will be accessed by the client).</param>
		/// <param name="scopes">The scope of access the client should be granted.  If <c>null</c>, all scopes in the original request will be granted.</param>
		/// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param>
		public void ApproveAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, string userName, IEnumerable<string> scopes = null, Uri callback = null) {
			Contract.Requires<ArgumentNullException>(authorizationRequest != null);

			var response = this.PrepareApproveAuthorizationRequest(authorizationRequest, userName, scopes, callback);

			this.Channel.Send(response);
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="EndUserAuthorizationSuccessAccessTokenResponse"/> class.
		/// </summary>
		/// <param name="clientCallback">The URL to redirect to so the client receives the message. This may not be built into the request message if the client pre-registered the URL with the authorization server.</param>
		/// <param name="request">The authorization request from the user agent on behalf of the client.</param>
		internal EndUserAuthorizationSuccessAccessTokenResponse(Uri clientCallback, EndUserAuthorizationRequest request)
			: base(clientCallback, request) {
			Contract.Requires<ArgumentNullException>(clientCallback != null);
			Contract.Requires<ArgumentNullException>(request != null);
			((IMessageWithClientState)this).ClientState = request.ClientState;
			this.TokenType = Protocol.AccessTokenTypes.Bearer;
		}
        public bool CanBeAutoApproved(EndUserAuthorizationRequest authorizationRequest) {
            //TODO: make sure we have a valid client secret on file matching that included with the authorization request
            return (true);
            //if (authorizationRequest == null) {
            //    throw new ArgumentNullException("authorizationRequest");
            //}

            //// NEVER issue an auto-approval to a client that would end up getting an access token immediately
            //// (without a client secret), as that would allow arbitrary clients to masquarade as an approved client
            //// and obtain unauthorized access to user data.
            //if (authorizationRequest.ResponseType == EndUserAuthorizationResponseType.AuthorizationCode) {
            //    // Never issue auto-approval if the client secret is blank, since that too makes it easy to spoof
            //    // a client's identity and obtain unauthorized access.
            //    var requestingClient = MvcApplication.DataContext.Clients.First(c => c.ClientIdentifier == authorizationRequest.ClientIdentifier);
            //    if (!string.IsNullOrEmpty(requestingClient.ClientSecret)) {
            //        return this.IsAuthorizationValid(
            //            authorizationRequest.Scope,
            //            authorizationRequest.ClientIdentifier,
            //            DateTime.UtcNow,
            //            HttpContext.Current.User.Identity.Name);
            //    }
            //}

            //// Default to not auto-approving.
            //return false;
        }
        public bool CanBeAutoApproved(EndUserAuthorizationRequest authorizationRequest)
        {
            if (authorizationRequest == null)
            {
                throw new ArgumentNullException("authorizationRequest");
            }

            // NEVER issue an auto-approval to a client that would end up getting an access token immediately
            // (without a client secret), as that would allow arbitrary clients to masquarade as an approved client
            // and obtain unauthorized access to user data.
            if (authorizationRequest.ResponseType == EndUserAuthorizationResponseType.AuthorizationCode)
            {
                // Never issue auto-approval if the client secret is blank, since that too makes it easy to spoof
                // a client's identity and obtain unauthorized access.
                var db = new OAuthEntities();
                var requestingClient = db.oauth_client.First(c => c.ClientIdentifier == authorizationRequest.ClientIdentifier);
                if (!string.IsNullOrEmpty(requestingClient.ClientSecret))
                {
                    return this.IsAuthorizationValid(
                        authorizationRequest.Scope,
                        authorizationRequest.ClientIdentifier,
                        DateTime.UtcNow,
                        "zhangsan"
                        //HttpContext.Current.User.Identity.Name
                        );
                }
            }

            // Default to not auto-approving.
            return false;
        }
Beispiel #9
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EndUserAuthorizationSuccessAccessTokenResponse"/> class.
 /// </summary>
 /// <param name="clientCallback">The URL to redirect to so the client receives the message. This may not be built into the request message if the client pre-registered the URL with the authorization server.</param>
 /// <param name="request">The authorization request from the user agent on behalf of the client.</param>
 internal EndUserAuthorizationSuccessAccessTokenResponse(Uri clientCallback, EndUserAuthorizationRequest request)
     : base(clientCallback, request)
 {
     Requires.NotNull(clientCallback, "clientCallback");
     Requires.NotNull(request, "request");
     ((IMessageWithClientState)this).ClientState = request.ClientState;
     this.TokenType = Protocol.AccessTokenTypes.Bearer;
 }
		/// <summary>
		/// Initializes a new instance of the <see cref="EndUserAuthorizationSuccessResponseBase"/> class.
		/// </summary>
		/// <param name="clientCallback">The URL to redirect to so the client receives the message. This may not be built into the request message if the client pre-registered the URL with the authorization server.</param>
		/// <param name="request">The authorization request from the user agent on behalf of the client.</param>
		internal EndUserAuthorizationSuccessResponseBase(Uri clientCallback, EndUserAuthorizationRequest request)
			: base(request, clientCallback) {
			Requires.NotNull(clientCallback, "clientCallback");
			Requires.NotNull(request, "request");
			((IMessageWithClientState)this).ClientState = request.ClientState;
			this.Scope = new HashSet<string>(OAuthUtilities.ScopeStringComparer);
			this.Scope.ResetContents(request.Scope);
		}
 /// <summary>
 /// Initializes a new instance of the <see cref="EndUserAuthorizationSuccessResponseBase"/> class.
 /// </summary>
 /// <param name="clientCallback">The URL to redirect to so the client receives the message. This may not be built into the request message if the client pre-registered the URL with the authorization server.</param>
 /// <param name="request">The authorization request from the user agent on behalf of the client.</param>
 internal EndUserAuthorizationSuccessResponseBase(Uri clientCallback, EndUserAuthorizationRequest request)
     : base(request, clientCallback)
 {
     Requires.NotNull(clientCallback, "clientCallback");
     Requires.NotNull(request, "request");
     ((IMessageWithClientState)this).ClientState = request.ClientState;
     this.Scope = new HashSet <string>(OAuthUtilities.ScopeStringComparer);
     this.Scope.ResetContents(request.Scope);
 }
		/// <summary>
		/// Generates a URL that the user's browser can be directed to in order to authorize
		/// this client to access protected data at some resource server.
		/// </summary>
		/// <param name="authorization">The authorization state that is tracking this particular request.  Optional.</param>
		/// <returns>A fully-qualified URL suitable to initiate the authorization flow.</returns>
		public Uri RequestUserAuthorization(IAuthorizationState authorization) {
			Contract.Requires<ArgumentNullException>(authorization != null);
			Contract.Requires<InvalidOperationException>(!string.IsNullOrEmpty(this.ClientIdentifier));

			if (authorization.Callback == null) {
				authorization.Callback = new Uri("http://localhost/");
			}

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

			return this.Channel.PrepareResponse(request).GetDirectUriRequest(this.Channel);
		}
Beispiel #13
0
		/// <summary>
		/// Generates a URL that the user's browser can be directed to in order to authorize
		/// this client to access protected data at some resource server.
		/// </summary>
		/// <param name="authorization">The authorization state that is tracking this particular request.  Optional.</param>
		/// <param name="state">The client state that should be returned with the authorization response.</param>
		/// <returns>
		/// A fully-qualified URL suitable to initiate the authorization flow.
		/// </returns>
		public Uri RequestUserAuthorization(IAuthorizationState authorization, string state = null) {
			Requires.NotNull(authorization, "authorization");
			Requires.ValidState(!string.IsNullOrEmpty(this.ClientIdentifier));

			if (authorization.Callback == null) {
				authorization.Callback = new Uri("http://localhost/");
			}

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

			return this.Channel.PrepareResponse(request).GetDirectUriRequest(this.Channel);
		}
		protected void Page_Load(object sender, EventArgs e) {
			if (!IsPostBack) {
				this.pendingRequest = OAuthServiceProvider.AuthorizationServer.ReadAuthorizationRequest();
				if (this.pendingRequest == null) {
					throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request.");
				}

				this.csrfCheck.Value = Code.SiteUtilities.SetCsrfCookie();
				var requestingClient = Database.DataContext.Clients.First(c => c.ClientIdentifier == this.pendingRequest.ClientIdentifier);
				this.consumerNameLabel.Text = HttpUtility.HtmlEncode(requestingClient.Name);
				this.scopeLabel.Text = HttpUtility.HtmlEncode(OAuthUtilities.JoinScopes(this.pendingRequest.Scope));

				// Consider auto-approving if safe to do so.
				if (((OAuthAuthorizationServer)OAuthServiceProvider.AuthorizationServer.AuthorizationServerServices).CanBeAutoApproved(this.pendingRequest)) {
					OAuthServiceProvider.AuthorizationServer.ApproveAuthorizationRequest(this.pendingRequest, HttpContext.Current.User.Identity.Name);
				}
				this.ViewState["AuthRequest"] = this.pendingRequest;
			} else {
				Code.SiteUtilities.VerifyCsrfCookie(this.csrfCheck.Value);
				this.pendingRequest = (EndUserAuthorizationRequest)this.ViewState["AuthRequest"];
			}
		}
		protected void Page_Load(object sender, EventArgs e) {
			this.RegisterAsyncTask(
				new PageAsyncTask(
					async ct => {
						if (!IsPostBack) {
							this.pendingRequest =
								await
								OAuthServiceProvider.AuthorizationServer.ReadAuthorizationRequestAsync(
									new HttpRequestWrapper(Request), Response.ClientDisconnectedToken);
							if (this.pendingRequest == null) {
								throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request.");
							}

							this.csrfCheck.Value = Code.SiteUtilities.SetCsrfCookie();
							var requestingClient =
								Database.DataContext.Clients.First(c => c.ClientIdentifier == this.pendingRequest.ClientIdentifier);
							this.consumerNameLabel.Text = HttpUtility.HtmlEncode(requestingClient.Name);
							this.scopeLabel.Text = HttpUtility.HtmlEncode(OAuthUtilities.JoinScopes(this.pendingRequest.Scope));

							// Consider auto-approving if safe to do so.
							if (
								((OAuthAuthorizationServer)OAuthServiceProvider.AuthorizationServer.AuthorizationServerServices)
									.CanBeAutoApproved(this.pendingRequest)) {
								var response = OAuthServiceProvider.AuthorizationServer.PrepareApproveAuthorizationRequest(
									this.pendingRequest, HttpContext.Current.User.Identity.Name);
								var responseMessage =
									await
									OAuthServiceProvider.AuthorizationServer.Channel.PrepareResponseAsync(
										response, Response.ClientDisconnectedToken);
								await responseMessage.SendAsync(new HttpContextWrapper(this.Context), Response.ClientDisconnectedToken);
								this.Context.Response.End();
							}
							this.ViewState["AuthRequest"] = this.pendingRequest;
						} else {
							Code.SiteUtilities.VerifyCsrfCookie(this.csrfCheck.Value);
							this.pendingRequest = (EndUserAuthorizationRequest)this.ViewState["AuthRequest"];
						}
					}));
		}
Beispiel #16
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);
		}
		/// <summary>
		/// Gets the redirect URL to use for a particular authorization request.
		/// </summary>
		/// <param name="authorizationRequest">The authorization request.</param>
		/// <returns>The URL to redirect to.  Never <c>null</c>.</returns>
		/// <exception cref="ProtocolException">Thrown if no callback URL could be determined.</exception>
		protected Uri GetCallback(EndUserAuthorizationRequest authorizationRequest) {
			Contract.Requires<ArgumentNullException>(authorizationRequest != null);
			Contract.Ensures(Contract.Result<Uri>() != null);

			var client = this.AuthorizationServerServices.GetClientOrThrow(authorizationRequest.ClientIdentifier);

			// Prefer a request-specific callback to the pre-registered one (if any).
			if (authorizationRequest.Callback != null) {
				// The OAuth channel has already validated the callback parameter against
				// the authorization server's whitelist for this client.
				return authorizationRequest.Callback;
			}

			// Since the request didn't include a callback URL, look up the callback from
			// the client's preregistration with this authorization server.
			Uri defaultCallback = client.DefaultCallback;
			ErrorUtilities.VerifyProtocol(defaultCallback != null, OAuthStrings.NoCallback);
			return defaultCallback;
		}
		/// <summary>
		/// Prepares a response to inform the Client that the user has rejected the Client's authorization request.
		/// </summary>
		/// <param name="authorizationRequest">The authorization request.</param>
		/// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param>
		/// <returns>The authorization response message to send to the Client.</returns>
		public EndUserAuthorizationFailedResponse PrepareRejectAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, Uri callback = null) {
			Contract.Requires<ArgumentNullException>(authorizationRequest != null);
			Contract.Ensures(Contract.Result<EndUserAuthorizationFailedResponse>() != null);

			if (callback == null) {
				callback = this.GetCallback(authorizationRequest);
			}

			var response = new EndUserAuthorizationFailedResponse(callback, authorizationRequest);
			return response;
		}
		/// <summary>
		/// Approves an authorization request.
		/// </summary>
		/// <param name="authorizationRequest">The authorization request to approve.</param>
		/// <param name="userName">The username of the account that approved the request (or whose data will be accessed by the client).</param>
		/// <param name="scopes">The scope of access the client should be granted.  If <c>null</c>, all scopes in the original request will be granted.</param>
		/// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param>
		/// <returns>The authorization response message to send to the Client.</returns>
		public EndUserAuthorizationSuccessResponseBase PrepareApproveAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, string userName, IEnumerable<string> scopes = null, Uri callback = null) {
			Contract.Requires<ArgumentNullException>(authorizationRequest != null);
			Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(userName));
			Contract.Ensures(Contract.Result<EndUserAuthorizationSuccessResponseBase>() != null);

			if (callback == null) {
				callback = this.GetCallback(authorizationRequest);
			}

			var client = this.AuthorizationServerServices.GetClientOrThrow(authorizationRequest.ClientIdentifier);
			EndUserAuthorizationSuccessResponseBase response;
			switch (authorizationRequest.ResponseType) {
				case EndUserAuthorizationResponseType.AccessToken:
					var accessTokenResponse = new EndUserAuthorizationSuccessAccessTokenResponse(callback, authorizationRequest);
					accessTokenResponse.Lifetime = this.AuthorizationServerServices.GetAccessTokenLifetime(authorizationRequest);
					response = accessTokenResponse;
					break;
				case EndUserAuthorizationResponseType.AuthorizationCode:
					response = new EndUserAuthorizationSuccessAuthCodeResponse(callback, authorizationRequest);
					break;
				default:
					throw ErrorUtilities.ThrowInternal("Unexpected response type.");
			}

			response.AuthorizingUsername = userName;

			// Customize the approved scope if the authorization server has decided to do so.
			if (scopes != null) {
				response.Scope.ResetContents(scopes);
			}

			return response;
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="EndUserAuthorizationFailedResponse"/> class.
		/// </summary>
		/// <param name="clientCallback">The URL to redirect to so the client receives the message. This may not be built into the request message if the client pre-registered the URL with the authorization server.</param>
		/// <param name="request">The authorization request from the user agent on behalf of the client.</param>
		internal EndUserAuthorizationFailedResponse(Uri clientCallback, EndUserAuthorizationRequest request)
			: base(((IProtocolMessage)request).Version, MessageTransport.Indirect, clientCallback) {
			Requires.NotNull(request, "request");
			((IMessageWithClientState)this).ClientState = request.ClientState;
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="EndUserAuthorizationFailedResponse"/> class.
		/// </summary>
		/// <param name="clientCallback">The URL to redirect to so the client receives the message. This may not be built into the request message if the client pre-registered the URL with the authorization server.</param>
		/// <param name="request">The authorization request from the user agent on behalf of the client.</param>
		internal EndUserAuthorizationFailedResponse(Uri clientCallback, EndUserAuthorizationRequest request)
			: base(((IProtocolMessage)request).Version, MessageTransport.Indirect, clientCallback) {
			Contract.Requires<ArgumentNullException>(request != null);
			((IMessageWithClientState)this).ClientState = request.ClientState;
		}
		/// <summary>
		/// Rejects an authorization request and sends an HTTP response to the user agent to redirect the user back to the Client.
		/// </summary>
		/// <param name="authorizationRequest">The authorization request to disapprove.</param>
		/// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param>
		public void RejectAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, Uri callback = null) {
			Contract.Requires<ArgumentNullException>(authorizationRequest != null);

			var response = this.PrepareRejectAuthorizationRequest(authorizationRequest, callback);
			this.Channel.Respond(response);
		}
Beispiel #23
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EndUserAuthorizationFailedResponse"/> class.
 /// </summary>
 /// <param name="clientCallback">The URL to redirect to so the client receives the message. This may not be built into the request message if the client pre-registered the URL with the authorization server.</param>
 /// <param name="request">The authorization request from the user agent on behalf of the client.</param>
 internal EndUserAuthorizationFailedResponse(Uri clientCallback, EndUserAuthorizationRequest request)
     : base(((IProtocolMessage)request).Version, MessageTransport.Indirect, clientCallback)
 {
     Requires.NotNull(request, "request");
     ((IMessageWithClientState)this).ClientState = request.ClientState;
 }
		/// <summary>
		/// Approves an authorization request.
		/// </summary>
		/// <param name="authorizationRequest">The authorization request to approve.</param>
		/// <param name="userName">The username of the account that approved the request (or whose data will be accessed by the client).</param>
		/// <param name="scopes">The scope of access the client should be granted.  If <c>null</c>, all scopes in the original request will be granted.</param>
		/// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param>
		/// <returns>The authorization response message to send to the Client.</returns>
		public EndUserAuthorizationSuccessResponseBase PrepareApproveAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, string userName, IEnumerable<string> scopes = null, Uri callback = null) {
			Requires.NotNull(authorizationRequest, "authorizationRequest");
			Requires.NotNullOrEmpty(userName, "userName");
			Contract.Ensures(Contract.Result<EndUserAuthorizationSuccessResponseBase>() != null);

			if (callback == null) {
				callback = this.GetCallback(authorizationRequest);
			}

			var client = this.AuthorizationServerServices.GetClientOrThrow(authorizationRequest.ClientIdentifier);
			EndUserAuthorizationSuccessResponseBase response;
			switch (authorizationRequest.ResponseType) {
				case EndUserAuthorizationResponseType.AccessToken:
					IAccessTokenRequestInternal accessRequestInternal = (EndUserAuthorizationImplicitRequest)authorizationRequest;
					var accessTokenResult = this.AuthorizationServerServices.CreateAccessToken(accessRequestInternal);
					ErrorUtilities.VerifyHost(accessTokenResult != null, "IAuthorizationServerHost.CreateAccessToken must not return null.");

					accessRequestInternal.AccessTokenResult = accessTokenResult;

					var implicitGrantResponse = new EndUserAuthorizationSuccessAccessTokenResponse(callback, authorizationRequest);
					implicitGrantResponse.Lifetime = accessTokenResult.AccessToken.Lifetime;
					accessTokenResult.AccessToken.ApplyAuthorization(implicitGrantResponse.Scope, userName, implicitGrantResponse.Lifetime);

					IAccessTokenCarryingRequest tokenCarryingResponse = implicitGrantResponse;
					tokenCarryingResponse.AuthorizationDescription = accessTokenResult.AccessToken;

					response = implicitGrantResponse;
					break;
				case EndUserAuthorizationResponseType.AuthorizationCode:
					var authCodeResponse = new EndUserAuthorizationSuccessAuthCodeResponseAS(callback, authorizationRequest);
					IAuthorizationCodeCarryingRequest codeCarryingResponse = authCodeResponse;
					codeCarryingResponse.AuthorizationDescription = new AuthorizationCode(
						authorizationRequest.ClientIdentifier,
						authorizationRequest.Callback,
						authCodeResponse.Scope,
						userName);
					response = authCodeResponse;
					break;
				default:
					throw ErrorUtilities.ThrowInternal("Unexpected response type.");
			}

			response.AuthorizingUsername = userName;

			// Customize the approved scope if the authorization server has decided to do so.
			if (scopes != null) {
				response.Scope.ResetContents(scopes);
			}

			return response;
		}
		/// <summary>
		/// Rejects an authorization request and sends an HTTP response to the user agent to redirect the user back to the Client.
		/// </summary>
		/// <param name="authorizationRequest">The authorization request to disapprove.</param>
		/// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param>
		public void RejectAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, Uri callback = null) {
			Requires.NotNull(authorizationRequest, "authorizationRequest");

			var response = this.PrepareRejectAuthorizationRequest(authorizationRequest, callback);
			this.Channel.Respond(response);
		}
		/// <summary>
		/// Approves an authorization request and sends an HTTP response to the user agent to redirect the user back to the Client.
		/// </summary>
		/// <param name="authorizationRequest">The authorization request to approve.</param>
		/// <param name="userName">The username of the account that approved the request (or whose data will be accessed by the client).</param>
		/// <param name="scopes">The scope of access the client should be granted.  If <c>null</c>, all scopes in the original request will be granted.</param>
		/// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param>
		public void ApproveAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, string userName, IEnumerable<string> scopes = null, Uri callback = null) {
			Requires.NotNull(authorizationRequest, "authorizationRequest");

			var response = this.PrepareApproveAuthorizationRequest(authorizationRequest, userName, scopes, callback);
			this.Channel.Respond(response);
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="EndUserAuthorizationSuccessAuthCodeResponseAS"/> class.
		/// </summary>
		/// <param name="clientCallback">The URL to redirect to so the client receives the message. This may not be built into the request message if the client pre-registered the URL with the authorization server.</param>
		/// <param name="request">The authorization request from the user agent on behalf of the client.</param>
		internal EndUserAuthorizationSuccessAuthCodeResponseAS(Uri clientCallback, EndUserAuthorizationRequest request)
			: base(clientCallback, request) {
			Requires.NotNull(clientCallback, "clientCallback");
			Requires.NotNull(request, "request");
			((IMessageWithClientState)this).ClientState = request.ClientState;
		}
		/// <summary>
		/// Prepares a response to inform the Client that the user has rejected the Client's authorization request.
		/// </summary>
		/// <param name="authorizationRequest">The authorization request.</param>
		/// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param>
		/// <returns>The authorization response message to send to the Client.</returns>
		public EndUserAuthorizationFailedResponse PrepareRejectAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, Uri callback = null) {
			Requires.NotNull(authorizationRequest, "authorizationRequest");

			if (callback == null) {
				callback = this.GetCallback(authorizationRequest);
			}

			var response = new EndUserAuthorizationFailedResponse(callback, authorizationRequest);
			return response;
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="EndUserAuthorizationSuccessAuthCodeResponse"/> class.
		/// </summary>
		/// <param name="clientCallback">The URL to redirect to so the client receives the message. This may not be built into the request message if the client pre-registered the URL with the authorization server.</param>
		/// <param name="request">The authorization request from the user agent on behalf of the client.</param>
		internal EndUserAuthorizationSuccessAuthCodeResponse(Uri clientCallback, EndUserAuthorizationRequest request)
			: base(clientCallback, request) {
			Contract.Requires<ArgumentNullException>(clientCallback != null);
			Contract.Requires<ArgumentNullException>(request != null);
			((IMessageWithClientState)this).ClientState = request.ClientState;
		}
 public bool CanBeAutoApproved(EndUserAuthorizationRequest authorizationRequest)
 {
     //For the sake of this exercise, don't auto-approve anyone.
     return false;
 }