Example #1
0
        protected virtual void CreateAuthTokenAndSendResponse(CustomAuthenticationResult customAuthResult, AuthenticateRequest authRequest,
                                                              SendParameters sendParameters, AuthSettings authSettings, OperationResponse operationResponse)
        {
            var app = (MasterApplication)ApplicationBase.Instance;

            this.unencryptedAuthToken = app.TokenCreator.CreateAuthenticationToken(
                authRequest,
                authSettings,
                this.UserId,
                customAuthResult.AuthCookie);

            operationResponse.Parameters.Add((byte)ParameterCode.Token, this.GetEncryptedAuthenticationToken(authRequest));

            if (customAuthResult.Data != null)
            {
                operationResponse.Parameters.Add((byte)ParameterCode.Data, customAuthResult.Data);
            }
            if (customAuthResult.Nickname != null)
            {
                operationResponse.Parameters.Add((byte)ParameterCode.Nickname, customAuthResult.Nickname);
            }

            operationResponse.Parameters.Add((byte)ParameterCode.UserId, this.UserId);

            this.SendOperationResponse(operationResponse, sendParameters);
        }
        public virtual void OnCustomAuthenticationResult(CustomAuthenticationResult customAuthResult, IAuthenticateRequest authenticateRequest, SendParameters sendParameters, object state)
        {
            var authSettings = (AuthSettings)state;

            this.RequestFiber.Enqueue(() => this.DoCustomAuthenticationResult(customAuthResult, authenticateRequest,
                                                                              sendParameters, authSettings));
        }
Example #3
0
        private void IncrementResultCounters(CustomAuthenticationResult customAuthResult, CustomAuthResultCounters.Instance instance)
        {
            switch (customAuthResult.ResultCode)
            {
            case CustomAuthenticationResultCode.Data:
                this.TotalInstance.IncrementCustomAuthResultData();
                instance.IncrementCustomAuthResultData();
                break;

            case CustomAuthenticationResultCode.Ok:
                this.TotalInstance.IncrementCustomAuthResultSuccess();
                instance.IncrementCustomAuthResultSuccess();
                break;

            default:    //CustomAuthenticationResultCode.Failed, CustomAuthenticationResultCode.ParameterInvalid
                this.TotalInstance.IncrementCustomAuthResultFailed();
                instance.IncrementCustomAuthResultFailed();
                break;
            }
        }
        protected virtual void HandleCustomAuthenticateResult(CustomAuthenticationResult customAuthResult, IAuthenticateRequest authenticateRequest, SendParameters sendParameters, AuthSettings authSettings)
        {
            //try to get the master server instance for the specified application id


            PhotonEndpointInfo masterServer;
            string             message;

            if (!this.application.ServerCache.TryGetPhotonEndpoint(authenticateRequest.Region, out masterServer, out message))
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat(
                        "MasterServer not found for service type {2}: {3}",
                        authenticateRequest.Region,
                        message);
                }

                var errorResponse = new OperationResponse(GetAuthOpCode(this.authOnceUsed))
                {
                    ReturnCode   = (short)ErrorCode.InvalidRegion,
                    DebugMessage = string.Format("No connections allowed on region {0}.", authenticateRequest.Region)
                };

                this.SendOperationResponse(errorResponse, sendParameters);
                return;
            }

            var    nameServerAuthRequest = (AuthenticateRequest)authenticateRequest;
            var    isAuthOnceUsed        = nameServerAuthRequest.OperationRequest.OperationCode != (byte)OperationCode.Authenticate;
            var    endpointProtocol      = isAuthOnceUsed ? (NetworkProtocolType)((AuthOnceRequest)nameServerAuthRequest).Protocol : this.NetworkProtocol;
            string masterEndPoint;

            //tmp webrtc
            try
            {
                masterEndPoint = masterServer.GetEndPoint(endpointProtocol, this.LocalPort,
                                                          isIPv6: this.LocalIPAddressIsIPv6, useHostnames: this.IsIPv6ToIPv4Bridged);
            }
            catch (Exception e)
            {
                masterEndPoint = masterServer.GetEndPoint(endpointProtocol, 0);

                var str = string.Format(
                    "Custom Auth: Exception during GetEndPoint call. EndPoint protocol:{0}, LocalPort:{1}, isIpV6:{2}, useHostNames:{3}",
                    endpointProtocol, this.LocalPort, this.LocalIPAddressIsIPv6, this.IsIPv6ToIPv4Bridged);

                log.Warn(exceptionGuard, str, e);
            }

            if (masterEndPoint == null)
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Master server endpoint for protocol {0} not found for master server {1}.", this.NetworkProtocol, masterServer);
                }

                var errorResponse = new OperationResponse(GetAuthOpCode(this.authOnceUsed))
                {
                    ReturnCode   = (short)AuthErrorCode.ProtocolNotSupported,
                    DebugMessage = ErrorMessages.ProtocolNotSupported
                };

                this.SendOperationResponse(errorResponse, sendParameters);
                return;
            }

            string userid;

            // the userid can be set
            if (!string.IsNullOrEmpty(customAuthResult.UserId))
            {
                // by authentication service <<< overides client
                userid = customAuthResult.UserId;
            }
            else if (!string.IsNullOrEmpty(authenticateRequest.UserId))
            {
                // or through the client
                userid = authenticateRequest.UserId;
            }
            else
            {
                // we generate a userid
                userid = Guid.NewGuid().ToString();
            }

            // create auth token
            var unencryptedToken = this.application.TokenCreator.CreateAuthenticationToken(
                authenticateRequest, new AuthSettings(), userid, customAuthResult.AuthCookie);

            var authToken = this.GetEncryptedAuthToken(unencryptedToken);

            var authResponse = new AuthenticateResponse
            {
                MasterEndpoint      = masterEndPoint,
                AuthenticationToken = authToken,
                Data           = customAuthResult.Data,
                Nickname       = customAuthResult.Nickname,
                UserId         = userid,
                EncryptionData = GetEncryptionData(unencryptedToken),
            };

            var operationResponse = new OperationResponse(GetAuthOpCode(this.authOnceUsed), authResponse);

            this.SendOperationResponse(operationResponse, sendParameters);
        }
        protected virtual void DoCustomAuthenticationResult(CustomAuthenticationResult customAuthResult, IAuthenticateRequest authenticateRequest, SendParameters sendParameters, AuthSettings authSettings)
        {
            if (customAuthResult == null)
            {
                log.WarnFormat("Custom authentication error. customAuthResult is null. appId={0}/{1}",
                               authenticateRequest.ApplicationId, authenticateRequest.ApplicationVersion);
                return;
            }

            try
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat(
                        "DoCustomAuthenticationResult: appId={0}, resultCode={1}, message={2}, client connected:{3}",
                        authenticateRequest.ApplicationId,
                        customAuthResult.ResultCode,
                        customAuthResult.Message,
                        this.Connected);
                }

                if (!this.Connected)
                {
                    return;
                }

                OperationResponse operationResponse;

                switch (customAuthResult.ResultCode)
                {
                default:
                    operationResponse = new OperationResponse(GetAuthOpCode(this.authOnceUsed))
                    {
                        ReturnCode   = (short)ErrorCode.CustomAuthenticationFailed,
                        DebugMessage = customAuthResult.Message
                    };
                    this.SendOperationResponse(operationResponse, new SendParameters());
                    return;

                case CustomAuthenticationResultCode.Data:
                    var auth = new AuthenticateResponse {
                        Data = customAuthResult.Data
                    };
                    operationResponse = new OperationResponse(GetAuthOpCode(this.authOnceUsed), auth);
                    this.SendOperationResponse(operationResponse, sendParameters);
                    return;

                case CustomAuthenticationResultCode.Ok:
                    this.HandleCustomAuthenticateResult(customAuthResult, authenticateRequest, sendParameters, authSettings);
                    return;
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
                var errorResponse = new OperationResponse(GetAuthOpCode(this.authOnceUsed))
                {
                    ReturnCode   = (short)ErrorCode.InternalServerError,
                    DebugMessage = ex.Message,
                };
                this.SendOperationResponse(errorResponse, sendParameters);
            }
        }
Example #6
0
        private void AuthQueueResponseCallback(AsyncHttpResponse response, ClientAuthenticationQueue queue)
        {
            var queueState     = (AuthQueueState)response.State;
            var peer           = queueState.Peer;
            var authRequest    = queueState.AuthenticateRequest;
            var sendParameters = queueState.SendParameters;

            if (log.IsDebugEnabled)
            {
                log.DebugFormat("Authenticate client finished: conId={0}, result={1}", peer.ConnectionId, response.Status);
            }

            switch (response.Status)
            {
            case HttpRequestQueueResultCode.Success:
            {
                if (response.ResponseData == null)
                {
                    log.ErrorFormat("Custom authentication: failed. ResponseData is empty. AppId={0}/{1}",
                                    authRequest.ApplicationId, authRequest.ApplicationId);

                    return;
                }

                // deserialize
                var responseString = Encoding.UTF8.GetString(response.ResponseData).Trim(new char[] { '\uFEFF', '\u200B' });
                CustomAuthenticationResult customAuthResult;
                try
                {
                    customAuthResult = Newtonsoft.Json.JsonConvert.DeserializeObject <CustomAuthenticationResult>(responseString);
                    //TBD: handle backward compatibility incustomAuthResult class
                    if (customAuthResult.AuthCookie == null)
                    {
                        customAuthResult.AuthCookie = customAuthResult.Secure;
                    }
                }
                catch (Exception ex)
                {
                    log.WarnFormat("Custom authentication: failed to deserialize response. AppId={0}/{1}, Response={2}, Uri={3}",
                                   authRequest.ApplicationId, authRequest.ApplicationVersion, responseString, queue.Uri);

                    peer.OnCustomAuthenticationError(
                        ErrorCode.CustomAuthenticationFailed, "Custom authentication deserialization failed: " + ex.Message, authRequest, sendParameters, queueState.State);
                    this.IncrementFailedCustomAuth();
                    return;
                }

                this.IncrementResultCounters(customAuthResult, (CustomAuthResultCounters.Instance)queue.CustomData);
                peer.OnCustomAuthenticationResult(customAuthResult, authRequest, sendParameters, queueState.State);
                return;
            }

            case HttpRequestQueueResultCode.Offline:
            case HttpRequestQueueResultCode.QueueFull:
            case HttpRequestQueueResultCode.QueueTimeout:
            case HttpRequestQueueResultCode.RequestTimeout:
            case HttpRequestQueueResultCode.Error:
            {
                if (response.RejectIfUnavailable)
                {
                    peer.OnCustomAuthenticationError(
                        ErrorCode.CustomAuthenticationFailed, "Custom authentication service error: " + response.Status, authRequest, sendParameters, queueState.State);
                    this.IncrementFailedCustomAuth();
                }
                else
                {
                    var result = new CustomAuthenticationResult {
                        ResultCode = CustomAuthenticationResultCode.Ok
                    };
                    peer.OnCustomAuthenticationResult(result, authRequest, sendParameters, queueState.State);
                }
                return;
            }
            }
        }
Example #7
0
        protected virtual void OnAuthenticateClient(ICustomAuthPeer peer, IAuthenticateRequest authRequest, AuthSettings authSettings, SendParameters sendParameters, object state)
        {
            try
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Authenticating client {0} - custom authentication type: {1}",
                                    peer.ConnectionId,
                                    authRequest.ClientAuthenticationType);
                }

                // when authentication data is provided check if
                // it is either a byte array or string and convert to byte array
                // if it's a string value
                byte[] authData = null;
                if (authRequest.ClientAuthenticationData != null)
                {
                    authData = authRequest.ClientAuthenticationData as byte[];
                    if (authData == null)
                    {
                        var stringData = authRequest.ClientAuthenticationData as string;
                        if (stringData == null)
                        {
                            peer.OnCustomAuthenticationError(
                                ErrorCode.CustomAuthenticationFailed,
                                "Authentication data type not supported",
                                authRequest,
                                sendParameters,
                                state);

                            this.IncrementFailedCustomAuth();
                            return;
                        }

                        authData = Encoding.UTF8.GetBytes(stringData);
                    }
                }

                if (string.IsNullOrEmpty(authRequest.ClientAuthenticationParams) && authData == null && this.isAnonymousAccessAllowed)
                {
                    // instant callback - treat as anonymous user:
                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("Authenticate client: grant access as anonymous user: conId={0}", peer.ConnectionId);
                    }

                    var customResult = new CustomAuthenticationResult {
                        ResultCode = CustomAuthenticationResultCode.Ok
                    };
                    peer.OnCustomAuthenticationResult(customResult, authRequest, sendParameters, state);
                    return;
                }

                // take auth type from auth request (default: custom)
                var authenticationType = (ClientAuthenticationType)authRequest.ClientAuthenticationType;

                ClientAuthenticationQueue authQueue;
                if (this.authenticationServices.TryGetValue(authenticationType, out authQueue) == false)
                {
                    if (log.IsWarnEnabled)
                    {
                        log.WarnFormat("Authentication type not supported: {0} for AppId={1}/{2}", authenticationType,
                                       authRequest.ApplicationId, authRequest.ApplicationVersion);
                    }

                    peer.OnCustomAuthenticationError(
                        ErrorCode.CustomAuthenticationFailed,
                        "Authentication type not supported",
                        authRequest,
                        sendParameters,
                        state);
                    this.IncrementFailedCustomAuth();
                    return;
                }

                var queueState = new AuthQueueState(peer, authRequest, sendParameters, state);
                authQueue.EnqueueRequest(authRequest.ClientAuthenticationParams, authData, this.AuthQueueResponseCallback, queueState);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }
        private void AuthQueueResponseCallback(AsyncHttpResponse response, ClientAuthenticationQueue queue)
        {
            var queueState = (AuthQueueState)response.State;
            var peer = queueState.Peer;
            var authRequest = queueState.AuthenticateRequest;
            var sendParameters = queueState.SendParameters;

            if (log.IsDebugEnabled)
            {
                log.DebugFormat("Authenticate client finished: conId={0}, result={1}", peer.ConnectionId, response.Status);
            }

            switch (response.Status)
            {
                case HttpRequestQueueResultCode.Success:
                    {
                        if (response.ResponseData == null)
                        {
                            log.ErrorFormat("Custom authentication: failed. ResponseData is empty. AppId={0}/{1}",
                                authRequest.ApplicationId, authRequest.ApplicationId);

                            return;
                        }

                        // deserialize
                        var responseString = Encoding.UTF8.GetString(response.ResponseData).Trim(new char[] { '\uFEFF', '\u200B' });
                        CustomAuthenticationResult customAuthResult;
                        try
                        {
                            customAuthResult = Newtonsoft.Json.JsonConvert.DeserializeObject<CustomAuthenticationResult>(responseString);
                            //TBD: handle backward compatibility incustomAuthResult class
                            if (customAuthResult.AuthCookie == null)
                            {
                                customAuthResult.AuthCookie = customAuthResult.Secure;
                            }
                        }
                        catch (Exception ex)
                        {
                            log.WarnFormat("Custom authentication: failed to deserialize response. AppId={0}/{1}, Response={2}, Uri={3}",
                                authRequest.ApplicationId, authRequest.ApplicationVersion, responseString, queue.Uri);

                            peer.OnCustomAuthenticationError(
                                ErrorCode.CustomAuthenticationFailed, "Custom authentication deserialization failed: " + ex.Message, authRequest, sendParameters, queueState.State);
                            this.IncrementFailedCustomAuth();
                            return;
                        }

                        this.IncrementResultCounters(customAuthResult, (CustomAuthResultCounters.Instance)queue.CustomData);
                        peer.OnCustomAuthenticationResult(customAuthResult, authRequest, sendParameters, queueState.State);
                        return;
                    }

                case HttpRequestQueueResultCode.Offline:
                case HttpRequestQueueResultCode.QueueFull:
                case HttpRequestQueueResultCode.QueueTimeout:
                case HttpRequestQueueResultCode.RequestTimeout:
                case HttpRequestQueueResultCode.Error:
                    {
                        if (response.RejectIfUnavailable)
                        {
                            peer.OnCustomAuthenticationError(
                                ErrorCode.CustomAuthenticationFailed, "Custom authentication service error: " + response.Status, authRequest, sendParameters, queueState.State);
                            this.IncrementFailedCustomAuth();
                        }
                        else
                        {
                            var result = new CustomAuthenticationResult { ResultCode = CustomAuthenticationResultCode.Ok };
                            peer.OnCustomAuthenticationResult(result, authRequest, sendParameters, queueState.State);
                        }
                        return;
                    }
            }
        }
        private void DoCustomAuthenticationResult(CustomAuthenticationResult customAuthResult, 
            AuthenticateRequest authRequest, SendParameters sendParameters, AuthSettings customAuthSettings)
        {
            if (this.Connected == false)
            {
                return;
            }

            try
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Client custom authentication callback: result={0}, msg={1}, userId={2}",
                        customAuthResult.ResultCode,
                        customAuthResult.Message,
                        this.UserId);
                }

                var operationResponse = new OperationResponse((byte)Hive.Operations.OperationCode.Authenticate)
                {
                    DebugMessage = customAuthResult.Message,
                    Parameters = new Dictionary<byte, object>()
                };

                switch (customAuthResult.ResultCode)
                {
                    default:
                        operationResponse.ReturnCode = (short)Photon.Common.ErrorCode.CustomAuthenticationFailed;
                        this.SendOperationResponse(operationResponse, sendParameters);
                        this.SetCurrentOperationHandler(OperationHandlerInitial.Instance);
                        return;

                    case CustomAuthenticationResultCode.Data:
                        operationResponse.Parameters = new Dictionary<byte, object> { { (byte)ParameterCode.Data, customAuthResult.Data } };
                        this.SendOperationResponse(operationResponse, sendParameters);
                        this.SetCurrentOperationHandler(OperationHandlerInitial.Instance);
                        return;

                    case CustomAuthenticationResultCode.Ok:
                        //apply user id from custom auth result
                        if (!string.IsNullOrEmpty(customAuthResult.UserId))
                        {
                            this.UserId = customAuthResult.UserId;
                        }
                        else if (!string.IsNullOrEmpty(authRequest.UserId))
                        {
                            this.UserId = authRequest.UserId;
                        }
                        else
                        {
                            this.UserId = Guid.NewGuid().ToString();
                        }
                        // create auth token and send response
                        this.CreateAuthTokenAndSendResponse(customAuthResult, authRequest, sendParameters, customAuthSettings, operationResponse);
                        this.SetCurrentOperationHandler(OperationHandlerDefault.Instance);
                        this.OnAuthSuccess(authRequest);
                        break;
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
                var errorResponse = new OperationResponse((byte)Hive.Operations.OperationCode.Authenticate) { ReturnCode = (short)ErrorCode.InternalServerError };
                this.SendOperationResponse(errorResponse, sendParameters);
                this.SetCurrentOperationHandler(OperationHandlerInitial.Instance);
            }
        }
 public override void OnCustomAuthenticationResult(CustomAuthenticationResult customAuthResult, IAuthenticateRequest authenticateRequest,
     SendParameters sendParameters, object state)
 {
     base.OnCustomAuthenticationResult(customAuthResult, authenticateRequest, sendParameters, state);
 }
        protected virtual void CreateAuthTokenAndSendResponse(CustomAuthenticationResult customAuthResult, AuthenticateRequest authRequest,
            SendParameters sendParameters, AuthSettings authSettings, OperationResponse operationResponse)
        {
            var app = (MasterApplication)ApplicationBase.Instance;
            this.unencryptedAuthToken = app.TokenCreator.CreateAuthenticationToken(
                authRequest,
                authSettings,
                this.UserId,
                customAuthResult.AuthCookie);

            operationResponse.Parameters.Add((byte) ParameterCode.Token, this.GetEncryptedAuthenticationToken(authRequest));
            operationResponse.Parameters.Add((byte) ParameterCode.Data, customAuthResult.Data);
            operationResponse.Parameters.Add((byte)ParameterCode.Nickname, customAuthResult.Nickname);
            operationResponse.Parameters.Add((byte)ParameterCode.UserId, this.UserId);
            this.SendOperationResponse(operationResponse, sendParameters);
        }
 public virtual void OnCustomAuthenticationResult(CustomAuthenticationResult customAuthResult, IAuthenticateRequest authenticateRequest,
                                          SendParameters sendParameters, object state)
 {
     var authRequest = (AuthenticateRequest)authenticateRequest;
     var authSettings = (AuthSettings)state;
     this.RequestFiber.Enqueue(() => this.DoCustomAuthenticationResult(customAuthResult, authRequest, sendParameters, authSettings));
 }
 private void IncrementResultCounters(CustomAuthenticationResult customAuthResult, CustomAuthResultCounters.Instance instance)
 {
     switch (customAuthResult.ResultCode)
     {
         case CustomAuthenticationResultCode.Data:
             this.TotalInstance.IncrementCustomAuthResultData();
             instance.IncrementCustomAuthResultData();
             break;
         case CustomAuthenticationResultCode.Ok:
             this.TotalInstance.IncrementCustomAuthResultSuccess();
             instance.IncrementCustomAuthResultSuccess();
             break;
         default://CustomAuthenticationResultCode.Failed, CustomAuthenticationResultCode.ParameterInvalid
             this.TotalInstance.IncrementCustomAuthResultFailed();
             instance.IncrementCustomAuthResultFailed();
             break;
     }
 }
        protected override void HandleCustomAuthenticateResult(CustomAuthenticationResult customAuthResult, IAuthenticateRequest authenticateRequest, SendParameters sendParameters, AuthSettings authSettings)
        {
            var appAccount = (ApplicationAccount)authSettings;
            // try to get the master server instance for the specified application id
            CloudPhotonEndpointInfo masterServer;
            string message;

            if (
                !((PhotonCloudApp)this.application).CloudCache.TryGetPhotonEndpoint(
                    authenticateRequest,
                    appAccount,
                    out masterServer,
                    out message))
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat(
                        "MasterServer not found for region {0} on cloud {1} / service type {2}: {3}",
                        authenticateRequest.Region,
                        appAccount.PrivateCloud,
                        appAccount.ServiceType,
                        message);
                }

                var errorResponse = new OperationResponse(GetAuthOpCode(this.authOnceUsed))
                {
                    ReturnCode   = (short)ErrorCode.InvalidRegion,
                    DebugMessage = string.Format("No connections allowed on region {0}.", authenticateRequest.Region)
                };

                this.SendOperationResponse(errorResponse, sendParameters);
                this.ScheduleDisconnect(this.GetDisconnectTime());
                return;
            }

            // TODO: V2: check if the master server is connected.
            // if (masterServer.IsOnline == false)
            // {
            // var opResponse = new OperationResponse { OperationCode = (byte)OperationCode.Authenticate, ReturnCode = (int)AuthenticationErrorCode.ApplicationOffline };
            // this.SendOperationResponse(opResponse, sendParameters);
            // return;
            // }

            var endpointProtocol = this.authOnceUsed
                ? (NetworkProtocolType)((Photon.NameServer.Operations.AuthOnceRequest)authenticateRequest).Protocol
                : this.NetworkProtocol;

            var masterEndPoint = masterServer.GetEndPoint(endpointProtocol, this.LocalPort,
                                                          isIPv6: this.LocalIPAddressIsIPv6, useHostnames: this.IsIPv6ToIPv4Bridged);

            if (masterEndPoint == null)
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Master server endpoint for protocol {0} not found for master server {1}.", endpointProtocol, masterServer);
                }

                var errorResponse = new OperationResponse(GetAuthOpCode(this.authOnceUsed))
                {
                    ReturnCode   = (short)AuthErrorCode.ProtocolNotSupported,
                    DebugMessage = ErrorMessages.ProtocolNotSupported
                };

                this.SendOperationResponse(errorResponse, sendParameters);
                this.ScheduleDisconnect(this.GetDisconnectTime());
                return;
            }

            string userid;

            // the userid can be set
            if (!string.IsNullOrEmpty(customAuthResult.UserId))
            {
                // by authentication service <<< overides client
                userid = customAuthResult.UserId;
            }
            else if (!string.IsNullOrEmpty(authenticateRequest.UserId))
            {
                // or through the client
                userid = authenticateRequest.UserId;
            }
            else
            {
                // we generate a userid
                userid = Guid.NewGuid().ToString();
            }

            // create auth token
            var unencryptedToken = this.application.TokenCreator.CreateAuthenticationToken(
                authenticateRequest, appAccount, userid, customAuthResult.AuthCookie);

            if (customAuthResult.ExpireAt.HasValue)
            {
                unencryptedToken.ExpireAtTicks = (UnixStart + TimeSpan.FromSeconds(customAuthResult.ExpireAt.Value)).Ticks;
            }
            else if (authenticateRequest.ClientAuthenticationType == (byte)ClientAuthenticationType.Xbox)
            {
                log.Debug(xboxCustomAuthLogGuard, "Custom auth response for XBox does not contain ExpireAt");
            }

            var authToken = this.GetEncryptedAuthToken(unencryptedToken, masterServer);

            this.CheckEncryptedToken(authToken, authenticateRequest, appAccount, masterServer);

            var authResponse = new AuthenticateResponse
            {
                MasterEndpoint      = masterEndPoint,
                AuthenticationToken = authToken,
                Data           = customAuthResult.Data,
                Nickname       = customAuthResult.Nickname,
                UserId         = userid,
                EncryptionData = this.authOnceUsed ? GetEncryptionData(unencryptedToken) : null,
                Cluster        = masterServer.Cluster
            };

            var operationResponse = new OperationResponse(GetAuthOpCode(this.authOnceUsed), authResponse);

            this.SendOperationResponse(operationResponse, sendParameters);
        }
        protected virtual void OnAuthenticateClient(ICustomAuthPeer peer, IAuthenticateRequest authRequest, AuthSettings authSettings, SendParameters sendParameters, object state)
        {
            try
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Authenticating client {0} - custom authentication type: {1}",
                                    peer.ConnectionId,
                                    authRequest.ClientAuthenticationType);
                }

                // when authentication data is provided check if
                // it is either a byte array or string and convert to byte array
                // if it's a string value
                byte[] authData = null;
                if (authRequest.ClientAuthenticationData != null)
                {
                    authData = authRequest.ClientAuthenticationData as byte[];
                    if (authData == null)
                    {
                        var stringData = authRequest.ClientAuthenticationData as string;
                        if (stringData == null)
                        {
                            peer.OnCustomAuthenticationError(
                                ErrorCode.CustomAuthenticationFailed,
                                "Authentication data type not supported",
                                authRequest,
                                sendParameters,
                                state);

                            this.IncrementFailedCustomAuth();
                            return;
                        }

                        authData = Encoding.UTF8.GetBytes(stringData);
                    }
                }

                //Test auth custom
                bool teste = true;

                if (teste)
                {
                    string authpar = authRequest.ClientAuthenticationParams;


                    log.Debug("Douglas teste authpar :: CustomAuthHandler.cs :: authpar :: ");


                    object  parms = sendParameters;
                    JObject o     = (JObject)JToken.FromObject(parms);
                    foreach (var item in o)
                    {
                        log.Debug("Douglas teste sendParameters :: CustomAuthHandler.cs :: item.Key [" + item.Key + "] item.Value[" + item.Value + "]");
                    }

                    log.Debug("Douglas teste ok :: CustomAuthHandler.cs");
                    var customResult = new CustomAuthenticationResult {
                        ResultCode = CustomAuthenticationResultCode.Ok
                    };
                    peer.OnCustomAuthenticationResult(customResult, authRequest, sendParameters, state);
                    return;
                }
                else
                {
                    log.Debug("Douglas teste erro :: CustomAuthHandler.cs");
                    peer.OnCustomAuthenticationError(
                        ErrorCode.CustomAuthenticationFailed,
                        "Authentication failed.",
                        authRequest,
                        sendParameters,
                        state);

                    this.IncrementFailedCustomAuth();
                    return;
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }

            /* Alterado para testes
             * try
             * {
             *  if (log.IsDebugEnabled)
             *  {
             *      log.DebugFormat("Authenticating client {0} - custom authentication type: {1}",
             *           peer.ConnectionId,
             *           authRequest.ClientAuthenticationType);
             *  }
             *
             *  // when authentication data is provided check if
             *  // it is either a byte array or string and convert to byte array
             *  // if it's a string value
             *  byte[] authData = null;
             *  if (authRequest.ClientAuthenticationData != null)
             *  {
             *      authData = authRequest.ClientAuthenticationData as byte[];
             *      if (authData == null)
             *      {
             *          var stringData = authRequest.ClientAuthenticationData as string;
             *          if (stringData == null)
             *          {
             *              peer.OnCustomAuthenticationError(
             *                  ErrorCode.CustomAuthenticationFailed,
             *                  "Authentication data type not supported",
             *                  authRequest,
             *                  sendParameters,
             *                  state);
             *
             *              this.IncrementFailedCustomAuth();
             *              return;
             *          }
             *
             *          authData = Encoding.UTF8.GetBytes(stringData);
             *      }
             *  }
             *
             *  if (string.IsNullOrEmpty(authRequest.ClientAuthenticationParams) && authData == null && this.isAnonymousAccessAllowed)
             *  {
             *      // instant callback - treat as anonymous user:
             *      if (log.IsDebugEnabled)
             *      {
             *          log.DebugFormat("Authenticate client: grant access as anonymous user: conId={0}", peer.ConnectionId);
             *      }
             *
             *      var customResult = new CustomAuthenticationResult { ResultCode = CustomAuthenticationResultCode.Ok };
             *      peer.OnCustomAuthenticationResult(customResult, authRequest, sendParameters, state);
             *      return;
             *  }
             *
             *  // take auth type from auth request (default: custom)
             *  var authenticationType = (ClientAuthenticationType)authRequest.ClientAuthenticationType;
             *
             *  ClientAuthenticationQueue authQueue;
             *  if (this.authenticationServices.TryGetValue(authenticationType, out authQueue) == false)
             *  {
             *      if (log.IsWarnEnabled)
             *      {
             *          log.WarnFormat("Authentication type not supported: {0} for AppId={1}/{2}", authenticationType,
             *              authRequest.ApplicationId, authRequest.ApplicationVersion);
             *      }
             *
             *      peer.OnCustomAuthenticationError(
             *          ErrorCode.CustomAuthenticationFailed,
             *          "Authentication type not supported",
             *          authRequest,
             *          sendParameters,
             *          state);
             *      this.IncrementFailedCustomAuth();
             *      return;
             *  }
             *
             *  var queueState = new AuthQueueState(peer, authRequest, sendParameters, state);
             *  authQueue.EnqueueRequest(authRequest.ClientAuthenticationParams, authData, this.AuthQueueResponseCallback, queueState);
             * }
             * catch (Exception ex)
             * {
             *  log.Error(ex);
             * }
             */
        }
        private void DoCustomAuthenticationResult(CustomAuthenticationResult customAuthResult,
                                                  AuthenticateRequest authRequest, SendParameters sendParameters, AuthSettings customAuthSettings)
        {
            if (this.Connected == false)
            {
                return;
            }

            try
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Client custom authentication callback: result={0}, msg={1}, userId={2}",
                                    customAuthResult.ResultCode,
                                    customAuthResult.Message,
                                    this.UserId);
                }

                var operationResponse = new OperationResponse((byte)Hive.Operations.OperationCode.Authenticate)
                {
                    DebugMessage = customAuthResult.Message,
                    Parameters   = new Dictionary <byte, object>()
                };

                switch (customAuthResult.ResultCode)
                {
                default:
                    operationResponse.ReturnCode = (short)Photon.Common.ErrorCode.CustomAuthenticationFailed;
                    this.SendOperationResponse(operationResponse, sendParameters);
                    this.SetCurrentOperationHandler(OperationHandlerInitial.Instance);
                    return;

                case CustomAuthenticationResultCode.Data:
                    operationResponse.Parameters = new Dictionary <byte, object> {
                        { (byte)ParameterCode.Data, customAuthResult.Data }
                    };
                    this.SendOperationResponse(operationResponse, sendParameters);
                    this.SetCurrentOperationHandler(OperationHandlerInitial.Instance);
                    return;

                case CustomAuthenticationResultCode.Ok:
                    //apply user id from custom auth result
                    if (!string.IsNullOrEmpty(customAuthResult.UserId))
                    {
                        this.UserId = customAuthResult.UserId;
                    }
                    else if (!string.IsNullOrEmpty(authRequest.UserId))
                    {
                        this.UserId = authRequest.UserId;
                    }
                    else
                    {
                        this.UserId = Guid.NewGuid().ToString();
                    }
                    // create auth token and send response
                    this.CreateAuthTokenAndSendResponse(customAuthResult, authRequest, sendParameters, customAuthSettings, operationResponse);
                    this.SetCurrentOperationHandler(OperationHandlerDefault.Instance);
                    this.OnAuthSuccess(authRequest);
                    break;
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
                var errorResponse = new OperationResponse((byte)Hive.Operations.OperationCode.Authenticate)
                {
                    ReturnCode = (short)ErrorCode.InternalServerError
                };
                this.SendOperationResponse(errorResponse, sendParameters);
                this.SetCurrentOperationHandler(OperationHandlerInitial.Instance);
            }
        }
        protected virtual void OnAuthenticateClient(ICustomAuthPeer peer, IAuthenticateRequest authRequest, AuthSettings authSettings, SendParameters sendParameters, object state)
        {
            try
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Authenticating client {0} - custom authentication type: {1}",
                         peer.ConnectionId,
                         authRequest.ClientAuthenticationType);
                }

                // when authentication data is provided check if
                // it is either a byte array or string and convert to byte array
                // if it's a string value
                byte[] authData = null;
                if (authRequest.ClientAuthenticationData != null)
                {
                    authData = authRequest.ClientAuthenticationData as byte[];
                    if (authData == null)
                    {
                        var stringData = authRequest.ClientAuthenticationData as string;
                        if (stringData == null)
                        {
                            peer.OnCustomAuthenticationError(
                                ErrorCode.CustomAuthenticationFailed,
                                "Authentication data type not supported",
                                authRequest,
                                sendParameters,
                                state);

                            this.IncrementFailedCustomAuth();
                            return;
                        }

                        authData = Encoding.UTF8.GetBytes(stringData);
                    }
                }

                if (string.IsNullOrEmpty(authRequest.ClientAuthenticationParams) && authData == null && this.isAnonymousAccessAllowed)
                {
                    // instant callback - treat as anonymous user:
                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("Authenticate client: grant access as anonymous user: conId={0}", peer.ConnectionId);
                    }

                    var customResult = new CustomAuthenticationResult { ResultCode = CustomAuthenticationResultCode.Ok };
                    peer.OnCustomAuthenticationResult(customResult, authRequest, sendParameters, state);
                    return;
                }

                // take auth type from auth request (default: custom)
                var authenticationType = (ClientAuthenticationType)authRequest.ClientAuthenticationType;

                ClientAuthenticationQueue authQueue;
                if (this.authenticationServices.TryGetValue(authenticationType, out authQueue) == false)
                {
                    if (log.IsWarnEnabled)
                    {
                        log.WarnFormat("Authentication type not supported: {0} for AppId={1}/{2}", authenticationType,
                            authRequest.ApplicationId, authRequest.ApplicationVersion);
                    }

                    peer.OnCustomAuthenticationError(
                        ErrorCode.CustomAuthenticationFailed,
                        "Authentication type not supported",
                        authRequest,
                        sendParameters,
                        state);
                    this.IncrementFailedCustomAuth();
                    return;
                }

                var queueState = new AuthQueueState(peer, authRequest, sendParameters, state);
                authQueue.EnqueueRequest(authRequest.ClientAuthenticationParams, authData, this.AuthQueueResponseCallback, queueState);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }