Пример #1
0
        /// <summary>
        /// Tries to find a secret on the environment that can be used for authentication
        /// </summary>
        /// <param name="environment">The environment.</param>
        /// <returns>
        /// A parsed secret
        /// </returns>
        public async Task <ParsedSecret> ParseAsync(IDictionary <string, object> environment)
        {
            var context = new OwinContext(environment);

            if (!context.Request.Body.CanSeek)
            {
                var copy = new MemoryStream();
                await context.Request.Body.CopyToAsync(copy);

                copy.Seek(0L, SeekOrigin.Begin);
                context.Request.Body = copy;
            }

            context.Request.Body.Seek(0L, SeekOrigin.Begin);
            var body = await context.Request.ReadFormAsync();

            context.Request.Body.Seek(0L, SeekOrigin.Begin);

            var grantType = body.Get("grant_type");

            if (String.IsNullOrEmpty(grantType))
            {
                return(null);
            }

            var clientId = body.Get("client_id");

            if (String.IsNullOrEmpty(clientId))
            {
                return(null);
            }

            var clientSecret = body.Get("client_secret");

            if (String.IsNullOrEmpty(clientSecret))
            {
                return(null);
            }

            if (grantType == "client_credentials")
            {
                return(new ParsedSecret
                {
                    Id = clientId,
                    Credential = clientSecret.Sha256(),
                    Type = "SharedSecret"
                });
            }

            var certificate = Convert.FromBase64String(clientId);

            var signature = Convert.FromBase64String(clientSecret);

            var data = body.Get("access_token");

            if (String.IsNullOrEmpty(data))
            {
                return(null);
            }

            var accessToken = data;

            data = body.Get("nonce");

            if (String.IsNullOrEmpty(data))
            {
                return(null);
            }

            var nonce = Convert.FromBase64String(data);

            try
            {
                X509Certificate2 x509 = new X509Certificate2(certificate);
                // TBD - use a CertificateValidator to verify certificate.

                // check that the id matches the certificate.
                var applicationUri = Utils.GetApplicationUriFromCertificate(x509);

                // verify signature.
                var dataToVerify = Utils.Append(new UTF8Encoding(false).GetBytes(accessToken), nonce);

                if (!RsaUtils.RsaPkcs15Sha1_Verify(new ArraySegment <byte>(dataToVerify), signature, x509))
                {
                    return(null);
                }

                return(new ParsedSecret
                {
                    Id = applicationUri,
                    Credential = x509,
                    Type = "ApplicationSignature"
                });
            }
            catch (Exception)
            {
                return(null);
            }
        }