/// <summary> Complete the refresh token grant </summary> /// <param name="inputParams">Null unless the input parameters have been manually set</param> /// <returns>FlowResult with the result</returns> /// <exception cref="ClientException"> Thrown if there is something wrong </exception> public override FlowResult CompleteFlow(dynamic inputParams = null) { // Get the required params var authParams = this.AuthServer.GetParam(new[] { "client_id", "client_secret", "refresh_token", "scope" }, HTTPMethod.Post, inputParams); if (string.IsNullOrEmpty(authParams.client_id)) throw new ClientException(HTTPErrorType.invalid_request, "client_id"); if (string.IsNullOrEmpty(authParams.client_secret)) throw new ClientException(HTTPErrorType.invalid_request, "client_secret"); // Validate client ID and client secret var clientDetails = this.AuthServer.Client.GetClient(Identifier, authParams.client_id, authParams.client_secret); if (clientDetails == null) throw new ClientException(HTTPErrorType.invalid_client); authParams.client_details = clientDetails; if (string.IsNullOrEmpty(authParams.refresh_token)) throw new ClientException(HTTPErrorType.invalid_request, "refresh_token"); // Validate refresh token var accessTokenId = this.AuthServer.Session.ValidateRefreshToken(authParams.refresh_token, authParams.client_id); if (accessTokenId == 0) throw new ClientException(HTTPErrorType.invalid_refresh); // Get the existing access token var accessTokenDetails = this.AuthServer.Session.GetAccessToken(accessTokenId); // Get the scopes for the existing access token List<ScopesResponse> scopes = this.AuthServer.Session.GetScopes(accessTokenDetails.AccessToken); // Generate new tokens and associate them to the session var accessToken = SecureKey.Make(); var accessTokenExpiresIn = (this.AccessTokenTTL != 0) ? this.AccessTokenTTL : this.AuthServer.AccessTokenTTL; var accessTokenExpires = DateTime.Now.AddSeconds(accessTokenExpiresIn); // Associate the new access token with the session var newAccessTokenId = this.AuthServer.Session.AssociateAccessToken(accessTokenDetails.SessionID, accessToken, accessTokenExpires); var refreshToken = string.Empty; if (this.RotateRefreshTokens) { // Generate a new refresh token refreshToken = SecureKey.Make(); var refreshTokenExpires = DateTime.Now.AddSeconds(this.RefreshTokenTTL); // Revoke the old refresh token this.AuthServer.Session.RemoveRefreshToken(authParams.refresh_token); // Associate the new refresh token with the new access token this.AuthServer.Session.AssociateRefreshToken(newAccessTokenId, refreshToken, refreshTokenExpires, authParams.client_id.ToString()); } // There isn't a request for reduced scopes so assign the original ones (or we're not rotating scopes) if (string.IsNullOrEmpty(authParams.scope)) { foreach (var scope in scopes) { this.AuthServer.Session.AssociateScope(newAccessTokenId, scope.ID); } } else if (!string.IsNullOrEmpty(authParams.scope) && this.RotateRefreshTokens) { // The request is asking for reduced scopes and rotate tokens is enabled string[] reqestedScopes = authParams.scope.Split(this.AuthServer.ScopeDelimeter); reqestedScopes = reqestedScopes.Where(r => !string.IsNullOrEmpty(r)).Select(r => r.Trim()).ToArray(); // Check that there aren't any new scopes being included var existingScopes = scopes.Select(s => s.Scope).ToList(); foreach (var reqScope in reqestedScopes) { if (!existingScopes.Contains(reqScope)) throw new ClientException(HTTPErrorType.invalid_request, "scope"); // Associate with the new access token var scopeDetails = this.AuthServer.Scope.GetScope(Identifier, reqScope, authParams.client_id); this.AuthServer.Session.AssociateScope(newAccessTokenId, scopeDetails.ID); } } var response = new FlowResult { access_token = accessToken, token_type = "Bearer", access_token_expires = accessTokenExpires, expires_in = accessTokenExpiresIn }; if (this.RotateRefreshTokens) response.refresh_token = refreshToken; return response; }
/// <summary> /// Complete the password grant /// </summary> /// <param name="inputParams">The input parameters</param> /// <returns>FlowResult the completed flow</returns> public override FlowResult CompleteFlow(dynamic inputParams = null) { // Get the required params var authParams = this.AuthServer.GetParam(new[] { "client_id", "client_secret", "username", "password" }, HTTPMethod.Post, inputParams); if (string.IsNullOrEmpty(authParams.client_id)) throw new ClientException(HTTPErrorType.invalid_request, "client_id"); if (string.IsNullOrEmpty(authParams.client_secret)) throw new ClientException(HTTPErrorType.invalid_request, "client_secret"); // Validate client credentials var clientDetails = this.AuthServer.Client.GetClient(Identifier, authParams.client_id, authParams.client_secret); if (clientDetails == null) throw new ClientException(HTTPErrorType.invalid_client); authParams.client_details = clientDetails; if (string.IsNullOrEmpty(authParams.username)) throw new ClientException(HTTPErrorType.invalid_request, "username"); if (string.IsNullOrEmpty(authParams.password)) throw new ClientException(HTTPErrorType.invalid_request, "password"); // Check if user"s username and password are correct if (this.VerifyCredentialsCallback == null) throw new InvalidGrantTypeException(HTTPErrorType.invalid_grant_callback); var userId = this.VerifyCredentialsCallback(authParams.username, authParams.password); if (string.IsNullOrEmpty(userId)) throw new ClientException(HTTPErrorType.invalid_credentials); // Validate any scopes that are in the request string scope = this.AuthServer.GetParam("scope", HTTPMethod.Post, inputParams).ToString(); var scopes = scope.Split(this.AuthServer.ScopeDelimeter); scopes = scopes.Where(s => !string.IsNullOrEmpty(s)).Select(s => s.Trim()).ToArray(); if (this.AuthServer.RequireScopeParam && string.IsNullOrEmpty(this.AuthServer.DefaultScope) && scopes.Length == 0) throw new ClientException(HTTPErrorType.invalid_request, "scope"); if (scopes.Length == 0 && this.AuthServer.DefaultScope != null) { scopes = this.AuthServer.DefaultScope.Split(this.AuthServer.ScopeDelimeter); } var sr = new List<ScopeResponse>(); foreach (var scopeDetails in scopes.Select(s => this.AuthServer.Scope.GetScope(this.Identifier, s, authParams.client_id))) { if (scopeDetails == null) throw new ClientException(HTTPErrorType.invalid_scope, scope); sr.Add(scopeDetails); } authParams.scopes = sr; // Generate an access token var accessToken = SecureKey.Make(); var accessTokenExpiresIn = (this.AccessTokenTTL != 0) ? this.AccessTokenTTL : this.AuthServer.AccessTokenTTL; var accessTokenExpires = DateTime.Now.AddSeconds(accessTokenExpiresIn); // Create a new session var sessionId = this.AuthServer.Session.CreateSession(authParams.client_id, OwnerType.User, userId); // Associate an access token with the session var accessTokenId = this.AuthServer.Session.AssociateAccessToken(sessionId, accessToken, accessTokenExpires); // Associate scopes with the access token foreach (var s in sr) { this.AuthServer.Session.AssociateScope(accessTokenId, s.ID); } var response = new FlowResult { access_token = accessToken, token_type = "Bearer", access_token_expires = accessTokenExpires, expires_in = accessTokenExpiresIn }; // Associate a refresh token if set if (this.AuthServer.HasGrantType(GrantTypIdentifier.refresh_token)) { var refreshToken = SecureKey.Make(); var refreshTokenTTL = DateTime.Now.AddSeconds(((RefreshToken)this.AuthServer.GetGrantType(GrantTypIdentifier.refresh_token)).RefreshTokenTTL); this.AuthServer.Session.AssociateRefreshToken(accessTokenId, refreshToken, refreshTokenTTL, authParams.client_id); response.refresh_token = refreshToken; } return response; }
/// <summary> Complete the auth code grant </summary> /// <param name="inputParams">The input parameters</param> /// <returns>FlowResult with the value of the flow</returns> /// <exception cref="ClientException"> Various client exceptions </exception> public override FlowResult CompleteFlow(dynamic inputParams = null) { // Get the required params var authParams = this.AuthServer.GetParam(new[] { "client_id", "client_secret", "redirect_uri", "code" }, HTTPMethod.Post, inputParams); if (string.IsNullOrEmpty(authParams.client_id)) throw new ClientException(HTTPErrorType.invalid_request, "client_id"); if (string.IsNullOrEmpty(authParams.client_secret)) throw new ClientException(HTTPErrorType.invalid_request, "client_secret"); if (string.IsNullOrEmpty(authParams.redirect_uri)) throw new ClientException(HTTPErrorType.invalid_request, "redirect_uri"); // Validate client ID and redirect URI var clientDetails = this.AuthServer.Client.GetClient(Identifier, authParams.client_id, authParams.client_secret, authParams.redirect_uri); if (clientDetails == null) throw new ClientException(HTTPErrorType.invalid_client); authParams.client_details = clientDetails; // Validate the authorization code if (string.IsNullOrEmpty(authParams.code)) throw new ClientException(HTTPErrorType.invalid_request, "code"); // Verify the authorization code matches the client_id and the request_uri var authCodeDetails = this.AuthServer.Session.ValidateAuthCode(authParams.client_id, authParams.redirect_uri, authParams.code); if (authCodeDetails == null) throw new ClientException(HTTPErrorType.invalid_grant, "code"); // Get any associated scopes var scopes = this.AuthServer.Session.GetAuthCodeScopes(authCodeDetails.AuthcodeID); // A session ID was returned so update it with an access token and remove the authorisation code var accessToken = SecureKey.Make(); var accessTokenExpiresIn = (this.AccessTokenTTL != 0) ? this.AccessTokenTTL : this.AuthServer.AccessTokenTTL; var accessTokenExpires = DateTime.Now.AddSeconds(accessTokenExpiresIn); // Remove the auth code this.AuthServer.Session.RemoveAuthCode(authCodeDetails.SessionID); // Create an access token var accessTokenId = this.AuthServer.Session.AssociateAccessToken(authCodeDetails.SessionID, accessToken, accessTokenExpires); // Associate scopes with the access token if (scopes.Count > 0) { foreach (var scope in scopes) { this.AuthServer.Session.AssociateScope(accessTokenId, scope); } } var response = new FlowResult { access_token = accessToken, token_type = "Bearer", access_token_expires = accessTokenExpires, expires_in = accessTokenExpiresIn }; // Associate a refresh token if set if (this.AuthServer.HasGrantType(GrantTypIdentifier.refresh_token)) { var refreshToken = SecureKey.Make(); var refreshTokenTTL = DateTime.Now.AddSeconds(((RefreshToken)this.AuthServer.GetGrantType(GrantTypIdentifier.refresh_token)).RefreshTokenTTL); this.AuthServer.Session.AssociateRefreshToken(accessTokenId, refreshToken, refreshTokenTTL, authParams.client_id); response.refresh_token = refreshToken; } return response; }