Example #1
0
        public void ParsingHugeVersionNumbersUrlThrowsOverflowException()
        {
            Uri malformedUrl = new Uri(@"http://sp-dev-stefan.cloudapp.net/v334334433344444433344433333334442321121.0/");
            int major, minor;

            UrlParser.GetMajorMinorAPIVersion(malformedUrl, out major, out minor);
        }
Example #2
0
        public void ParsingUrlEndingInVersionNumbersThrowsArgException()
        {
            Uri malformedUrl = new Uri(@"http://sp-dev-stefan.cloudapp.net/v0.2");
            int major, minor;

            UrlParser.GetMajorMinorAPIVersion(malformedUrl, out major, out minor);
        }
Example #3
0
        public void ParsingNegativeVersionNumbersUrlThrowsArgException()
        {
            Uri malformedUrl = new Uri(@"http://sp-dev-stefan.cloudapp.net/v-2.0/users");
            int major, minor;

            UrlParser.GetMajorMinorAPIVersion(malformedUrl, out major, out minor);
        }
Example #4
0
        public void ParsingRelativeUrlThrowsNullException()
        {
            Uri malformedUrl = new Uri(@"../relativeUrl", UriKind.Relative);
            int major, minor;

            UrlParser.GetMajorMinorAPIVersion(malformedUrl, out major, out minor);
        }
Example #5
0
        public void ParsingNullUrlThrowsNullException()
        {
            Uri malformedUrl = null;
            int major, minor;

            UrlParser.GetMajorMinorAPIVersion(malformedUrl, out major, out minor);
        }
Example #6
0
        public void ParsingVersionNumbersWorks()
        {
            Uri malformedUrl = new Uri(@"http://sp-dev-stefan.cloudapp.net/v0.2/users");
            int major, minor;

            UrlParser.GetMajorMinorAPIVersion(malformedUrl, out major, out minor);
            Assert.AreEqual(major, 0);
            Assert.AreEqual(minor, 2);
        }
        /// <summary>
        /// Authenticate async.
        /// This method:
        ///     - checks that there is an authorization field
        ///     - checks that if the authorization scheme is Anon the controller called is labelled with the Allow Anonymous attribute
        ///     - dispatches the authorization parameter to the appropriate auth manager
        ///     - populates the HTTP context with the user and app principals
        /// </summary>
        /// <remarks>
        /// Requirements for different schemes:
        ///  - SocialPlus: must include token
        ///  - Anon: must include app key
        ///  - OAuth: must include app key and token
        ///  - AADS2S: must include app key and token (and optionally user handle)
        /// In summary: the app key cannot be null unless AuthScheme is SocialPlus; token cannot be null unless AuthScheme is Anon
        /// </remarks>
        /// <param name="context">Http context</param>
        /// <param name="cancellationToken">Cancellation token</param>
        /// <returns>Authenticate async task</returns>
        public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
        {
            HttpActionContext  actionContext = context.ActionContext;
            HttpRequestMessage request       = context.Request;
            int versionMajor             = 0;
            int versionMinor             = 0;
            List <IPrincipal> principals = null;

            // parse out the api version number from the request url
            try
            {
                UrlParser.GetMajorMinorAPIVersion(request.RequestUri, out versionMajor, out versionMinor);
            }
            catch (Exception e)
            {
                string errorMessage = "Request API version is malformed.";
                this.log.LogError(errorMessage, e);

                context.ErrorResult = new BadRequestMessageResult(ResponseStrings.VersionNumbersMalformed, request);
                return;
            }

            AuthenticationHeaderValue authorization = request.Headers.Authorization;

            if (authorization == null)
            {
                string errorMessage = "No authorization header field present.";
                this.log.LogError(errorMessage);

                context.ErrorResult = new UnauthorizedMessageResult(ResponseStrings.GenericUnauthorizedError, context.Request);
                return;
            }

            // Anon authorization is only allowed on controllers labelled with the AllowAnonymous attribute
            if (authorization.Scheme == AnonScheme && (actionContext.ActionDescriptor.GetCustomAttributes <AllowAnonymousAttribute>().Any() == false))
            {
                string errorMessage = $"Anon auth attempted on a controller/action not labelled AllowAnonymous. Auth: {authorization.ToString()}";
                this.log.LogError(errorMessage);

                context.ErrorResult = new UnauthorizedMessageResult(ResponseStrings.GenericUnauthorizedError, context.Request);
                return;
            }

            // Validate the authorization string
            try
            {
                principals = await this.authManager.ValidateAuth(authorization.Parameter, authorization.Scheme);
            }
            catch (Exception e)
            {
                // Catch unauthorized exceptions, log them, and return unauthorized
                string errorMessage = $"Invalid authorization header: {authorization.ToString()}";
                this.log.LogError(errorMessage, e);

                context.ErrorResult = new UnauthorizedMessageResult(ResponseStrings.GenericUnauthorizedError, context.Request);
                return;
            }

            // Save user and app principal in the HTTP context
            foreach (var p in principals)
            {
                if (p is AppPrincipal)
                {
                    HttpContext.Current.Items["AppPrincipal"] = p;
                }
                else if (p is UserPrincipal)
                {
                    HttpContext.Current.User = p;
                }
            }
        }