无论用户标识和密码组合是否有效,IdentityServer4都会返回有效标记

时间:2017-07-19 00:10:57

标签: c# identityserver4

我正在编写一个Angular4应用程序,我想在IdentityServer4上使用RestFul API进行身份验证/授权。为了开始这个过程,我下载了GitHub IdentityServer4Demo项目。我做了演示工作并决定添加 ResourceOwnerPasswordValidator ProfileService 服务来验证应该有权访问该应用程序的用户。我的问题是,现在所有用户ID /密码组合都会从IdentityServer 触发有效的令牌,无论用户是否有效。我在这里错过了什么? the userid and password should be alice to get an access token Startup.cs

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        var builder = services.AddIdentityServer()
            .AddInMemoryApiResources(Config.GetApis())
            .AddInMemoryIdentityResources(Config.GetIdentityResources())
            .AddInMemoryClients(Config.GetClients());
        //                .AddTestUsers(TestUsers.Users);
        services.AddTransient<IProfileService, Configuration.ProfileService>();
        services.AddTransient<IResourceOwnerPasswordValidator, Configuration.ResourceOwnerPasswordValidator>();


        // demo versions
        services.AddTransient<IRedirectUriValidator, DemoRedirectValidator>();
        services.AddTransient<ICorsPolicyService, DemoCorsPolicy>();

        if (_env.IsDevelopment())
        {
            builder.AddTemporarySigningCredential();
        }
        else
        {
            builder.AddTemporarySigningCredential();
            //builder.AddSigningCredential("6B7ACC520305BFDB4F7252DAEB2177CC091FAAE1", StoreLocation.CurrentUser, nameType: NameType.Thumbprint);
        }
    }

ResourceOwnerPasswordValidator.cs

      public Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
    {
        using (IDbConnection db = new SqlConnection("Data Source=server1;Initial Catalog=myDB;Integrated Security=SSPI;"))
        {
            var user = db.Query<User>("select * from Users where UserName=@UserName and Password=@Password",
                new { UserName = context.UserName, Password = context.Password }).SingleOrDefault<User>();
            if (user == null)
            {
                context.Result = new GrantValidationResult(IdentityModel.OidcConstants.TokenErrors.UnauthorizedClient, "Invalid User of Password.");
                return Task.FromResult<ResourceOwnerPasswordValidationContext>(context);
            }
            else
            {
                context.Result = new GrantValidationResult(user.Id.ToString(), "password");
                return Task.FromResult<ResourceOwnerPasswordValidationContext>(context);
            }

        }
    }

ProfileService.cs

     public class ProfileService : IProfileService
{

    public Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        context.IssuedClaims = context.Subject.Claims.ToList();
        //context.IssuedClaims.Add(new Claim("test-claim", "test-value"));
        return Task.FromResult(0);
    }

    public Task IsActiveAsync(IsActiveContext context)
    {
        return Task.FromResult(0);
    }
}

Config.cs

     public static IEnumerable<Client> GetClients()
    {
        return new List<Client>
        {
            new Client
            {
                ClientId = "client1",
                RequireClientSecret = false,
                //ClientSecrets = { new Secret("secret".Sha256()) },
                //AccessTokenLifetime = 3600,
                //AlwaysSendClientClaims=false,
                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
                AllowedScopes = { "openid", "profile", "email", "api","api1"  },
                                    AllowOfflineAccess = true
            },

2 个答案:

答案 0 :(得分:2)

当你在行var user = db.Query<User>("select * from Users where UserName=@UserName and Password=@Password"上设置断点时,User使用无效的用户名/密码调用它时会有什么价值?它是空的吗?如果没有,则问题出在select / tables上,因为 正在寻找用户。

如果它不为null,则问题在于您如何返回Task.

在我们的实施中,我们正在做类似以下的事情:

context.Result = new GrantValidationResult(TokenRequestErrors.UnauthorizedClient);
return Task.FromResult(false);

这样的成功......

context.Result = new GrantValidationResult(user.UserName, "password", claims);
return Task.FromResult(0);

答案 1 :(得分:0)

不确定为什么你想要角度应用程序的ResourceOwnerPassword流程。您应该使用隐式或混合解决方案。

  

规范建议仅使用资源所有者密码授予   “可信”(或遗留)应用程序。一般来说,你是   通常使用交互式OpenID Connect之一会好得多   当您想要对用户进行身份验证并请求访问令牌时流动。

无论如何,here是一个很好的示例应用程序,您可以查看,可能有助于解决您的问题。