示例#1
0
        public async Task <IActionResult> Confirm([FromBody] ConfirmViewModel vm,
                                                  CancellationToken cancellationToken)
        {
            SecurityToken token;

            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
            var claims =
                new JwtSecurityTokenHandler().ValidateToken(vm.JwtTokenString, this._tokenValidationParameters,
                                                            out token);

            if (!claims.HasClaim("register", "yes"))
            {
                return(this.BadRequest());
            }

            var user = await this._users.FindByIdAsync(claims.GetSubjectId(), cancellationToken);

            user.Email         = claims.Claims.First(c => c.Type == JwtRegisteredClaimNames.Email).Value;
            user.EmailVerified = true;
            user.UserName      = claims.Claims.First(c => c.Type == JwtRegisteredClaimNames.UniqueName).Value;

            if (await this._users.CreateAsync(user, nameof(AccountController) + nameof(this.Confirm), cancellationToken) != IdentityResult.Success)
            {
                return(this.ServerError(new Exception("Create user failed")));
            }

            return(this.Ok());
        }
示例#2
0
        public async Task <IActionResult> Reset([FromBody] ResetViewModel vm, CancellationToken cancellationToken)
        {
            SecurityToken token;

            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
            var claims =
                new JwtSecurityTokenHandler().ValidateToken(vm.JwtTokenString, this._tokenValidationParameters,
                                                            out token);

            if (!claims.HasClaim("reset_password", "yes") || vm.Password != vm.ConfirmPassword)
            {
                return(this.BadRequest());
            }

            var user = await this._users.FindByIdAsync(claims.GetSubjectId(), cancellationToken);

            if (await this._users.SetUserPasswordAsync(user, vm.Password, cancellationToken))
            {
                return(this.Ok());
            }

            return(this.BadRequest());
        }
示例#3
0
        /// <summary>
        /// validates a jwtToken based off the options defined in config.
        /// </summary>
        /// <param name="token">the token</param>
        /// <returns>returns an instance of the validated token</returns>
        private async Task <List <Claim> > ValidateTokenInternal(string token)
        {
            if (string.IsNullOrEmpty(token))
            {
                throw new ArgumentNullException(nameof(token));
            }

            var claims = new List <Claim>();



            ICollection <SecurityKey>  signingKeys       = null;
            OpenIdConnectConfiguration discoveryDocument = null;

            if (_config.validationOptions.ValidateIssuerSigningKey || _config.enableUserInfoLookup)
            {
                //issuer config
                var issuer = new Uri(_config.issuer);


                //be default make the discovery url the issuer + OAUTH spec https://tools.ietf.org/html/draft-ietf-oauth-discovery-07#section-3
                var discovery = new Uri(issuer, ".well-known/openid-configuration");

                //sometimes the issuer can be different than the discovery endpoint. allow for that
                //is the discovery url absolute?
                if (Uri.IsWellFormedUriString(_config.discoveryUri, UriKind.Absolute))
                {
                    discovery = new Uri(_config.discoveryUri);
                }
                else if (Uri.IsWellFormedUriString(_config.discoveryUri, UriKind.Relative))
                {
                    discovery = new Uri(issuer, _config.discoveryUri);
                }
                var configurationManager = new ConfigurationManager <OpenIdConnectConfiguration>(discovery.AbsoluteUri,
                                                                                                 new OpenIdConnectConfigurationRetriever(),
                                                                                                 new HttpDocumentRetriever {
                    RequireHttps = _config.requireHttpsDiscovery
                });

                //get the public keys from the discovery endpoint
                //this could be cached to avoid excessive lookup
                discoveryDocument = await configurationManager.GetConfigurationAsync(default(CancellationToken)).ConfigureAwait(false);

                signingKeys = discoveryDocument.SigningKeys;
            }

            //these are other options for building a key to use to validate if the key is known.
            #region alternate keys
            //load from file
            //IssuerSigningKey = new X509SecurityKey(new X509Certificate2(certLocation)),

            ///provided signing cert
            //	string X509Cert = "CERT CONTENTS";
            //X509Certificate2 DefaultCert_Public_2048 = new X509Certificate2(Convert.FromBase64String(X509Cert));
            //X509SecurityKey DefaultX509Key_Public_2048 = new X509SecurityKey(DefaultCert_Public_2048);
            //SigningCredentials DefaultX509SigningCreds_Public_2048_RsaSha2_Sha2 = new SigningCredentials(DefaultX509Key_Public_2048, SecurityAlgorithms.RsaSha256Signature);


            ///Alternative asyematric public key build. Typeically gathered from discovery endpoint
            //var e = Base64Url.Decode("AQAB");
            //var n = Base64Url.Decode("wKchfRYocmVQW2tEbagQYLJDwkYOyU2Nf1vomzHZGdjeIyyvexLjW6YW6kCnNG5-I2Lm67pTUE8fBI7gL68whkUYsXCx7lXgo3Snx17_xwPBPdmiI42Xx-IAU-D8YvO7aOaYwbUqwiPrDG5GeaaMHqqbNu4G4vrKptkgBvUSSbNWfqmkg3e-BdrjLIlkyqMmpGuAokMl_eHH90_Av_D27Nw8RzhsGezlThQUte-MXd5oFLr4IT730SKRksR1Clm--CGIc7rr79oaVF1OZw44cgl1DsezsmKw9MQRTe8Mr_j4l0i6RPuVdm_LzUpE5zoStb1ta5b6RBekO1F5ZEjNUQ");

            //var signingKey = new RsaSecurityKey(new RSAParameters { Exponent = e, Modulus = n }) {
            //	KeyId = "2c4147d18d355afaf60bce38220898f2"
            //};

            #endregion

            var validationParameters = new TokenValidationParameters {
                ValidateIssuer           = _config.validationOptions.validateIssuer,
                RequireSignedTokens      = _config.validationOptions.ValidateIssuerSigningKey,
                ValidateIssuerSigningKey = _config.validationOptions.ValidateIssuerSigningKey,
                ValidateLifetime         = _config.validationOptions.ValidateLifetime,
                ValidateAudience         = _config.validationOptions.ValidateAudience,

                // Allow for some drift in server time
                // (a lower value is better; we recommend five minutes or less)
                ClockSkew = TimeSpan.FromMinutes(5),
            };

            if (_config.validationOptions.validateIssuer)
            {
                validationParameters.ValidIssuer = _config.issuer;
            }

            if (_config.validationOptions.ValidateIssuerSigningKey)
            {
                validationParameters.IssuerSigningKeys = signingKeys;
            }
            else
            {
                validationParameters.SignatureValidator = (t, opt) => {
                    var jwt = new JwtSecurityToken(t);
                    return(jwt);
                }
            };

            if (_config.validationOptions.ValidateAudience)
            {
                validationParameters.ValidAudiences = _config.audiences;
            }


            var principal             = new JwtSecurityTokenHandler().ValidateToken(token, validationParameters, out var rawValidatedToken);
            JwtSecurityToken newToken = (JwtSecurityToken)rawValidatedToken;
            claims.AddRange(newToken.Claims);
            //if there is a 'sub' claim on the token query for additional claims
            if (principal.HasClaim("scope", "openid") && _config.enableUserInfoLookup)
            {
                //look up user information to gather additional claims

                HttpClient httpClient = HttpClientManager.Instance.HttpClient;
                using (var requestMessage = new HttpRequestMessage(HttpMethod.Get, discoveryDocument.UserInfoEndpoint)) {
                    requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
                    using (var response = await httpClient.SendAsync(requestMessage).ConfigureAwait(false)) {
                        if (response.IsSuccessStatusCode)
                        {
                            var content = await response.Content.ReadAsStringAsync();

                            var userclaims = JsonConvert.DeserializeObject <Dictionary <string, object> >(content);
                            foreach (var c in userclaims)
                            {
                                if (c.Value.GetType().IsArray)
                                {
                                    foreach (var v in (string[])c.Value)
                                    {
                                        claims.Add(new Claim(c.Key, v, ClaimValueTypes.String, issuer: newToken.Issuer));
                                    }
                                }
                                claims.Add(new Claim(c.Key, c.Value.ToString(), ClaimValueTypes.String, issuer: newToken.Issuer));
                            }
                        }
                    }
                }
            }
            return(claims);
        }