首页 文章

ASP.NET Boilerplate IdentityServer

提问于
浏览
1

我试图实现IdentityServer,因为它在https://aspnetboilerplate.com/Pages/Documents/Zero/Identity-Server解释

但样本不起作用 .

我从ASP.NET Boilerplate开始了一个Core 2.0 Angular项目 . 是否有基于文档的更新工作样本?

有一个以上的问题,但其中一个是 AuthConfigurer.cs .

API调用者(客户端)无法传递令牌验证 .

实际上,_1665399中有一个令牌生成代码:

private string CreateAccessToken(IEnumerable<Claim> claims, TimeSpan? expiration = null)
{
    var now = DateTime.UtcNow;
    var jwtSecurityToken = new JwtSecurityToken(
        issuer: _configuration.Issuer,
        audience: _configuration.Audience,
        claims: claims,
        notBefore: now,
        expires: now.Add(expiration ?? _configuration.Expiration),
        signingCredentials: _configuration.SigningCredentials
    );
    return new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
}

但是在 Startup 类中, AddIdentityAddAuthentication 会创建不同的标记值和验证规则 .

services.AddIdentityServer()
        .AddDeveloperSigningCredential()
        .AddInMemoryIdentityResources(IdentityServerConfig.GetIdentityResources())
        .AddInMemoryApiResources(IdentityServerConfig.GetApiResources())
        .AddInMemoryClients(IdentityServerConfig.GetClients())
        .AddAbpPersistedGrants<IAbpPersistedGrantDbContext>()
        .AddAbpIdentityServer<User>(); ;

services.AddAuthentication().AddIdentityServerAuthentication("IdentityBearer", options =>
{
    options.Authority = "http://localhost:62114/";
    options.RequireHttpsMetadata = false;
});

令牌可以由双方生成 . CreateAccessToken 由Angular客户端和API客户端调用,如下所示:

var disco = await DiscoveryClient.GetAsync("http://localhost:21021");

var httpHandler = new HttpClientHandler();
httpHandler.CookieContainer.Add(new Uri("http://localhost:21021/"), new Cookie(MultiTenancyConsts.TenantIdResolveKey, "1")); //Set TenantId
var tokenClient = new TokenClient(disco.TokenEndpoint, "AngularSPA", "secret", httpHandler);
var tokenResponse = await tokenClient.RequestResourceOwnerPasswordAsync("admin", "123qwe", "default-api"); //RequestClientCredentialsAsync("default-api");

但只有其中一个(根据身份验证部分)无法通过身份验证 .

我需要API客户端身份验证和Angular客户端身份验证才能工作 .

我从一个关于双重身份验证的链接中得到了一些线索:
https://wildermuth.com/2017/08/19/Two-AuthorizationSchemes-in-ASP-NET-Core-2

但我无法解决这个问题 . 任何评论对解决问题都非常有 Value .

2 回答

  • 3

    在和我设法解决问题这里是需要的修改;

    1-在TokenAuthController中有一个令牌创建代码,如下所示;

    private static List<Claim> CreateJwtClaims(ClaimsIdentity identity)
            {
                var claims = identity.Claims.ToList();
                var nameIdClaim = claims.First(c => c.Type == ClaimTypes.NameIdentifier);
    
                // Specifically add the jti (random nonce), iat (issued timestamp), and sub (subject/user) claims.
                claims.AddRange(new[]
                {
                    new Claim(JwtRegisteredClaimNames.Sub, nameIdClaim.Value),
                    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                    new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.Now.ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64)
                });
    
                return claims;
            }
    

    如果您开始使用Identityserver来自登录的声明与当前实现完全不同,并且“sub”声明已添加到声明中 . 因此没有必要单独添加 . 所以请更新如下所示

    private static List<Claim> CreateJwtClaims(ClaimsIdentity identity)
            {
                var claims = identity.Claims.ToList();
    
                // Specifically add the jti (random nonce), iat (issued timestamp), and sub (subject/user) claims.
                claims.AddRange(new[]
                {
                    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                    new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.Now.ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64)
                });
    
                return claims;
            }
    

    2-将Authentcation添加到启动类,如下所示;最重要的部分是authenticationSchemaName“IdentityBearer”,不要忘记添加它 .

    services.AddAuthentication().AddIdentityServerAuthentication("IdentityBearer", options =>
                {
                    options.Authority = "http://localhost:21021/";
                    options.RequireHttpsMetadata = false;
                });
    

    3-但这还不够 . 因为如果你看启动authontication中的配置方法注册为

    app.UseJwtTokenMiddleware();
    

    如果你检查它,它使用“bearer”架构而不是我们在上面添加的IdentityBearer . 所以我们还需要一个真正的认证注册 . 添加此行(同时使用它们)

    app.UseJwtTokenMiddleware("IdentityBearer");
    

    4-但是你可以看到没有方法采用字符串参数来添加UseJwtTokenMiddleware,因此需要将该类更新为 . 请改变你的课程,如下所示;

    using Microsoft.AspNetCore.Authentication;
    using Microsoft.AspNetCore.Authentication.JwtBearer;
    using Microsoft.AspNetCore.Builder;
    
    namespace MyProject.Authentication.JwtBearer
    {
        public static class JwtTokenMiddleware
        {
            public static IApplicationBuilder UseJwtTokenMiddleware(this IApplicationBuilder app)
            {
                return UseJwtTokenMiddleware(app, JwtBearerDefaults.AuthenticationScheme);
            }
    
            public static IApplicationBuilder UseJwtTokenMiddleware(this IApplicationBuilder app, string authenticationScheme)
            {
                return app.Use(async (ctx, next) =>
                {
                    if (ctx.User.Identity?.IsAuthenticated != true)
                    {
                        var result = await ctx.AuthenticateAsync(authenticationScheme);
                        if (result.Succeeded && result.Principal != null)
                        {
                            ctx.User = result.Principal;
                        }
                    }
    
                    await next();
                });
            }        
        }
    }
    

    现在你有两种不同的令牌类型和两种不同的验证器 . 您可以使用基本令牌信息的API客户端,并通过从角客户端登录来创建JWT令牌 . 如果您调试每个请求尝试传递其中两个,但只有其中一个成功,这对您来说已经足够了 .

    如果aspnetboilerplate团队根据这个要求更新样本,那就太好了 .

  • 0

    虽然我还在尝试理解整个过程,但我发现GitHub上的这个存储库在ABP和IdentityServer4方面非常有用 . IdentityServer的ABP文档不完整,下载IdentityServerDemo示例,运行它,如果成功将其与您的代码进行比较:

    https://github.com/parallelbgls/aspnetboilerplate-samples

相关问题