public static bool FetchUserInfoFromDatabaseService_ByMethod( IBDatabaseServiceInterface _DatabaseService, IBMemoryServiceInterface _MemoryService, string _Method, out string _UserID, out string _UserEmail, out string _UserName, out BWebServiceResponse _FailureResponse, Action <string> _ErrorMessageAction = null) { _UserID = null; _UserEmail = null; _UserName = null; _FailureResponse = new BWebServiceResponse(); string ReturnedEntryAsString = null; if (!_DatabaseService.GetItem( AuthDBEntry.DBSERVICE_AUTHMETHODS_TABLE(), AuthDBEntry.KEY_NAME_AUTH_DB_ENTRY, new BPrimitiveType(_Method), AuthDBEntry.Properties, out JObject ReturnedObject, _ErrorMessageAction)) { _FailureResponse = BWebResponse.InternalError("Database fetch operation has failed"); return(false); } if (ReturnedObject == null) { _ErrorMessageAction?.Invoke("FetchFromDatabaseService: Given credentials are invalid: " + _Method); _FailureResponse = BWebResponse.Unauthorized("Given credentials are invalid."); return(false); } try { ReturnedEntryAsString = ReturnedObject.ToString(); var ReturnedEntry = JsonConvert.DeserializeObject <AuthDBEntry>(ReturnedEntryAsString); _UserID = ReturnedEntry.UserID; _UserEmail = ReturnedEntry.UserEmail; _UserName = ReturnedEntry.UserName; } catch (Exception e) { _ErrorMessageAction?.Invoke("FetchFromDatabaseService: " + e.Message + ", Trace: " + e.StackTrace); _FailureResponse = BWebResponse.InternalError("Database fetch operation failed."); return(false); } _MemoryService.SetKeyValue(CommonData.MemoryQueryParameters, new Tuple <string, BPrimitiveType>[] { new Tuple <string, BPrimitiveType>(AuthDBEntry.KEY_NAME_AUTH_DB_ENTRY + _Method, new BPrimitiveType(ReturnedEntryAsString)) }, _ErrorMessageAction); return(true); }
private BWebServiceResponse OnRequest_Internal_Logic( JObject ParsedBody, Action <string> _ErrorMessageAction) { var ForUrlPath = (string)ParsedBody["forUrlPath"]; var RequestMethod = (string)ParsedBody["requestMethod"]; var SSOTokenRefreshStatus = Controller_SSOAccessToken.EPerformCheckAndRefreshSuccessStatus.None; var AccessTokenWithTokenType = (string)ParsedBody["authorization"]; string Method; if (AccessTokenWithTokenType.StartsWith("Basic")) { var QueryParameters = new BMemoryQueryParameters() { Domain = Resources_DeploymentManager.Get().GetDeploymentBranchNameEscapedLoweredWithDash().ToUpper(), SubDomain = "SELF_SIGNED_ACCESS_TOKEN_VALIDATION", Identifier = AccessTokenWithTokenType }; var MethodPrimitive = MemoryService.GetKeyValue(QueryParameters, "method", _ErrorMessageAction); if (MethodPrimitive == null) { return(BWebResponse.Unauthorized("Token is invalid. Please re-login.")); } Method = MethodPrimitive.AsString; } else { var AccessTokenManager = new Controller_SSOAccessToken(AccessTokenWithTokenType, DatabaseService, MemoryService, AzureAD_AppID, AzureAD_ClientSecret, SSOSuperAdmins, _ErrorMessageAction); if (AccessTokenManager.PerformCheckAndRefresh( out SSOTokenRefreshStatus, out AccessTokenWithTokenType, out _, out string _EmailAddressWithoutPostfix)) { ParsedBody["authorization"] = AccessTokenWithTokenType; }
private BWebServiceResponse OnRequest_Internal(HttpListenerContext _Context, Action <string> _ErrorMessageAction = null) { if (_Context.Request.HttpMethod != "POST") { _ErrorMessageAction?.Invoke("SSOAzureTokenRefreshRequest: POST method is accepted. But received request method: " + _Context.Request.HttpMethod); return(BWebResponse.MethodNotAllowed("POST method is accepted. But received request method: " + _Context.Request.HttpMethod)); } if (!BWebUtilities.DoesContextContainHeader(out List <string> ClientAuthorizationHeaderValues, out string _, _Context, "client-authorization") || !BUtility.CheckAndGetFirstStringFromList(ClientAuthorizationHeaderValues, out string ClientAuthorization) || ClientAuthorization.Length == 0) { return(BWebResponse.BadRequest("Authorization header must be set validly.")); } //Check and try refresh if expired if (new Controller_SSOAccessToken(ClientAuthorization, DatabaseService, MemoryService, AzureAD_AppID, AzureAD_ClientSecret, SSOSuperAdmins, _ErrorMessageAction) .PerformCheckAndRefresh( out Controller_SSOAccessToken.EPerformCheckAndRefreshSuccessStatus SuccessStatus, out ClientAuthorization, out string UserID, out string EmailAddressWithoutPostfix) && ClientAuthorization != null && ClientAuthorization.Length > 0) { return(BWebResponse.StatusOK("Success.", new JObject() { ["token"] = ClientAuthorization, ["status"] = SuccessStatus == Controller_SSOAccessToken.EPerformCheckAndRefreshSuccessStatus.Refreshed ? "Refreshed" : "AlreadyValid", ["userId"] = UserID, ["email"] = EmailAddressWithoutPostfix })); } return(BWebResponse.Unauthorized("Please re-login.")); }
private bool Parse_FirstLeg_Authentication_Content( string _ResponseContent, out string _AuthorizationCode_From_FirstLeg, out BMemoryQueryParameters _SSOStateUniqueID_QueryParameters, out SSOStateMEntry _SSOState, out string _LocalRedirectUrl_From_FirstLeg, out string _EmailAddress_From_FirstLeg, out string _AzureADUniqueID_From_FirstLeg, out BWebServiceResponse _FailureResponse, Action <string> _ErrorMessageAction) { _AuthorizationCode_From_FirstLeg = null; _SSOStateUniqueID_QueryParameters = new BMemoryQueryParameters(); _SSOState = null; _LocalRedirectUrl_From_FirstLeg = null; _EmailAddress_From_FirstLeg = null; _AzureADUniqueID_From_FirstLeg = null; _FailureResponse = BWebResponse.InternalError(""); _ResponseContent = _ResponseContent.Trim(); //Handle error if (_ResponseContent.StartsWith("error=")) { var ErrorResponse = new JObject() { ["result"] = "failure" }; try { var ErrorFields = _ResponseContent.Split('&'); if (ErrorFields != null && ErrorFields.Length >= 2) { ErrorResponse["error"] = ErrorFields[0].Substring("error=".Length); ErrorResponse["message"] = ErrorFields[1].Substring("error_description=".Length); } } catch (Exception) { } _FailureResponse = BWebResponse.Unauthorized(ErrorResponse.ToString()); return(false); } //Normal flow var Splitted = _ResponseContent.Split('&'); if (Splitted == null || Splitted.Length < 3) { _FailureResponse = BWebResponse.BadRequest("Request body must contain all requested types. Split has failed."); return(false); } string IDToken = null; string StateField = null; for (var i = 0; i < Splitted.Length; i++) { if (Splitted[i].StartsWith("id_token=")) { IDToken = Splitted[i].Substring("id_token=".Length); } else if (Splitted[i].StartsWith("code=")) { _AuthorizationCode_From_FirstLeg = Splitted[i].Substring("code=".Length); } else if (Splitted[i].StartsWith("state=")) { StateField = WebUtility.UrlDecode(Splitted[i].Substring("state=".Length)); } } if (IDToken == null || _AuthorizationCode_From_FirstLeg == null || StateField == null) { _FailureResponse = BWebResponse.BadRequest("Request body must contain all requested types."); return(false); } Splitted = StateField.Split('&'); if (Splitted == null || Splitted.Length < 3) { _FailureResponse = BWebResponse.BadRequest("State field must contain all mandatory entries. Split has failed."); return(false); } bool bSSOStateUniqueID_QueryParameters_Set = false; string TenantName = null; for (var i = 0; i < Splitted.Length; i++) { if (Splitted[i].StartsWith("redirect_url=")) { _LocalRedirectUrl_From_FirstLeg = WebUtility.UrlDecode(Splitted[i].Substring("redirect_url=".Length)); } else if (Splitted[i].StartsWith("tenant=")) { TenantName = Splitted[i].Substring("tenant=".Length); } else if (Splitted[i].StartsWith("state=")) { _SSOStateUniqueID_QueryParameters = SSOStateMEntry.ID_SSO_STATE_MEMORY_SERVICE_KEY(Splitted[i].Substring("state=".Length)); bSSOStateUniqueID_QueryParameters_Set = true; } } if (_LocalRedirectUrl_From_FirstLeg == null || TenantName == null || !bSSOStateUniqueID_QueryParameters_Set) { _FailureResponse = BWebResponse.BadRequest("State field must contain all mandatory entries."); return(false); } var Serialized = MemoryService.GetKeyValue(_SSOStateUniqueID_QueryParameters, SSOStateMEntry.HASH_KEY, _ErrorMessageAction); if (Serialized == null) { _FailureResponse = BWebResponse.Unauthorized("Login prompt session has expired. Please try again."); return(false); } try { _SSOState = JsonConvert.DeserializeObject <SSOStateMEntry>(Serialized.AsString); if (_SSOState == null) { throw new NullReferenceException(); } } catch (Exception e) { _ErrorMessageAction?.Invoke("Error: SSOLoginCallback->Parse_FirstLeg_Authentication_Content: Invalid session state. Message: " + e.Message + ", trace: " + e.StackTrace); _FailureResponse = BWebResponse.InternalError("Invalid session state. Please try again."); return(false); } if (_SSOState.Status != SSOStateMEntry.STATUS_AUTHENTICATING) { _FailureResponse = BWebResponse.Unauthorized("Invalid SSO state. Please try again."); return(false); } if (TenantName != _SSOState.TenantName) { _FailureResponse = BWebResponse.Unauthorized("SSO state - request tenant mismatch. Please try again."); return(false); } var JWTHandler = new JwtSecurityTokenHandler(); JwtSecurityToken Token = null; try { Token = JWTHandler.ReadJwtToken(IDToken); } catch (Exception e) { _ErrorMessageAction?.Invoke("Error: SSOLoginCallback->Parse_FirstLeg_Authentication_Content: Invalid JWT token. Token: " + IDToken + ", message: " + e.Message + ", trace: " + e.StackTrace); _FailureResponse = BWebResponse.BadRequest("Invalid JWT token."); return(false); } if (!Token.Payload.TryGetValue("email", out object EmailObject)) { _FailureResponse = BWebResponse.BadRequest("JWT token does not contain email in the payload."); return(false); } _EmailAddress_From_FirstLeg = ((string)EmailObject).ToLower(); if (!Token.Payload.TryGetValue("sub", out object AzureADUserUniqueIDObject)) { _FailureResponse = BWebResponse.BadRequest("JWT token does not contain sub in the payload."); return(false); } _AzureADUniqueID_From_FirstLeg = ((string)AzureADUserUniqueIDObject).ToLower(); return(true); }
private bool AccessCheck(out BWebServiceResponse _FailureResponse, out bool _bSSOTokenRefreshed, out string _NewSSOTokenAfterRefresh, HttpListenerContext _Context, Action <string> _ErrorMessageAction = null) { _FailureResponse = new BWebServiceResponse(); _bSSOTokenRefreshed = false; _NewSSOTokenAfterRefresh = ""; if (bAuthCheck) { //Check for authorization header if (!BWebUtilities.DoesContextContainHeader(out List <string> Authorization, out string _, _Context, "authorization")) { _FailureResponse = BWebResponse.Unauthorized("Authorization header must be set."); return(false); } var RequestObject = new JObject() { ["forUrlPath"] = _Context.Request.RawUrl, ["requestMethod"] = _Context.Request.HttpMethod }; if (BUtility.CheckAndGetFirstStringFromList(Authorization, out string _Authorization)) { RequestObject["authorization"] = _Authorization; } else //Zero length { _FailureResponse = BWebResponse.Unauthorized("Authorization header must be set."); return(false); } GetTracingService()?.On_FromGatewayToService_Sent(_Context, _ErrorMessageAction); var Result = BWebServiceExtraUtilities.InterServicesRequest(new BWebServiceExtraUtilities.InterServicesRequestRequest() { DestinationServiceUrl = AuthServiceBaseUrl + "/auth/access_check", RequestMethod = "POST", ContentType = "application/json", Content = new BStringOrStream(RequestObject.ToString()), bWithAuthToken = true, UseContextHeaders = _Context, }, false, _ErrorMessageAction); GetTracingService()?.On_FromServiceToGateway_Received(_Context, _ErrorMessageAction); if (!Result.bSuccess || Result.ResponseCode >= 400) { if (Result.ResponseCode == BWebResponse.Error_Unauthorized_Code || Result.ResponseCode == BWebResponse.Error_Forbidden_Code) { _FailureResponse = new BWebServiceResponse(Result.ResponseCode, Result.Content, Result.ContentType); return(false); } _ErrorMessageAction?.Invoke("Access check internal call has failed: Response: " + Result.ResponseCode + " -> " + Result.Content.String + ", Request: " + RequestObject.ToString()); _FailureResponse = BWebResponse.InternalError("Internal access check call has failed."); return(false); } var ResponseContent = Result.Content.ToString(); try { var Parsed = JObject.Parse(ResponseContent); Authenticated_UserID = (string)Parsed["userId"]; Authenticated_UserName = (string)Parsed["userName"]; Authenticated_UserEmail = (string)Parsed["userEmail"]; Authenticated_AuthMethodKey = (string)Parsed["authMethodKey"]; _bSSOTokenRefreshed = (bool)Parsed["ssoTokenRefreshed"]; _NewSSOTokenAfterRefresh = (string)Parsed["newSSOTokenAfterRefresh"]; } catch (Exception e) { _ErrorMessageAction?.Invoke("HandleRequest->AccessCheck: Error during content parse: " + ResponseContent + ", Message: " + e.Message + ", Trace: " + e.StackTrace); _FailureResponse = BWebResponse.InternalError("Request has failed due to an internal api gateway error."); return(false); } _Context.Request.Headers.Set("authorized-u-id", Authenticated_UserID); _Context.Request.Headers.Set("authorized-u-name", Authenticated_UserName); _Context.Request.Headers.Set("authorized-u-email", Authenticated_UserEmail); _Context.Request.Headers.Set("authorized-u-auth-key", Authenticated_AuthMethodKey); } return(true); }