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); }
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 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(); } var vm = new OAuthClientViewModel(client); return View("Edit", vm); }
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 client secret provided."); return false; } return ClientsRepository.ValidateAndGetClient( ClaimsPrincipal.Current.Identity.Name, passwordClaim.Value, out client); }
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)) { Tracing.Error("Malformed scope: " + request.Scope); return OAuthErrorResponseMessage(OAuth2Constants.Errors.InvalidScope); } Tracing.Information("OAuth2 endpoint called for scope: " + request.Scope); } 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) { Tracing.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) { Tracing.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) { Tracing.Error("Refresh tokens not allowed for client"); return OAuthErrorResponseMessage(OAuth2Constants.Errors.UnsupportedGrantType); } } return null; }
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, client.AllowRefreshToken); } Tracing.Error("Resource owner credential validation failed: " + request.UserName); return OAuthErrorResponseMessage(OAuth2Constants.Errors.InvalidGrant); }
private HttpResponseMessage ProcessRefreshTokenRequest(Client client, string refreshToken, string tokenType) { Tracing.Information("Processing refresh token request for client: " + client.Name); return ProcessCodeTokenRequest(client, refreshToken, tokenType); }
private HttpResponseMessage ProcessCodeTokenRequest(Client client, string codeToken, string tokenType) { // 1. get code token from DB - if not exists: error CodeToken token; if (CodeTokenRepository.TryGetCode(codeToken, out token)) { CodeTokenRepository.DeleteCode(token.Code); // 2. make sure the client is the same - if not: error if (token.ClientId == client.ID) { // 3. call STS return CreateTokenResponse(token.UserName, client, new EndpointReference(token.Scope), tokenType, client.AllowRefreshToken); } Tracing.Error("Invalid client for refresh token. " + client.Name + " / " + codeToken); return OAuthErrorResponseMessage(OAuth2Constants.Errors.InvalidGrant); } Tracing.Error("Refresh token not found. " + client.Name + " / " + codeToken); return OAuthErrorResponseMessage(OAuth2Constants.Errors.InvalidGrant); }
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 CreateTokenResponse(string userName, Client client, EndpointReference scope, string tokenType, bool includeRefreshToken) { var auth = new AuthenticationHelper(); var principal = auth.CreatePrincipal(userName, "OAuth2", new[] { 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 = CodeTokenRepository.AddCode(CodeTokenType.RefreshTokenIdentifier, client.ID, userName, scope.Uri.AbsoluteUri); } var resp = Request.CreateResponse(HttpStatusCode.OK, tokenResponse); return resp; } return OAuthErrorResponseMessage(OAuth2Constants.Errors.InvalidRequest); }