public ActionResult HandleConsentResponse(string button, AuthorizeRequest request)
        {
            Client client;
            var    error = CheckRequest(request, out client);

            if (error != null)
            {
                return(error);
            }

            if (button == "no")
            {
                return(ClientError(client.RedirectUri, OAuth2Constants.Errors.AccessDenied, request.response_type,
                                   request.state));
            }

            if (button == "yes")
            {
                var grantResult = PerformGrant(request, client);
                if (grantResult != null)
                {
                    return(grantResult);
                }
            }

            // todo: return appropiate error
            return(ClientError(client.RedirectUri, OAuth2Constants.Errors.InvalidRequest, request.response_type,
                               request.state));
        }
        private ActionResult PerformImplicitGrant(AuthorizeRequest request, Client client)
        {
            var sts = new STS();

            TokenResponse tokenResponse;

            if (sts.TryIssueToken(
                    new EndpointReference(request.scope),
                    ClaimsPrincipal.Current,
                    Configuration.Global.DefaultHttpTokenType,
                    out tokenResponse))
            {
                var tokenString = string.Format("access_token={0}&token_type={1}&expires_in={2}",
                                                tokenResponse.AccessToken,
                                                tokenResponse.TokenType,
                                                tokenResponse.ExpiresIn);

                if (!string.IsNullOrEmpty(request.state))
                {
                    tokenString = string.Format("{0}&state={1}", tokenString, Server.UrlEncode(request.state));
                }

                var redirectString = string.Format("{0}#{1}",
                                                   client.RedirectUri.AbsoluteUri,
                                                   tokenString);

                return(Redirect(redirectString));
            }

            // return right error code
            return(ClientError(client.RedirectUri, OAuth2Constants.Errors.InvalidRequest, request.response_type,
                               request.state));
        }
        public ActionResult HandleRequest(AuthorizeRequest request)
        {
            Tracing.Information("OAuth2 HandleRequest endpoint invoked");

            // check client
            Client client;
            var    error = CheckRequest(request, out client);

            if (error != null)
            {
                return(error);
            }

            RelyingParty rp;

            if (!RPRepository.TryGet(request.scope, out rp))
            {
                Tracing.Error("RP not found for scope : " + request.scope);
                return(ClientError(client.RedirectUri, OAuth2Constants.Errors.InvalidScope, request.response_type,
                                   request.state));
            }

            if (Configuration.OAuth2.EnableConsent)
            {
                // show resource name, uri and client name
                // client is trying to access resource on your behalf
                var vm = new OAuth2ConsentViewModel
                {
                    ResourceUri         = rp.Realm.AbsoluteUri,
                    ResourceName        = rp.Name,
                    ClientName          = client.ClientId,
                    RefreshTokenEnabled = client.AllowRefreshToken
                };

                return(View("ShowConsent", vm));
            }
            var grantResult = PerformGrant(request, client);

            if (grantResult != null)
            {
                return(grantResult);
            }

            // we don't know exactly why, so use ServerError
            Tracing.Error("Authorization Endpoint failed");
            return(ClientError(client.RedirectUri, OAuth2Constants.Errors.InvalidRequest, request.response_type,
                               request.state));
        }
        private ActionResult PerformGrant(AuthorizeRequest request, Client client)
        {
            // implicit grant
            if (request.response_type.Equals(OAuth2Constants.ResponseTypes.Token, StringComparison.Ordinal))
            {
                return(PerformImplicitGrant(request, client));
            }

            // authorization code grant
            if (request.response_type.Equals(OAuth2Constants.ResponseTypes.Code, StringComparison.Ordinal))
            {
                return(PerformAuthorizationCodeGrant(request, client));
            }

            return(null);
        }
        private ActionResult PerformAuthorizationCodeGrant(AuthorizeRequest request, Client client)
        {
            var code = CodeTokenRepository.AddCode(CodeTokenType.AuthorizationCode, client.ID,
                                                   ClaimsPrincipal.Current.Identity.Name, request.scope);
            var tokenString = string.Format("code={0}", code);

            if (!string.IsNullOrEmpty(request.state))
            {
                tokenString = string.Format("{0}&state={1}", tokenString, Server.UrlEncode(request.state));
            }

            var redirectString = string.Format("{0}?{1}",
                                               client.RedirectUri.AbsoluteUri,
                                               tokenString);

            return(Redirect(redirectString));
        }
        public ActionResult HandleConsent(AuthorizeRequest request, string button, string[] selectedScopes)
        {
            Tracing.Start("OIDC consent response");

            ValidatedRequest validatedRequest;
            ActionResult failedResult;
            if (!TryValidateRequest(request, out validatedRequest, out failedResult))
            {
                Tracing.Error("Aborting OIDC consent response");
                return failedResult;
            }

            if (button == "allow")
            {
                var vm = new OidcViewModel(validatedRequest);
                vm.SetScopes(selectedScopes);
                return PerformGrant(vm.ValidatedRequest);
            }
            return DenyGrant(validatedRequest);
        }
        public ActionResult HandleConsentResponse(string button, AuthorizeRequest request)
        {
            Client client;
            var error = CheckRequest(request, out client);
            if (error != null) return error;

            if (button == "no")
            {
                return ClientError(client.RedirectUri, OAuth2Constants.Errors.AccessDenied, request.response_type,
                    request.state);
            }

            if (button == "yes")
            {
                var grantResult = PerformGrant(request, client);
                if (grantResult != null) return grantResult;
            }

            // todo: return appropiate error
            return ClientError(client.RedirectUri, OAuth2Constants.Errors.InvalidRequest, request.response_type,
                request.state);
        }
        private ActionResult PerformImplicitGrant(AuthorizeRequest request, Client client)
        {
            var sts = new STS();

            TokenResponse tokenResponse;
            if (sts.TryIssueToken(
                new EndpointReference(request.scope),
                ClaimsPrincipal.Current,
                Configuration.Global.DefaultHttpTokenType,
                out tokenResponse))
            {
                var tokenString = string.Format("access_token={0}&token_type={1}&expires_in={2}",
                    tokenResponse.AccessToken,
                    tokenResponse.TokenType,
                    tokenResponse.ExpiresIn);

                if (!string.IsNullOrEmpty(request.state))
                {
                    tokenString = string.Format("{0}&state={1}", tokenString, Server.UrlEncode(request.state));
                }

                var redirectString = string.Format("{0}#{1}",
                    client.RedirectUri.AbsoluteUri,
                    tokenString);

                return Redirect(redirectString);
            }

            // return right error code
            return ClientError(client.RedirectUri, OAuth2Constants.Errors.InvalidRequest, request.response_type,
                request.state);
        }
        private ActionResult PerformGrant(AuthorizeRequest request, Client client)
        {
            // implicit grant
            if (request.response_type.Equals(OAuth2Constants.ResponseTypes.Token, StringComparison.Ordinal))
            {
                return PerformImplicitGrant(request, client);
            }

            // authorization code grant
            if (request.response_type.Equals(OAuth2Constants.ResponseTypes.Code, StringComparison.Ordinal))
            {
                return PerformAuthorizationCodeGrant(request, client);
            }

            return null;
        }
        private ActionResult PerformAuthorizationCodeGrant(AuthorizeRequest request, Client client)
        {
            var code = CodeTokenRepository.AddCode(CodeTokenType.AuthorizationCode, client.ID,
                ClaimsPrincipal.Current.Identity.Name, request.scope);
            var tokenString = string.Format("code={0}", code);

            if (!string.IsNullOrEmpty(request.state))
            {
                tokenString = string.Format("{0}&state={1}", tokenString, Server.UrlEncode(request.state));
            }

            var redirectString = string.Format("{0}?{1}",
                client.RedirectUri.AbsoluteUri,
                tokenString);

            return Redirect(redirectString);
        }
        private ActionResult CheckRequest(AuthorizeRequest request, out Client client)
        {
            if (request == null)
            {
                client = null;
                ViewBag.Message = "Invalid request parameters";
                Tracing.Error(ViewBag.Message);
                return View("Error");
            }

            // validate client
            if (!Clients.TryGetClient(request.client_id, out client))
            {
                ViewBag.Message = "Invalid client_id : " + request.client_id;
                Tracing.Error(ViewBag.Message);
                return View("Error");
            }

            // validate redirect uri
            if (client.RedirectUri == null)
            {
                ViewBag.Message = "A redirect uri for client_id " + request.client_id + " was not configured.";
                Tracing.Error(ViewBag.Message);
                return View("Error");
            }

            if (string.IsNullOrEmpty(request.redirect_uri) ||
                !string.Equals(request.redirect_uri, client.RedirectUri.AbsoluteUri, StringComparison.OrdinalIgnoreCase))
            {
                ViewBag.Message = "The redirect_uri in the request: " + request.redirect_uri +
                                  " did not match a registered redirect URI.";
                Tracing.Error(ViewBag.Message);
                return View("Error");
            }

            Uri redirectUrl;
            if (Uri.TryCreate(request.redirect_uri, UriKind.Absolute, out redirectUrl))
            {
                if (redirectUrl.Scheme == Uri.UriSchemeHttp)
                {
                    Tracing.Error("Redirect URI not over SSL : " + request.redirect_uri);
                    return ClientError(client.RedirectUri, OAuth2Constants.Errors.InvalidRequest, string.Empty,
                        request.state);
                }
            }
            else
            {
                Tracing.Error("Redirect URI not a valid URI : " + request.redirect_uri);
                return ClientError(client.RedirectUri, OAuth2Constants.Errors.InvalidRequest, string.Empty,
                    request.state);
            }

            if (string.IsNullOrWhiteSpace(request.response_type))
            {
                Tracing.Error("response_type is null or empty");
                return ClientError(client.RedirectUri, OAuth2Constants.Errors.InvalidRequest, string.Empty,
                    request.state);
            }

            // check response type (only code and token are supported)
            if (!request.response_type.Equals(OAuth2Constants.ResponseTypes.Token, StringComparison.Ordinal) &&
                !request.response_type.Equals(OAuth2Constants.ResponseTypes.Code, StringComparison.Ordinal))
            {
                Tracing.Error("response_type is not token or code: " + request.response_type);
                return ClientError(client.RedirectUri, OAuth2Constants.Errors.UnsupportedResponseType, string.Empty,
                    request.state);
            }

            // validate scope (must be a valid URI)
            Uri uri;
            if (!Uri.TryCreate(request.scope, UriKind.Absolute, out uri))
            {
                Tracing.Error("scope is not a URI: " + request.scope);
                return ClientError(client.RedirectUri, OAuth2Constants.Errors.InvalidScope, request.response_type,
                    request.state);
            }

            // validate if request grant type is allowed for client (implicit vs code flow)
            if (request.response_type.Equals(OAuth2Constants.ResponseTypes.Token) &&
                !client.AllowImplicitFlow)
            {
                Tracing.Error("response_type is token and client does not allow implicit flow. client: " + client.Name);
                return ClientError(client.RedirectUri, OAuth2Constants.Errors.UnsupportedResponseType,
                    request.response_type, request.state);
            }

            if (request.response_type.Equals(OAuth2Constants.ResponseTypes.Code) &&
                !client.AllowCodeFlow)
            {
                Tracing.Error("response_type is code and client does not allow code flow. client: " + client.Name);
                return ClientError(client.RedirectUri, OAuth2Constants.Errors.UnsupportedResponseType,
                    request.response_type, request.state);
            }

            return null;
        }
        public ActionResult HandleRequest(AuthorizeRequest request)
        {
            Tracing.Information("OAuth2 HandleRequest endpoint invoked");

            // check client
            Client client;
            var error = CheckRequest(request, out client);
            if (error != null) return error;

            RelyingParty rp;
            if (!RPRepository.TryGet(request.scope, out rp))
            {
                Tracing.Error("RP not found for scope : " + request.scope);
                return ClientError(client.RedirectUri, OAuth2Constants.Errors.InvalidScope, request.response_type,
                    request.state);
            }

            if (Configuration.OAuth2.EnableConsent)
            {
                // show resource name, uri and client name
                // client is trying to access resource on your behalf
                var vm = new OAuth2ConsentViewModel
                {
                    ResourceUri = rp.Realm.AbsoluteUri,
                    ResourceName = rp.Name,
                    ClientName = client.ClientId,
                    RefreshTokenEnabled = client.AllowRefreshToken
                };

                return View("ShowConsent", vm);
            }
            var grantResult = PerformGrant(request, client);
            if (grantResult != null) return grantResult;

            // we don't know exactly why, so use ServerError
            Tracing.Error("Authorization Endpoint failed");
            return ClientError(client.RedirectUri, OAuth2Constants.Errors.InvalidRequest, request.response_type,
                request.state);
        }
        private ActionResult CheckRequest(AuthorizeRequest request, out Client client)
        {
            if (request == null)
            {
                client          = null;
                ViewBag.Message = "Invalid request parameters";
                Tracing.Error(ViewBag.Message);
                return(View("Error"));
            }

            // validate client
            if (!Clients.TryGetClient(request.client_id, out client))
            {
                ViewBag.Message = "Invalid client_id : " + request.client_id;
                Tracing.Error(ViewBag.Message);
                return(View("Error"));
            }

            // validate redirect uri
            if (client.RedirectUri == null)
            {
                ViewBag.Message = "A redirect uri for client_id " + request.client_id + " was not configured.";
                Tracing.Error(ViewBag.Message);
                return(View("Error"));
            }

            if (string.IsNullOrEmpty(request.redirect_uri) ||
                !string.Equals(request.redirect_uri, client.RedirectUri.AbsoluteUri, StringComparison.OrdinalIgnoreCase))
            {
                ViewBag.Message = "The redirect_uri in the request: " + request.redirect_uri +
                                  " did not match a registered redirect URI.";
                Tracing.Error(ViewBag.Message);
                return(View("Error"));
            }

            Uri redirectUrl;

            if (Uri.TryCreate(request.redirect_uri, UriKind.Absolute, out redirectUrl))
            {
                if (redirectUrl.Scheme == Uri.UriSchemeHttp)
                {
                    Tracing.Error("Redirect URI not over SSL : " + request.redirect_uri);
                    return(ClientError(client.RedirectUri, OAuth2Constants.Errors.InvalidRequest, string.Empty,
                                       request.state));
                }
            }
            else
            {
                Tracing.Error("Redirect URI not a valid URI : " + request.redirect_uri);
                return(ClientError(client.RedirectUri, OAuth2Constants.Errors.InvalidRequest, string.Empty,
                                   request.state));
            }

            if (string.IsNullOrWhiteSpace(request.response_type))
            {
                Tracing.Error("response_type is null or empty");
                return(ClientError(client.RedirectUri, OAuth2Constants.Errors.InvalidRequest, string.Empty,
                                   request.state));
            }

            // check response type (only code and token are supported)
            if (!request.response_type.Equals(OAuth2Constants.ResponseTypes.Token, StringComparison.Ordinal) &&
                !request.response_type.Equals(OAuth2Constants.ResponseTypes.Code, StringComparison.Ordinal))
            {
                Tracing.Error("response_type is not token or code: " + request.response_type);
                return(ClientError(client.RedirectUri, OAuth2Constants.Errors.UnsupportedResponseType, string.Empty,
                                   request.state));
            }

            // validate scope (must be a valid URI)
            Uri uri;

            if (!Uri.TryCreate(request.scope, UriKind.Absolute, out uri))
            {
                Tracing.Error("scope is not a URI: " + request.scope);
                return(ClientError(client.RedirectUri, OAuth2Constants.Errors.InvalidScope, request.response_type,
                                   request.state));
            }

            // validate if request grant type is allowed for client (implicit vs code flow)
            if (request.response_type.Equals(OAuth2Constants.ResponseTypes.Token) &&
                !client.AllowImplicitFlow)
            {
                Tracing.Error("response_type is token and client does not allow implicit flow. client: " + client.Name);
                return(ClientError(client.RedirectUri, OAuth2Constants.Errors.UnsupportedResponseType,
                                   request.response_type, request.state));
            }

            if (request.response_type.Equals(OAuth2Constants.ResponseTypes.Code) &&
                !client.AllowCodeFlow)
            {
                Tracing.Error("response_type is code and client does not allow code flow. client: " + client.Name);
                return(ClientError(client.RedirectUri, OAuth2Constants.Errors.UnsupportedResponseType,
                                   request.response_type, request.state));
            }

            return(null);
        }
        public ValidatedRequest Validate(AuthorizeRequest request)
        {
            var validatedRequest = new ValidatedRequest();

            // validate request model binding
            if (request == null)
            {
                throw new AuthorizeRequestResourceOwnerException("Invalid request parameters.");
            }

            // make sure redirect uri is present
            if (string.IsNullOrWhiteSpace(request.redirect_uri))
            {
                throw new AuthorizeRequestResourceOwnerException("Missing redirect URI");
            }

            // validate client
            if (string.IsNullOrWhiteSpace(request.client_id))
            {
                throw new AuthorizeRequestResourceOwnerException("Missing client identifier");
            }

            var client = Clients.Get(request.client_id);

            if (client == null)
            {
                throw new AuthorizeRequestResourceOwnerException("Invalid client: " + request.client_id);
            }

            validatedRequest.Client = client;
            Tracing.InformationFormat("Client: {0} ({1})",
                validatedRequest.Client.Name,
                validatedRequest.Client.ClientId);

            // make sure redirect_uri is a valid uri, and in case of http is over ssl
            Uri redirectUri;
            if (Uri.TryCreate(request.redirect_uri, UriKind.Absolute, out redirectUri))
            {
                if (redirectUri.Scheme == Uri.UriSchemeHttp)
                {
                    throw new AuthorizeRequestClientException(
                        "Redirect URI not over SSL : " + request.redirect_uri,
                        new Uri(request.redirect_uri),
                        OAuth2Constants.Errors.InvalidRequest,
                        string.Empty,
                        validatedRequest.State);
                }

                // make sure redirect uri is registered with client
                if (!validatedRequest.Client.RedirectUris.Contains(request.redirect_uri))
                {
                    throw new AuthorizeRequestResourceOwnerException("Invalid redirect URI: " + request.redirect_uri);
                }

                validatedRequest.RedirectUri = request.redirect_uri;
                Tracing.InformationFormat("Redirect URI: {0}",
                    validatedRequest.RedirectUri);
            }
            else
            {
                throw new AuthorizeRequestResourceOwnerException("Invalid redirect URI: " + request.redirect_uri);
            }

            // check state
            if (!string.IsNullOrWhiteSpace(request.state))
            {
                validatedRequest.State = request.state;
                Tracing.Information("State: " + validatedRequest.State);
            }
            else
            {
                Tracing.Information("No state supplied.");
            }

            // validate response type
            if (string.IsNullOrWhiteSpace(request.response_type))
            {
                throw new AuthorizeRequestClientException(
                    "response_type is null or empty",
                    new Uri(validatedRequest.RedirectUri),
                    OAuth2Constants.Errors.InvalidRequest,
                    string.Empty,
                    validatedRequest.State);
            }

            // check response type (only code and token are supported)
            if (!request.response_type.Equals(OAuth2Constants.ResponseTypes.Token, StringComparison.Ordinal) &&
                !request.response_type.Equals(OAuth2Constants.ResponseTypes.Code, StringComparison.Ordinal))
            {
                throw new AuthorizeRequestClientException(
                    "response_type is not token or code: " + request.response_type,
                    new Uri(validatedRequest.RedirectUri),
                    OAuth2Constants.Errors.UnsupportedResponseType,
                    string.Empty,
                    validatedRequest.State);
            }

            validatedRequest.ResponseType = request.response_type;
            Tracing.Information("Response type: " + validatedRequest.ResponseType);

            // scope is required
            if (string.IsNullOrWhiteSpace(request.scope))
            {
                throw new AuthorizeRequestClientException(
                    "Missing scope",
                    new Uri(validatedRequest.RedirectUri),
                    OAuth2Constants.Errors.InvalidScope,
                    validatedRequest.ResponseType,
                    validatedRequest.State);
            }

            // validate scopes
            if (!request.scope.StartsWith("openid"))
            {
                throw new AuthorizeRequestClientException(
                    "Invalid scope: " + request.scope,
                    new Uri(validatedRequest.RedirectUri),
                    OAuth2Constants.Errors.InvalidScope,
                    validatedRequest.ResponseType,
                    validatedRequest.State);
            }

            validatedRequest.Scopes = request.scope;

            if (request.response_type == OAuth2Constants.ResponseTypes.Code)
            {
                ValidateCodeResponseType(validatedRequest, request);
            }
            else if (request.response_type == OAuth2Constants.ResponseTypes.Token)
            {
                ValidateTokenResponseType(validatedRequest, request);
            }
            else
            {
                throw new AuthorizeRequestClientException(
                    "Invalid response_type: " + request.response_type,
                    new Uri(validatedRequest.RedirectUri),
                    OAuth2Constants.Errors.UnsupportedResponseType,
                    request.response_type,
                    validatedRequest.State);
            }

            return validatedRequest;
        }
 private void ValidateTokenResponseType(ValidatedRequest validatedRequest, AuthorizeRequest request)
 {
     throw new NotImplementedException();
 }
 private void ValidateCodeResponseType(ValidatedRequest validatedRequest, AuthorizeRequest request)
 {
     if (validatedRequest.Client.Flow != OpenIdConnectFlows.AuthorizationCode)
     {
         throw new AuthorizeRequestClientException(
             "response_type is not allowed: " + request.response_type,
             new Uri(validatedRequest.RedirectUri),
             OAuth2Constants.Errors.UnsupportedResponseType,
             request.response_type,
             validatedRequest.State);
     }
 }