示例#1
0
        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);
        }
示例#2
0
        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;
                }
示例#3
0
        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."));
        }
示例#4
0
        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);
        }
示例#5
0
        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);
        }