Exemplo n.º 1
0
        /// <summary>
        ///     Acquires the access token and related parameters that go into the formulation of the token endpoint's response to a
        ///     client.
        /// </summary>
        /// <param name="accessTokenRequestMessage">
        ///     Details regarding the resources that the access token will grant access to, and the identity of the client
        ///     that will receive that access.
        ///     Based on this information the receiving resource server can be determined and the lifetime of the access
        ///     token can be set based on the sensitivity of the resources.
        /// </param>
        /// <returns>A non-null parameters instance that DotNetOpenAuth will dispose after it has been used.</returns>
        public AccessTokenResult CreateAccessToken(IAccessTokenRequest accessTokenRequestMessage)
        {
            TimeSpan clientApplicationLifetime = GetClientLifetime(accessTokenRequestMessage);

            var accessToken = new AuthorizationServerAccessToken
            {
                // Note: all other fields are assigned by IsAuthorizationValid() (i.e. ClientIdentifier, Scope, User and UtcIssued)

                // Set the crypto keys for accessing the secured services (assume there is only one secured service)
                AccessTokenSigningKey =
                    CryptoKeyProvider.GetCryptoKey(CryptoKeyType.AuthZServer).PrivateEncryptionKey,
                ResourceServerEncryptionKey = GetRequestedSecureResourceCryptoKey(),

                // Set the limited lifetime of the token
                Lifetime = (clientApplicationLifetime != TimeSpan.Zero)
                    ? clientApplicationLifetime
                    : TimeSpan.FromMinutes(DefaultLifetime),
            };

            // Insert user specific information
            string username = GetUserFromAccessTokenRequest(accessTokenRequestMessage);

            if (username.HasValue())
            {
                IUserAuthInfo user = GetUserAuthInfo(username);
                if (user != null)
                {
                    accessToken.ExtraData.Add(new KeyValuePair <string, string>(
                                                  RequireAuthorizationAttribute.ExtraDataRoles, String.Join(@",", user.Roles)));
                }
            }

            return(new AccessTokenResult(accessToken));
        }
Exemplo n.º 2
0
        /// <summary>
        ///     Determines whether a given set of resource owner credentials is valid based on the authorization server's user
        ///     database
        ///     and if so records an authorization entry such that subsequent calls to <see cref="IsAuthorizationValid" /> would
        ///     return <c>true</c>.
        /// </summary>
        /// <param name="userName">Username on the account.</param>
        /// <param name="password">The user's password.</param>
        /// <param name="accessRequest">
        ///     The access request the credentials came with.
        ///     This may be useful if the authorization server wishes to apply some policy based on the client that is making the
        ///     request.
        /// </param>
        /// <returns>A value that describes the result of the authorization check.</returns>
        /// <exception cref="NotSupportedException">
        ///     May be thrown if the authorization server does not support the resource owner password credential grant type.
        /// </exception>
        public AutomatedUserAuthorizationCheckResponse CheckAuthorizeResourceOwnerCredentialGrant(string userName,
                                                                                                  string password, IAccessTokenRequest accessRequest)
        {
            Guard.NotNullOrEmpty(() => userName, userName);
            Guard.NotNullOrEmpty(() => password, password);
            Guard.NotNull(() => accessRequest, accessRequest);

            bool approved = false;

            //Ensure client exists
            if (IsClientExist(accessRequest.ClientIdentifier))
            {
                // Ensure user exists
                IUserAuthInfo user = UserAccountStore.GetUserAuthInfo(userName);
                if (user != null)
                {
                    if (IsValidScope(accessRequest))
                    {
                        if (user.VerifyPassword(password))
                        {
                            approved = true;

                            //TODO: audit the passed authentication
                        }

                        //TODO: audit the failed authentication
                    }
                }
            }

            return(new AutomatedUserAuthorizationCheckResponse(accessRequest, approved, (approved) ? userName : null));
        }
Exemplo n.º 3
0
        /// <summary>
        ///     Creates a new instance of the <see cref="ClientUserInfo" /> class.
        /// </summary>
        public ClientUserInfo(IUserAuthInfo authInfo, string password, string emailDomain)
        {
            Guard.NotNull(() => authInfo, authInfo);
            Guard.NotNullOrEmpty(() => password, password);
            Guard.NotNullOrEmpty(() => emailDomain, emailDomain);

            AuthInfo         = authInfo;
            Password         = password;
            this.emailDomain = emailDomain;
        }
Exemplo n.º 4
0
            public void WhenGetUserAuthInfoWithUnknownUserName_ThenReturnsNull()
            {
                manager.Setup(
                    uam => uam.ListUserAccounts(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>()))
                .Returns(Enumerable.Empty <IUserAccount>());

                IUserAuthInfo result = store.GetUserAuthInfo("foo");

                Assert.Null(result);
            }
Exemplo n.º 5
0
        public void reading_IUserAuthInfo_for_an_unexisting_user_or_Anonymous_returns_null()
        {
            var p = TestHelper.StObjMap.Default.Obtain <Package>();

            using (var ctx = new SqlStandardCallContext())
            {
                IUserAuthInfo info = p.ReadUserAuthInfo(ctx, 1, int.MaxValue);
                info.Should().BeNull();
                info = p.ReadUserAuthInfo(ctx, 1, 0);
                info.Should().BeNull();
            }
        }
Exemplo n.º 6
0
            public void WhenGetUserAuthInfoProfileWithKnownUserName_ThenReturnsUserAuthInfo()
            {
                var userAccount = new UserAccount
                {
                    Id           = "fooid",
                    Username     = "******",
                    PasswordHash = "bar",
                };

                manager.Setup(
                    uam => uam.ListUserAccounts(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>()))
                .Returns(new[]
                {
                    userAccount
                });

                IUserAuthInfo result = store.GetUserAuthInfo("foo");

                Assert.Equal("bar", result.PasswordHash);
                Assert.Equal("foo2", result.Username);
            }
Exemplo n.º 7
0
        static public void StandardTestForGenericAuthenticationProvider(
            Package auth,
            string schemeOrProviderName,
            Func <int, string, object> payloadForCreateOrUpdate,
            Func <int, string, object> payloadForLogin,
            Func <int, string, object> payloadForLoginFail
            )
        {
            var user = TestHelper.StObjMap.Default.Obtain <Actor.UserTable>();
            IGenericAuthenticationProvider g = auth.FindProvider(schemeOrProviderName);

            using (var ctx = new SqlStandardCallContext())
            {
                string userName = Guid.NewGuid().ToString();
                int    userId   = user.CreateUser(ctx, 1, userName);
                using (TestHelper.Monitor.OpenInfo($"StandardTest for generic {schemeOrProviderName} with userId:{userId} and userName:{userName}."))
                {
                    IUserAuthInfo info = auth.ReadUserAuthInfo(ctx, 1, userId);
                    info.UserId.Should().Be(userId);
                    info.UserName.Should().Be(userName);
                    info.Schemes.Should().BeEmpty();

                    using (TestHelper.Monitor.OpenInfo("CreateOrUpdateUser without login"))
                    {
                        g.CreateOrUpdateUser(ctx, 1, userId, payloadForCreateOrUpdate(userId, userName)).OperationResult.Should().Be(UCResult.Created);
                        info = auth.ReadUserAuthInfo(ctx, 1, userId);
                        info.Schemes.Count.Should().Be(0, "Still no scheme since we did not use WithActualLogin.");

                        g.LoginUser(ctx, payloadForLogin(userId, userName), actualLogin: false).UserId.Should().Be(userId);
                        info = auth.ReadUserAuthInfo(ctx, 1, userId);
                        info.Schemes.Should().BeEmpty("Still no scheme since we challenge login but not use WithActualLogin.");

                        g.LoginUser(ctx, payloadForLogin(userId, userName)).UserId.Should().Be(userId);
                        info = auth.ReadUserAuthInfo(ctx, 1, userId);
                        info.Schemes.Count.Should().Be(1);
                        info.Schemes[0].Name.Should().StartWith(g.ProviderName);
                        info.Schemes[0].Name.Should().BeEquivalentTo(schemeOrProviderName);
                        info.Schemes[0].LastUsed.Should().BeCloseTo(DateTime.UtcNow, 1000);

                        g.DestroyUser(ctx, 1, userId);
                        info = auth.ReadUserAuthInfo(ctx, 1, userId);
                        info.Schemes.Should().BeEmpty();
                    }
                    using (TestHelper.Monitor.OpenInfo("CreateOrUpdateUser WithActualLogin"))
                    {
                        info.UserId.Should().Be(userId);
                        info.UserName.Should().Be(userName);
                        info.Schemes.Should().BeEmpty();

                        var result = g.CreateOrUpdateUser(ctx, 1, userId, payloadForCreateOrUpdate(userId, userName), UCLMode.CreateOnly | UCLMode.WithActualLogin);
                        result.OperationResult.Should().Be(UCResult.Created);
                        result.LoginResult.UserId.Should().Be(userId);
                        info = auth.ReadUserAuthInfo(ctx, 1, userId);
                        info.Schemes.Should().HaveCount(1);
                        info.Schemes[0].Name.Should().StartWith(g.ProviderName);
                        info.Schemes[0].Name.Should().BeEquivalentTo(schemeOrProviderName);
                        info.Schemes[0].LastUsed.Should().BeCloseTo(DateTime.UtcNow, 1000);

                        g.LoginUser(ctx, payloadForLoginFail(userId, userName)).UserId.Should().Be(0);

                        g.DestroyUser(ctx, 1, userId);
                        info = auth.ReadUserAuthInfo(ctx, 1, userId);
                        info.Schemes.Should().BeEmpty();
                    }
                    using (TestHelper.Monitor.OpenInfo("Login for an unregistered user."))
                    {
                        info.UserId.Should().Be(userId);
                        info.UserName.Should().Be(userName);
                        info.Schemes.Should().BeEmpty();

                        var result = g.LoginUser(ctx, payloadForLogin(userId, userName));
                        result.IsSuccess.Should().BeFalse();
                        result.UserId.Should().Be(0);
                        result.FailureCode.Should().Be((int)KnownLoginFailureCode.UnregisteredUser);
                        result.FailureReason.Should().Be("Unregistered user.");
                        info = auth.ReadUserAuthInfo(ctx, 1, userId);
                        info.Schemes.Should().BeEmpty();

                        g.DestroyUser(ctx, 1, userId);
                        info = auth.ReadUserAuthInfo(ctx, 1, userId);
                        info.Schemes.Should().BeEmpty();
                    }
                    using (TestHelper.Monitor.OpenInfo("Invalid payload MUST throw an ArgumentException."))
                    {
                        g.Invoking(sut => sut.CreateOrUpdateUser(ctx, 1, userId, DBNull.Value)).Should().Throw <ArgumentException>();
                        g.Invoking(sut => sut.LoginUser(ctx, DBNull.Value)).Should().Throw <ArgumentException>();
                    }
                }
                user.DestroyUser(ctx, 1, userId);
            }
        }
Exemplo n.º 8
0
        static public async Task StandardTestForGenericAuthenticationProviderAsync(
            Package auth,
            string schemeOrProviderName,
            Func <int, string, object> payloadForCreateOrUpdate,
            Func <int, string, object> payloadForLogin,
            Func <int, string, object> payloadForLoginFail
            )
        {
            var user = TestHelper.StObjMap.Default.Obtain <Actor.UserTable>();
            IGenericAuthenticationProvider g = auth.FindProvider(schemeOrProviderName);

            using (var ctx = new SqlStandardCallContext())
            {
                string userName = Guid.NewGuid().ToString();
                int    userId   = await user.CreateUserAsync(ctx, 1, userName);

                using (TestHelper.Monitor.OpenInfo($"StandardTestAsync for generic {schemeOrProviderName} with userId:{userId} and userName:{userName}."))
                {
                    IUserAuthInfo info = await auth.ReadUserAuthInfoAsync(ctx, 1, userId);

                    info.UserId.Should().Be(userId);
                    info.UserName.Should().Be(userName);
                    info.Schemes.Should().BeEmpty();

                    using (TestHelper.Monitor.OpenInfo("CreateOrUpdateUser without login."))
                    {
                        (await g.CreateOrUpdateUserAsync(ctx, 1, userId, payloadForCreateOrUpdate(userId, userName))).OperationResult.Should().Be(UCResult.Created);
                        info = await auth.ReadUserAuthInfoAsync(ctx, 1, userId);

                        info.Schemes.Should().BeEmpty("Still no scheme since we did not use WithLogin.");

                        (await g.LoginUserAsync(ctx, payloadForLogin(userId, userName), actualLogin: false)).UserId.Should().Be(userId);
                        info = await auth.ReadUserAuthInfoAsync(ctx, 1, userId);

                        info.Schemes.Should().BeEmpty("Still no scheme since we challenge login but not use WithLogin.");

                        (await g.LoginUserAsync(ctx, payloadForLogin(userId, userName))).UserId.Should().Be(userId);
                        info = await auth.ReadUserAuthInfoAsync(ctx, 1, userId);

                        info.Schemes.Should().HaveCount(1);
                        info.Schemes[0].Name.Should().StartWith(g.ProviderName);
                        info.Schemes[0].Name.Should().BeEquivalentTo(schemeOrProviderName);
                        info.Schemes[0].LastUsed.Should().BeCloseTo(DateTime.UtcNow, 1000);

                        await g.DestroyUserAsync(ctx, 1, userId);

                        info = await auth.ReadUserAuthInfoAsync(ctx, 1, userId);

                        info.Schemes.Should().BeEmpty();
                    }
                    using (TestHelper.Monitor.OpenInfo("CreateOrUpdateUser WithActualLogin."))
                    {
                        info.UserId.Should().Be(userId);
                        info.UserName.Should().Be(userName);
                        info.Schemes.Should().BeEmpty();

                        var result = await g.CreateOrUpdateUserAsync(ctx, 1, userId, payloadForCreateOrUpdate( userId, userName ), UCLMode.CreateOnly | UCLMode.WithActualLogin);

                        result.OperationResult.Should().Be(UCResult.Created);
                        result.LoginResult.UserId.Should().Be(userId);
                        info = await auth.ReadUserAuthInfoAsync(ctx, 1, userId);

                        info.Schemes.Count.Should().Be(1);
                        info.Schemes[0].Name.Should().StartWith(g.ProviderName);
                        info.Schemes[0].Name.Should().BeEquivalentTo(schemeOrProviderName);
                        info.Schemes[0].LastUsed.Should().BeCloseTo(DateTime.UtcNow, 1000);

                        (await g.LoginUserAsync(ctx, payloadForLoginFail(userId, userName))).UserId.Should().Be(0);

                        await g.DestroyUserAsync(ctx, 1, userId);

                        info = await auth.ReadUserAuthInfoAsync(ctx, 1, userId);

                        info.Schemes.Should().BeEmpty();
                    }
                    using (TestHelper.Monitor.OpenInfo("Login for an unregistered user."))
                    {
                        info.UserId.Should().Be(userId);
                        info.UserName.Should().Be(userName);
                        info.Schemes.Should().BeEmpty();

                        var result = await g.LoginUserAsync(ctx, payloadForLogin( userId, userName ));

                        result.IsSuccess.Should().BeFalse();
                        result.UserId.Should().Be(0);
                        result.FailureCode.Should().Be((int)KnownLoginFailureCode.UnregisteredUser);
                        result.FailureReason.Should().Be("Unregistered user.");
                        info = await auth.ReadUserAuthInfoAsync(ctx, 1, userId);

                        info.Schemes.Should().BeEmpty();

                        await g.DestroyUserAsync(ctx, 1, userId);

                        info = await auth.ReadUserAuthInfoAsync(ctx, 1, userId);

                        info.Schemes.Should().BeEmpty();
                    }
                    using (TestHelper.Monitor.OpenInfo("Invalid payload MUST throw an ArgumentException."))
                    {
                        g.Awaiting(sut => sut.CreateOrUpdateUserAsync(ctx, 1, userId, DBNull.Value)).Should().Throw <ArgumentException>();
                        g.Awaiting(sut => sut.LoginUserAsync(ctx, DBNull.Value)).Should().Throw <ArgumentException>();
                    }
                    using (TestHelper.Monitor.OpenInfo("Injecting disabled user in sAuthUserOnLogin."))
                        using (auth.Database.TemporaryTransform(@"
                            create transformer on CK.sAuthUserOnLogin
                            as
                            begin
                                inject ""set @FailureCode = 6; -- GloballyDisabledUser"" into ""CheckLoginFailure"";
                            end
                        "))
                        {
                            UCLResult result = await g.CreateOrUpdateUserAsync(ctx, 1, userId, payloadForCreateOrUpdate( userId, userName ), UCLMode.CreateOnly | UCLMode.WithActualLogin);

                            result.OperationResult.Should().Be(UCResult.Created);
                            result.LoginResult.UserId.Should().Be(0);
                            result.LoginResult.IsSuccess.Should().BeFalse();
                            result.LoginResult.FailureCode.Should().Be((int)KnownLoginFailureCode.GloballyDisabledUser);
                            LoginResult login = await g.LoginUserAsync(ctx, payloadForLogin( userId, userName ));

                            login.IsSuccess.Should().BeFalse();
                            login.UserId.Should().Be(0);
                            login.FailureCode.Should().Be((int)KnownLoginFailureCode.GloballyDisabledUser);
                            login = await g.LoginUserAsync(ctx, payloadForLogin( userId, userName ), actualLogin : false);

                            login.IsSuccess.Should().BeFalse();
                            login.UserId.Should().Be(0);
                            login.FailureCode.Should().Be((int)KnownLoginFailureCode.GloballyDisabledUser);
                        }
                }
                await user.DestroyUserAsync(ctx, 1, userId);
            }
        }