Beispiel #1
0
        /// <summary>
        /// For the request, determine if the requestor's IP address is valid.
        /// </summary>
        /// <param name="auth">An authentication configuration instance.</param>
        /// <param name="authModule">The authentication module instance to use to authenticate the user for the operation.</param>
        /// <param name="operation">The operation that is being requested.</param>
        /// <param name="opContext">The OperationContext for the request (note: this is not the WebOperationContext used for other calls).</param>
        /// <returns>An errordetail instance holding any error that was encountered, or null if no errors were encountered.</returns>
        private static errordetail AuthorizeIPAddressForUser(AuthenticationConfig auth, OttaMattaAuthentication authModule, string operation, System.ServiceModel.OperationContext opContext)
        {
            errordetail  result = null;
            const string endpointPropertyName = "System.ServiceModel.Channels.RemoteEndpointMessageProperty";
            bool         failIfNoIP           = false;

            System.ServiceModel.Channels.MessageProperties properties = opContext.IncomingMessageProperties;
            if (properties.ContainsKey(endpointPropertyName))
            {
                RemoteEndpointMessageProperty endpoint = properties[endpointPropertyName] as RemoteEndpointMessageProperty;

                //
                // Note: on local dev machines this is the IPv6 address, like "fe80::c513:967d:1b57:8c33%11".
                //
                string ipAddress = endpoint.Address;

                //
                // We have an IP address.  Let's see if it's authorized for this user.
                //
                if (authModule != null && auth.UserAllowedIps.ContainsKey(authModule.Username))
                {
                    bool ipOK = auth.UserAllowedIps[authModule.Username].Contains(ipAddress);

                    if (!ipOK)
                    {
                        result = new errordetail(string.Format("The IP address \"{0}\" is not authorized for user account \"{1}\"", ipAddress, authModule.Username), HttpStatusCode.Forbidden);
                    }
                }
                else
                {
                    //
                    // There are no IP address restrictions for this account.
                    //
                }
            }
            else
            {
                //
                // Can't get the remote IP from the system.  We can assume that something has changed in the WCF .NET codebase, and allow it for now.
                // Or, we can fail the request.
                //
                if (failIfNoIP)
                {
                    result = new errordetail("Unable to determine request IP address", HttpStatusCode.InternalServerError);
                }
            }

            return(result);
        }
Beispiel #2
0
        /// <summary>
        /// From the operation, determine if SSL is required and if so, if the current request uses it.
        /// </summary>
        /// <param name="auth">An authentication configuration instance.</param>
        /// <param name="operation">The operation that is being requested.</param>
        /// <param name="isSSL">Whether the current operation is SSL or not.</param>
        /// <param name="operationAuthenticationMethod">The authentication method required for the current operation.</param>
        /// <returns>An errordetail instance holding any error that was encountered, or null if no errors were encountered.</returns>
        private static errordetail ValidateSSLStatus(AuthenticationConfig auth, string operation, bool isSSL, AuthenticationMethod operationAuthenticationMethod)
        {
            errordetail result = null;

            //
            // Test if the operation requires SSL.
            //
            bool requiresSSL = auth.OperationsRequiringSSL.Contains(operation) ||
                               (operationAuthenticationMethod == AuthenticationMethod.Basic && !auth.OperationsRequiringBasicAuthButAllowingNoSSL.Contains(operation));

            if (requiresSSL && !isSSL)
            {
                result = new errordetail(string.Format("The operation \"{0}\" requires a secure connection.", operation), HttpStatusCode.BadRequest);
            }

            return(result);
        }
Beispiel #3
0
        /// <summary>
        /// Validate whether the user is authenticated and whether the user is authorized for this operation.
        /// </summary>
        /// <remarks>
        /// This function will not return if the request is invalid.  An error is thrown and the appropriate response returned to the client.
        /// If this function does return, the request can safely be considered valid.
        /// </remarks>
        public static void Validate()
        {
            //
            // Variables required for authentication and authorization.
            //
            System.ServiceModel.Web.IncomingWebRequestContext context = System.ServiceModel.Web.WebOperationContext.Current.IncomingRequest;
            errordetail          currentException = null;
            AuthenticationConfig auth             = AuthenticationConfig.Instance;
            WebHeaderCollection  headers          = null;
            string ipAddress = string.Empty;
            string operation = string.Empty;
            bool   isSSL     = false;
            AuthenticationMethod operationAuthenticationMethod = AuthenticationMethod.Unknown;
            bool opRequiresCredentials         = true;
            OttaMattaAuthentication authModule = null;

            //
            // Test for credentials
            //
            currentException = GatherBasicInfo(context, out headers, out operation, out isSSL);

            if (currentException == null)
            {
                currentException = GetCredentialStatus(auth, operation, out opRequiresCredentials, out operationAuthenticationMethod);
            }

            //
            // Validate SSL status
            //
            if (currentException == null)
            {
                currentException = ValidateSSLStatus(auth, operation, isSSL, operationAuthenticationMethod);
            }

            //
            // Authenticate the user
            //
            if (currentException == null)
            {
                currentException = ValidateAuthenticationCredentials(opRequiresCredentials, auth, context, operationAuthenticationMethod, out authModule);
            }

            //
            // Authorize the user for this operation
            //
            if (currentException == null)
            {
                currentException = AuthorizeUserForOperation(opRequiresCredentials, auth, authModule, operation);
            }

            //
            // Validate IP address
            //
            if (currentException == null)
            {
                currentException = AuthorizeIPAddressForUser(auth, authModule, operation, System.ServiceModel.OperationContext.Current);
            }

            //
            // Validate throttling
            //
            if (currentException == null)
            {
                currentException = ValidateThrottleForUser(authModule, operation);
            }

            //
            // Can't continue - return the response.
            //
            if (currentException != null)
            {
                throw new WebFaultException <errordetail>(currentException, currentException.statuscode);
            }
        }
Beispiel #4
0
        /// <summary>
        /// For the request, get the credentials (if required) and determine if the user is authorized.
        /// </summary>
        /// <param name="opRequiresCredentials">Whether the operation requires credentials or not.</param>
        /// <param name="auth">An authentication configuration instance.</param>
        /// <param name="authModule">The authentication module instance to use to authenticate the user for the operation.</param>
        /// <param name="operation">The operation that is being requested.</param>
        /// <returns>An errordetail instance holding any error that was encountered, or null if no errors were encountered.</returns>
        private static errordetail AuthorizeUserForOperation(bool opRequiresCredentials, AuthenticationConfig auth, OttaMattaAuthentication authModule, string operation)
        {
            errordetail result = null;

            if (opRequiresCredentials)
            {
                //
                // UID and PW good.  Authorize the user for this operation
                //
                bool userAllowed = false;

                if (auth.UserAllowedOperations.ContainsKey(authModule.Username))
                {
                    userAllowed = auth.UserAllowedOperations[authModule.Username].Contains(operation);
                }

                if (!userAllowed)
                {
                    result = new errordetail(string.Format("Operation \"{0}\" not authorized for user \"{1}\"", operation, authModule.Username), HttpStatusCode.Forbidden);
                }
            }

            return(result);
        }
Beispiel #5
0
        /// <summary>
        /// From the current context, determine if we have enough information to authenticate the user/request.
        /// </summary>
        /// <param name="opRequiresCredentials">Whether the operation requires credentials or not.</param>
        /// <param name="auth">An authentication configuration instance.</param>
        /// <param name="context">The server request context.</param>
        /// <param name="operationAuthenticationMethod">The authentication method required for the current operation.</param>
        /// <param name="authModule">(out) A authentication module that can be used to authenticate this user.</param>
        /// <returns>An errordetail instance holding any error that was encountered, or null if no errors were encountered.</returns>
        private static errordetail ValidateAuthenticationCredentials(bool opRequiresCredentials, AuthenticationConfig auth, System.ServiceModel.Web.IncomingWebRequestContext context, AuthenticationMethod operationAuthenticationMethod, out OttaMattaAuthentication authModule)
        {
            errordetail result = null;

            authModule = null;

            if (opRequiresCredentials)
            {
                if (operationAuthenticationMethod == AuthenticationMethod.Basic)
                {
                    authModule = new BasicAuthentication();
                }
                else
                {
                    authModule = new DigestAuthentication();
                }

                authModule.Context = context;
                authModule.Auth    = auth;

                result = authModule.Authenticate();
            }

            return(result);
        }