Beispiel #1
0
        public void Authenticate_TrueOnValidMembership()
        {
            string ipAddress = "127.0.0.1";

            var configuration = CreateNewConfig();
            var inspector     = new DigestAuthenticator(configuration);

            //the result of MD5 hashing some well known values (either specified in the header below or similar)
            string response = "dc950f2d7c24037a6c775bcc9198b6f8";

            //939e7578ed9e3c518a452acee763bce9:NjM0Mzc3MjI2OTIwMDA6Yjg3ZWZlODM0Mjc1NThjZGVlZWVkYjRjNTI1MzFjMzM=:00000001:0a4f113b:auth:39aff3a2bab6126f332b942af96d3366

            NonceManager.Now = () => DateTime.Parse("4/6/2011 9:38:12 PM", CultureInfo.CurrentCulture);

            string nonce = NonceManager.Generate(ipAddress, privateHashEncoder);
            //this should generate very specific nonce "NjM0Mzc3MjI2OTIwMDA6Yjg3ZWZlODM0Mjc1NThjZGVlZWVkYjRjNTI1MzFjMzM="

            var headers = new NameValueCollection()
            {
                { "Authorization", string.Format(CultureInfo.InvariantCulture,
                                                 @"Digest username=""Mufasa"",realm=""{0}"",
                     nonce=""{1}"",
                     uri=""/dir/index.html"",qop=auth,nc=00000001,cnonce=""0a4f113b"",
                     response=""{2}"",
                     opaque=""{3}""", configuration.Realm, nonce, response, Opaque.Current()) }
            };

            var result = inspector.Authenticate(CreateNewFakeContext(headers, ipAddress));

            NonceManager.Now = () => { return(DateTime.UtcNow); };
            Assert.True(result.Success);
            Assert.Equal(result.Principal.Identity.Name, "Mufasa");
        }
 public NonceInternalApiV1Controller(
     NonceManager nonceManager,
     IdentityUserManager identityUserManager
     ) : base(identityUserManager)
 {
     m_nonceManager = nonceManager;
 }
Beispiel #3
0
        public void IsStale_TrueOnZeroSeconds()
        {
            string nonce = GenerateNonce();

            Thread.Sleep(2);
            Assert.True(NonceManager.IsStale(nonce, TimeSpan.FromSeconds(0)));
        }
 public AccountController(
     UserManager userManager,
     IEventService events,
     IIdentityServerInteractionService interaction,
     IdentitySignInManager signInManager,
     IdentityUserManager identityUserManager,
     MessageSenderManager messageSenderManager,
     ReturnUrlConfiguration returnUrlConfiguration,
     ILocalizationService localization,
     NonceManager nonceManager,
     DynamicModuleProvider dynamicModuleProvider,
     FeatureFlagsManager featureFlagsManager
     )
 {
     m_userManager            = userManager;
     m_events                 = events;
     m_interaction            = interaction;
     m_signInManager          = signInManager;
     m_identityUserManager    = identityUserManager;
     m_messageSenderManager   = messageSenderManager;
     m_returnUrlConfiguration = returnUrlConfiguration;
     m_localization           = localization;
     m_nonceManager           = nonceManager;
     m_dynamicModuleProvider  = dynamicModuleProvider;
     m_featureFlagsManager    = featureFlagsManager;
 }
Beispiel #5
0
        public void IsStale_FalseOnCurrentNonce()
        {
            FreezeNonceClock();

            string nonce = GenerateNonce();
            bool   stale = NonceManager.IsStale(nonce, TimeSpan.FromSeconds(1));

            ThawNonceClock();

            Assert.False(stale);
        }
Beispiel #6
0
        public void Generate_CanRoundtripThroughValidate()
        {
            FreezeNonceClock();

            string nonce = GenerateNonce();
            bool   match = NonceManager.Validate(nonce, ipAddress, privateHashEncoder);

            ThawNonceClock();

            Assert.True(match);
        }
        public UserController(
            UserManager usersManager, IdentityUserManager identityUserManager,
            IAuthorizationService authorizationService, IdentitySignInManager signInManager,
            ClaimManager claimManager, TwoFactorValidator twoFactorValidator,
            UserStore userStore, NonceManager nonceManager,
            IMapper mapper
            )
        {
            m_authorizationService = authorizationService;
            m_usersManager         = usersManager;
            m_identityUserManager  = identityUserManager;

            m_signInManager = signInManager;

            m_twoFactorValidator = twoFactorValidator;
            m_claimManager       = claimManager;
            m_userStore          = userStore;
            m_nonceManager       = nonceManager;
            m_mapper             = mapper;
        }
Beispiel #8
0
        public ValueTask <IdentityHttpResponse> Login(string state)
        {
            var nonce = NonceManager.Generate(serviceProvider);

            var requestDocument = new OpenIDLoginRequest(
                serviceProvider: serviceProvider,
                redirectUrl: redirectUrl,
                responseType: this.responseType,
                responseMode: OpenIDResponseMode.form_post,
                bindingType: BindingType.Form,
                scope: this.scope,
                state: state,
                nonce: nonce
                );

            var requestBinding = OpenIDBinding.GetBindingForDocument(requestDocument, BindingType.Form);
            var response       = requestBinding.GetResponse(loginUrl);

            return(new ValueTask <IdentityHttpResponse>(response));
        }
Beispiel #9
0
        public void OnAuthenticationFailure_RecognizesAndReportsStaleNonce()
        {
            HttpContextBase context        = GetDefaultFakedContext();
            var             failureHandler = GetFailureHandler();

            string nonce = NonceManager.Generate(ipAddress, privateHashEncoder);

            var headers = new NameValueCollection()
            {
                { "Authorization", string.Format(CultureInfo.InvariantCulture,
                                                 @"Digest username=""Mufasa"",realm=""*****@*****.**"",
                     nonce=""{0}"",
                     uri=""/dir/index.html"",qop=auth,nc=00000001,cnonce=""0a4f113b"",
                     response=""6629fae49393a05397450978507c4ef1"",
                     opaque=""5ccc069c403ebaf9f0171e9517f40e41""", nonce) }
            };

            A.CallTo(() => context.Request.Headers).Returns(headers);

            //jump ahead just outside the reach of our configuration
            DateTime now = DateTime.UtcNow;

            NonceManager.Now = () => now + failureHandler.Configuration.NonceValidDuration.Add(TimeSpan.FromSeconds(1));

            //record the values from the AddHeader call and make sure they match our expectations
            string headerName = string.Empty, headerValue = string.Empty;

            A.CallTo(() => context.Response.AddHeader(A <string> .Ignored, A <string> .Ignored))
            .Invokes(call => { headerName = (string)call.Arguments[0]; headerValue = (string)call.Arguments[1]; });

            failureHandler.OnAuthenticationFailure(context, inspectorResults);

            string expectedHeader = String.Format(CultureInfo.InvariantCulture,
                                                  "Digest realm=\"{0}\", nonce=\"{1}\", opaque=\"{2}\", stale=TRUE, algorithm=MD5, qop=\"auth\"",
                                                  realm, NonceManager.Generate(ipAddress, privateHashEncoder), Opaque.Current());

            ThawNonceClock();

            Assert.True(headerName == "WWW-Authenticate" && expectedHeader == headerValue);
        }
Beispiel #10
0
        public void Authenticate_FalseOnMismatchedRealm()
        {
            string ipAddress = "127.0.0.1";
            string nonce     = NonceManager.Generate(ipAddress, privateHashEncoder);

            var inspector = new DigestAuthenticator(CreateNewConfig());

            var headers = new NameValueCollection()
            {
                { "Authorization", string.Format(CultureInfo.InvariantCulture,
                                                 @"Digest username=""Mufasa"",realm=""*****@*****.**"",
                     nonce=""{0}"",
                     uri=""/dir/index.html"",qop=auth,nc=00000001,cnonce=""0a4f113b"",
                     response=""6629fae49393a05397450978507c4ef1"",
                     opaque=""5ccc069c403ebaf9f0171e9517f40e41""", nonce) }
            };

            var result = inspector.Authenticate(CreateNewFakeContext(headers, ipAddress));

            //TODO: validate that we have a GenericPrincipal / GenericIdentity
            Assert.False(result.Success);
        }
Beispiel #11
0
        public void OnAuthenticationFailure_GeneratesCorrectHeaderForNewRequest()
        {
            FreezeNonceClock();
            HttpContextBase context = GetDefaultFakedContext();

            //record the values from the AddHeader call and make sure they match our expectations
            string headerName = string.Empty, headerValue = string.Empty;

            A.CallTo(() => context.Response.AddHeader(A <string> .Ignored, A <string> .Ignored))
            .Invokes(call => { headerName = (string)call.Arguments[0]; headerValue = (string)call.Arguments[1]; });

            var failureHandler = GetFailureHandler();

            failureHandler.OnAuthenticationFailure(context, inspectorResults);

            string expectedHeader = String.Format(CultureInfo.InvariantCulture,
                                                  "Digest realm=\"{0}\", nonce=\"{1}\", opaque=\"{2}\", stale=FALSE, algorithm=MD5, qop=\"auth\"",
                                                  realm, NonceManager.Generate(ipAddress, privateHashEncoder), Opaque.Current());

            ThawNonceClock();

            Assert.Equal(headerName, "WWW-Authenticate");
            Assert.Equal(expectedHeader, headerValue);
        }
Beispiel #12
0
 public void IsStale_ThrowsOnNullNonce()
 {
     Assert.Throws <ArgumentNullException>(() => NonceManager.IsStale(null, TimeSpan.FromSeconds(30)));
 }
Beispiel #13
0
 private string GenerateNonce()
 {
     return(NonceManager.Generate(ipAddress, privateHashEncoder));
 }
Beispiel #14
0
 public void Generate_ThrowsOnEmptyIPAddress()
 {
     Assert.Throws <ArgumentException>(() => NonceManager.Generate(string.Empty, privateHashEncoder));
 }
Beispiel #15
0
 public void Generate_ThrowsOnNullIPAddress()
 {
     Assert.Throws <ArgumentNullException>(() => NonceManager.Generate(null, privateHashEncoder));
 }
Beispiel #16
0
 public void Validate_ThrowsOnNullPrivateHashEncoderNotInitialized()
 {
     //this is a valid nonce conforming to our standards
     Assert.Throws <ArgumentNullException>(() => NonceManager.Validate("NjM0MzM4ODg3Nzc1MzEuMzpmZDIxNzllOTUzMDY2ODc2YWQyYjY1NmVmZGJkYTc4MQ==", "127.0.0.1", null));
 }
Beispiel #17
0
 public void Generate_ThrowsOnNullPrivateHashEncoderNotInitialized()
 {
     Assert.Throws <ArgumentNullException>(() => NonceManager.Generate("127.0.0.1", null));
 }
Beispiel #18
0
 public void IsStale_TrueOnOldPreCalculatedNonce()
 {
     Assert.True(NonceManager.IsStale(validNonce, TimeSpan.FromSeconds(0)));
 }
Beispiel #19
0
 public void Validate_MatchesPreCalculatedNonce()
 {
     Assert.True(NonceManager.Validate(validNonce, ipAddress, privateHashEncoder));
 }
Beispiel #20
0
 public void Validate_ThrowsOnEmptyNonce()
 {
     Assert.Throws <ArgumentException>(() => NonceManager.Validate(string.Empty, ipAddress, privateHashEncoder));
 }
Beispiel #21
0
 public void Validate_ThrowsOnNullNonce()
 {
     Assert.Throws <ArgumentNullException>(() => NonceManager.Validate(null, ipAddress, privateHashEncoder));
 }
Beispiel #22
0
        public async ValueTask <IdentityModel> LoginCallback(IdentityHttpRequest request)
        {
            OpenIDJwtBinding callbackBinding;

            if (OpenIDJwtBinding.IsCodeBinding(request))
            {
                var callbackCodeBinding = OpenIDBinding.GetBindingForRequest(request, BindingDirection.Response);

                var callbackCodeDocument = new OpenIDLoginResponse(callbackCodeBinding);
                if (!String.IsNullOrWhiteSpace(callbackCodeDocument.Error))
                {
                    throw new IdentityProviderException($"{callbackCodeDocument.Error}: {callbackCodeDocument.ErrorDescription}");
                }

                //Get Token--------------------
                var requestTokenDocument = new OpenIDTokenRequest(callbackCodeDocument.AccessCode, this.secret, OpenIDGrantType.authorization_code, redirectUrl);
                var requestTokenBinding  = OpenIDBinding.GetBindingForDocument(requestTokenDocument, BindingType.Form);

                var requestTokenBody = requestTokenBinding.GetContent();
                var requestToken     = WebRequest.Create(tokenUrl);
                requestToken.Method      = "POST";
                requestToken.ContentType = "application/x-www-form-urlencoded";
                var requestTokenBodyBytes = Encoding.UTF8.GetBytes(requestTokenBody);
                requestToken.ContentLength = requestTokenBodyBytes.Length;
                using (var stream = await requestToken.GetRequestStreamAsync())
                {
#if NETSTANDARD2_0 || NET461_OR_GREATER
                    await stream.WriteAsync(requestTokenBodyBytes, 0, requestTokenBodyBytes.Length);
#else
                    await stream.WriteAsync(requestTokenBodyBytes.AsMemory());
#endif
                    await stream.FlushAsync();
                }

                WebResponse responseToken;
                try
                {
                    responseToken = await requestToken.GetResponseAsync();
                }
                catch (WebException ex)
                {
                    if (ex.Response == null)
                    {
                        throw ex;
                    }
                    var responseTokenStream = ex.Response.GetResponseStream();
                    var error = await new StreamReader(responseTokenStream).ReadToEndAsync();
                    ex.Response.Close();
                    ex.Response.Dispose();
                    throw new IdentityProviderException(error);
                }

                //access_code is a JWT
                callbackBinding = OpenIDJwtBinding.GetBindingForResponse(responseToken, BindingDirection.Response);
            }
            else
            {
                callbackBinding = OpenIDJwtBinding.GetBindingForRequest(request, BindingDirection.Response);
            }

            var callbackDocument = new OpenIDLoginResponse(callbackBinding);
            if (!String.IsNullOrWhiteSpace(callbackDocument.Error))
            {
                throw new IdentityProviderException($"{callbackDocument.Error}: {callbackDocument.ErrorDescription}");
            }

            NonceManager.Validate(serviceProvider, callbackDocument.Nonce);

            if (callbackDocument.Audience != serviceProvider)
            {
                throw new IdentityProviderException("OpenID Audience is not valid", $"Received: {serviceProvider}, Expected: {callbackDocument.Audience}");
            }

            var keys = await GetSignaturePublicKeys(this.identityProviderCertUrl);

            var key = keys.FirstOrDefault(x => x.X509Thumbprint == callbackDocument.X509Thumbprint);
            if (key == null)
            {
                key = keys.FirstOrDefault(x => x.KeyID == callbackDocument.KeyID);
            }
            if (key == null)
            {
                throw new IdentityProviderException("Identity Provider OpenID certificate not found from Json Key Url");
            }
            if (key.KeyType != "RSA")
            {
                throw new IdentityProviderException("Identity Provider OpenID only supporting RSA at the moment");
            }

            RSA rsa;
            if (key.X509Certificates == null || key.X509Certificates.Length == 0)
            {
                var rsaParams = new RSAParameters()
                {
                    Modulus  = Base64UrlEncoder.FromBase64String(key.Modulus),
                    Exponent = Base64UrlEncoder.FromBase64String(key.Exponent)
                };
                rsa = RSA.Create();
                rsa.ImportParameters(rsaParams);
            }
            else
            {
                var certString = key.X509Certificates.First();
                var certBytes  = Convert.FromBase64String(certString);
                var cert       = new X509Certificate2(certBytes);
                rsa = cert.GetRSAPublicKey();
            }

            callbackBinding.ValidateSignature(rsa, requiredSignature);
            callbackBinding.ValidateFields();

            var identity = new IdentityModel()
            {
                UserID          = callbackDocument.UserID,
                UserName        = callbackDocument.UserName ?? callbackDocument.Emails?.FirstOrDefault(),
                Name            = callbackDocument.Name,
                Roles           = callbackDocument.Roles,
                ServiceProvider = callbackDocument.Issuer,
                OtherClaims     = callbackDocument.OtherClaims,
                State           = callbackDocument.State,
                AccessToken     = callbackBinding.AccessToken,
            };

            return(identity);
        }
Beispiel #23
0
 public void IsStale_ThrowsOnEmptyNonce()
 {
     Assert.Throws <ArgumentException>(() => NonceManager.IsStale(string.Empty, TimeSpan.FromSeconds(30)));
 }