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

            // validate redirect uri
            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.";
                return View("Error");
            }

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

            return null;
        }
 public ActionResult Edit(int? id)
 {
     Client client = null;
     if (id != null && id > 0)
     {
         client = this.clientRepository.Get(id.Value);
         if (client == null) return HttpNotFound();
     }
     else
     {
         client = new Client();
     }
     
     return View("Edit", client);
 }
        public ActionResult Edit(string id)
        {
            Client client;
            if (!String.IsNullOrEmpty(id))
            {
                client = ClientRepository.Get(id);
                if (client == null) return HttpNotFound();
            }
            else
            {
                client = new Client();
            }

            var vm = new OAuthClientViewModel(client); 
            return View("Edit", vm);
        }
        private HttpResponseMessage ProcessResourceOwnerCredentialRequest(TokenRequest request, string tokenType, Client client)
        {
            Tracing.Information("Starting resource owner password credential flow for client: " + client.Name);
            var appliesTo = new EndpointReference(request.Scope);

            if (string.IsNullOrWhiteSpace(request.UserName) || string.IsNullOrWhiteSpace(request.Password))
            {
                Tracing.Error("Invalid resource owner credentials for: " + appliesTo.Uri.AbsoluteUri);
                return OAuthErrorResponseMessage(OAuth2Constants.Errors.InvalidGrant);
            }

            if (UserRepository.ValidateUser(request.UserName, request.Password))
            {
                return CreateTokenResponse(request.UserName, client, appliesTo, tokenType, includeRefreshToken: client.AllowRefreshToken);
            }
            else
            {
                Tracing.Error("Resource owner credential validation failed: " + request.UserName);
                return OAuthErrorResponseMessage(OAuth2Constants.Errors.InvalidGrant);
            }
        }
        public ActionResult Create(Client client)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    this.clientRepository.Create(client);
                    TempData["Message"] = Resources.OAuthClientController.ClientCreated;
                    return RedirectToAction("Edit", new { id = client.ID });
                }
                catch (ValidationException ex)
                {
                    ModelState.AddModelError("", ex.Message);
                }
                catch (Exception)
                {
                    ModelState.AddModelError("", Resources.OAuthClientController.ErrorCreatingClient);
                }
            }

            return Edit(client.ID);
        }
 public bool ValidateAndGetClient(string clientId, string clientSecret, out Client client)
 {
     throw new NotImplementedException();
 }
        private HttpResponseMessage ValidateRequest(TokenRequest request, out Client client)
        {
            client = null;

            // grant type is required
            if (string.IsNullOrWhiteSpace(request.Grant_Type))
            {
                return OAuthErrorResponseMessage(OAuth2Constants.Errors.UnsupportedGrantType);
            }

            // check supported grant types
            if (!request.Grant_Type.Equals(OAuth2Constants.GrantTypes.AuthorizationCode) &&
                !request.Grant_Type.Equals(OAuth2Constants.GrantTypes.Password) &&
                !request.Grant_Type.Equals(OAuth2Constants.GrantTypes.RefreshToken))
            {
                return OAuthErrorResponseMessage(OAuth2Constants.Errors.UnsupportedGrantType);
            }

            // resource owner password flow requires a well-formed scope
            EndpointReference appliesTo = null;
            if (request.Grant_Type.Equals(OAuth2Constants.GrantTypes.Password))
            {
                try
                {
                    appliesTo = new EndpointReference(request.Scope);
                    Tracing.Information("OAuth2 endpoint called for scope: " + request.Scope);
                }
                catch
                {
                    Tracing.Error("Malformed scope: " + request.Scope);
                    return OAuthErrorResponseMessage(OAuth2Constants.Errors.InvalidScope);
                }
            }

            if (!ValidateClient(out client))
            {
                Tracing.Error("Invalid client: " + ClaimsPrincipal.Current.Identity.Name);
                return OAuthErrorResponseMessage(OAuth2Constants.Errors.InvalidClient);
            }

            // validate grant types against global and client configuration
            if (request.Grant_Type.Equals(OAuth2Constants.GrantTypes.AuthorizationCode))
            {
                if (!ConfigurationRepository.OAuth2.EnableCodeFlow ||
                    !client.AllowCodeFlow)
                {
                    return OAuthErrorResponseMessage(OAuth2Constants.Errors.UnsupportedGrantType);
                }
            }

            if (request.Grant_Type.Equals(OAuth2Constants.GrantTypes.Password))
            {
                if (!ConfigurationRepository.OAuth2.EnableResourceOwnerFlow ||
                    !client.AllowResourceOwnerFlow)
                {
                    return OAuthErrorResponseMessage(OAuth2Constants.Errors.UnsupportedGrantType);
                }
            }

            if (request.Grant_Type.Equals(OAuth2Constants.GrantTypes.RefreshToken))
            {
                if (!client.AllowRefreshToken)
                {
                    return OAuthErrorResponseMessage(OAuth2Constants.Errors.UnsupportedGrantType);
                }
            }

            return null;
        }
        private HttpResponseMessage CreateTokenResponse(string userName, Client client, EndpointReference scope, string tokenType, bool includeRefreshToken)
        {
            var auth = new AuthenticationHelper();

            var principal = auth.CreatePrincipal(userName, "OAuth2",
                    new Claim[]
                        {
                            new Claim(Constants.Claims.Client, client.Name),
                            new Claim(Constants.Claims.Scope, scope.Uri.AbsoluteUri)
                        });

            if (!ClaimsAuthorization.CheckAccess(principal, Constants.Actions.Issue, Constants.Resources.OAuth2))
            {
                Tracing.Error("OAuth2 endpoint authorization failed for user: " + userName);
                return OAuthErrorResponseMessage(OAuth2Constants.Errors.InvalidGrant);
            }

            var sts = new STS();
            TokenResponse tokenResponse;
            if (sts.TryIssueToken(scope, principal, tokenType, out tokenResponse))
            {
                if (includeRefreshToken)
                {
                    tokenResponse.RefreshToken = RefreshTokenRepository.AddCode(CodeTokenType.RefreshTokenIdentifier, client.ID, userName, scope.Uri.AbsoluteUri);
                }

                var resp = Request.CreateResponse<TokenResponse>(HttpStatusCode.OK, tokenResponse);
                return resp;
            }
            else
            {
                return OAuthErrorResponseMessage(OAuth2Constants.Errors.InvalidRequest);
            }
        }
        private HttpResponseMessage ProcessRefreshTokenRequest(Client client, string refreshToken, string tokenType)
        {
            Tracing.Information("Processing refresh token request for client: " + client.Name);

            // 1. get refresh token from DB - if not exists: error
            CodeToken token;
            if (RefreshTokenRepository.TryGetCode(refreshToken, out token))
            {
                // 2. make sure the client is the same - if not: error
                if (token.ClientId == client.ID)
                {
                    // 3. call STS 
                    RefreshTokenRepository.DeleteCode(token.Code);
                    return CreateTokenResponse(token.UserName, client, new EndpointReference(token.Scope), tokenType, includeRefreshToken: client.AllowRefreshToken);
                }

                Tracing.Error("Invalid client for refresh token. " + client.Name + " / " + refreshToken);
                return OAuthErrorResponseMessage(OAuth2Constants.Errors.InvalidGrant);
            }

            Tracing.Error("Refresh token not found. " + client.Name + " / " + refreshToken);
            return OAuthErrorResponseMessage(OAuth2Constants.Errors.InvalidGrant);
        }
        private ActionResult CheckRequest(AuthorizeRequest request, out Client client)
        {
            // validate client
            if (!Clients.TryGetClient(request.client_id, out client))
            {
                ViewBag.Message = "Invalid client_id : " + request.client_id;
                return View("Error");
            }

            // validate redirect uri
            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.";
                return View("Error");
            }

            // 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))
            {
                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))
            {
                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)
            {
                return ClientError(client.RedirectUri, OAuth2Constants.Errors.UnsupportedResponseType, request.response_type, request.state);
            }

            if (request.response_type.Equals(OAuth2Constants.ResponseTypes.Code) &&
                !client.AllowCodeFlow)
            {
                return ClientError(client.RedirectUri, OAuth2Constants.Errors.UnsupportedResponseType, request.response_type, request.state);
            }

            return null;
        }
        private HttpResponseMessage ValidateRequest(TokenRequest request, out Client client)
        {
            client = null;

            if (request == null)
            {
                return OAuthErrorResponseMessage(OAuth2Constants.Errors.InvalidRequest);
            }

            // grant type is required
            if (string.IsNullOrWhiteSpace(request.Grant_Type))
            {
                return OAuthErrorResponseMessage(OAuth2Constants.Errors.UnsupportedGrantType);
            }

            // check supported grant types
            if (!request.Grant_Type.Equals(OAuth2Constants.GrantTypes.AuthorizationCode) &&
                !request.Grant_Type.Equals(OAuth2Constants.GrantTypes.Password) &&
                !request.Grant_Type.Equals(OAuth2Constants.GrantTypes.RefreshToken))
            {
                return OAuthErrorResponseMessage(OAuth2Constants.Errors.UnsupportedGrantType);
            }

            // resource owner password flow requires a well-formed scope
            if (request.Grant_Type.Equals(OAuth2Constants.GrantTypes.Password))
            {
                Uri appliesTo;
                if (!Uri.TryCreate(request.Scope, UriKind.Absolute, out appliesTo))
                {
                    logger.Error("Malformed scope: " + request.Scope);
                    return OAuthErrorResponseMessage(OAuth2Constants.Errors.InvalidScope);
                }

                logger.Info("OAuth2 endpoint called for scope: " + request.Scope);
            }

            if (!ValidateClient(out client))
            {
                logger.Error("Invalid client: " + ClaimsPrincipal.Current.Identity.Name); 
                return OAuthErrorResponseMessage(OAuth2Constants.Errors.InvalidClient);
            }

            // validate grant types against global and client configuration
            if (request.Grant_Type.Equals(OAuth2Constants.GrantTypes.AuthorizationCode))
            {
                if (!ConfigurationRepository.OAuth2.EnableCodeFlow ||
                    !client.AllowCodeFlow) 
                {
                    logger.Error("Code flow not allowed for client");

                    return OAuthErrorResponseMessage(OAuth2Constants.Errors.UnsupportedGrantType);
                }
            }

            if (request.Grant_Type.Equals(OAuth2Constants.GrantTypes.Password))
            {
                if (!ConfigurationRepository.OAuth2.EnableResourceOwnerFlow ||
                    !client.AllowResourceOwnerFlow)
                {

                    logger.Error("Resource owner password flow not allowed for client");

                    return OAuthErrorResponseMessage(OAuth2Constants.Errors.UnsupportedGrantType);
                }
            }

            if (request.Grant_Type.Equals(OAuth2Constants.GrantTypes.RefreshToken))
            {
                if (!client.AllowRefreshToken)
                {

                    logger.Error("Refresh tokens not allowed for client");

                    return OAuthErrorResponseMessage(OAuth2Constants.Errors.UnsupportedGrantType);
                }
            }

            return null;
        }
        private HttpResponseMessage ProcessResourceOwnerCredentialRequest(string userName, string password, EndpointReference appliesTo, string tokenType, Client client)
        {
            Tracing.Information("Starting resource owner password credential flow for client: " + client.Name);

            if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(password))
            {
                Tracing.Error("Invalid resource owner credentials for: " + appliesTo.Uri.AbsoluteUri);
                return OAuthErrorResponseMessage(OAuth2Constants.Errors.InvalidGrant);
            }

            var auth = new AuthenticationHelper();
            ClaimsPrincipal principal;
            if (UserRepository.ValidateUser(userName, password))
            {
                principal = auth.CreatePrincipal(userName, "OAuth2",
                    new Claim[]
                        {
                            new Claim(Constants.Claims.Client, client.Name),
                            new Claim(Constants.Claims.Scope, appliesTo.Uri.AbsoluteUri)
                        });

                if (!ClaimsAuthorization.CheckAccess(principal, Constants.Actions.Issue, Constants.Resources.OAuth2))
                {
                    Tracing.Error("OAuth2 endpoint authorization failed for user: "******"Resource owner credential validation failed: " + userName);
                return OAuthErrorResponseMessage(OAuth2Constants.Errors.InvalidGrant);
            }

            var sts = new STS();
            TokenResponse tokenResponse;
            if (sts.TryIssueToken(appliesTo, principal, tokenType, out tokenResponse))
            {
                var resp = Request.CreateResponse<TokenResponse>(HttpStatusCode.OK, tokenResponse);
                return resp;
            }
            else
            {
                return OAuthErrorResponseMessage(OAuth2Constants.Errors.InvalidRequest);
            }
        }
 private HttpResponseMessage ProcessAuthorizationCodeRequest(Client client, string code, string tokenType)
 {
     return ProcessRefreshTokenRequest(client, code, tokenType);
 }
 private ActionResult HandleAuthorizationCodeGrant(AuthorizeRequest request, Client client)
 {
     throw new System.NotImplementedException();
 }
 public void Update(Client model)
 {
     throw new NotImplementedException();
 }
 public bool TryGetClient(string clientId, out Client client)
 {
     throw new NotImplementedException();
 }
 private HttpResponseMessage ProcessAuthorizationCodeRequest(Client client, string code, string tokenType)
 {
     Tracing.Information("Processing authorization code token request for client: " + client.Name);
     return ProcessCodeTokenRequest(client, code, tokenType);
 }
 private HttpResponseMessage ProcessRefreshTokenRequest(Client client, string refreshToken, string tokenType)
 {
     Tracing.Information("Processing refresh token request for client: " + client.Name);
     return ProcessCodeTokenRequest(client, refreshToken, tokenType);
 }
        public ActionResult Create(Client model)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    this.clientRepository.Create(model);
                    TempData["Message"] = "Client Created";
                    return RedirectToAction("Edit", new { id = model.ID });
                }
                catch (ValidationException ex)
                {
                    ModelState.AddModelError("", ex.Message);
                }
                catch (Exception)
                {
                    ModelState.AddModelError("", "Error creating client.");
                }
            }

            return Edit(model.ID);
        }
        private ActionResult PerformGrant(AuthorizeRequest request, Client client)
        {
            // implicit grant
            if (request.response_type.Equals(OAuth2Constants.ResponseTypes.Token, StringComparison.Ordinal))
            {
                return HandleImplicitGrant(request, client);
            }

            // authorization code grant
            if (request.response_type.Equals(OAuth2Constants.ResponseTypes.Code, StringComparison.Ordinal))
            {
                return HandleAuthorizationCodeGrant(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 HandleImplicitGrant(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 redirectString = string.Format("{0}#access_token={1}&token_type={2}&expires_in={3}",
                        client.RedirectUri.AbsoluteUri,
                        tokenResponse.AccessToken,
                        tokenResponse.TokenType,
                        tokenResponse.ExpiresIn);

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

                return Redirect(redirectString);
            }

            // return right error code
            return Error(client.RedirectUri, OAuth2Constants.Errors.InvalidRequest, request.state);
        }
 private ActionResult PerformGrant(AuthorizeRequest request, Client client)
 {
   if (request.response_type.Equals("token", StringComparison.Ordinal))
     return this.HandleImplicitGrant(request, client);
   if (request.response_type.Equals("code", StringComparison.Ordinal))
     return this.HandleAuthorizationCodeGrant(request, client);
   else
     return (ActionResult) null;
 }
        private bool ValidateClient(out Client client)
        {
            client = null;

            if (!ClaimsPrincipal.Current.Identity.IsAuthenticated)
            {
                Tracing.Error("Anonymous client.");
                return false;
            }

            var passwordClaim = ClaimsPrincipal.Current.FindFirst("password");
            if (passwordClaim == null)
            {
                Tracing.Error("No password provided.");
                return false;
            }

            return ClientsRepository.ValidateAndGetClient(
                ClaimsPrincipal.Current.Identity.Name,
                passwordClaim.Value, 
                out client);
        }
 private ActionResult HandleImplicitGrant(AuthorizeRequest request, Client client)
 {
   TokenResponse response;
   if (!new STS().TryIssueToken(new EndpointReference(request.scope), ClaimsPrincipal.Current, this.Configuration.Global.DefaultHttpTokenType, out response))
     return this.Error(client.RedirectUri, "invalid_request", request.state);
   string str = string.Format("access_token={0}&token_type={1}&expires_in={2}", (object) response.AccessToken, (object) response.TokenType, (object) response.ExpiresIn);
   if (!string.IsNullOrEmpty(request.state))
     str = string.Format("{0}&state={1}", (object) str, (object) request.state);
   return (ActionResult) this.Redirect(string.Format("{0}#{1}", (object) client.RedirectUri.AbsoluteUri, (object) str));
 }
 public OAuthClientViewModel(Client client)
 {
     Container.Current.SatisfyImportsOnce(this);
     this.Client = client;
 }
    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 (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;
    }