当前位置: 首页 > 知识库问答 >
问题:

ASP.NET内核中基于令牌的身份验证

微生学
2023-03-14

我正在使用ASP.NET核心应用程序。我正在尝试实现基于令牌的身份验证,但无法确定如何使用新的安全系统。我查看了一些示例,但它们对我没有太大帮助,它们使用的是cookie身份验证或外部身份验证(GitHub、Microsoft、Twitter)。

我的场景是:angularjs应用程序应该请求/tokenurl,传递用户名和密码。WebApi应该授权user并返回access_token,angularjs应用程序将在以下请求中使用该access_token

我找到了关于在当前版本的ASP.NET中实现我所需要的东西的很好的文章--使用ASP.NET Web API2、Owin和Identity基于令牌的身份验证。但如何在ASP.NET核心中做同样的事情对我来说并不明显。

我的问题是:如何配置ASP.NET Core WebApi应用程序来使用基于令牌的身份验证?

共有1个答案

林绪
2023-03-14

David Fowler(ASP.NET Core team的架构师)组合了一组非常简单的任务应用程序,包括一个演示JWT的简单应用程序。我会把他的更新和简单化的风格融入这个帖子很快。

此答案的以前版本使用RSA;如果生成令牌的代码同时也在验证令牌,则实际上没有必要这样做。但是,如果要分配责任,您可能仍然希望使用microsoft.identitymodel.tokens.rsasecuritykey的实例来完成此操作。

>

  • 创建一些我们稍后将使用的常量;我是这么做的:

    const string TokenAudience = "Myself";
    const string TokenIssuer = "MyProject";
    

    将此添加到您的Startup.cs的configureReservices中。我们稍后将使用依赖注入来访问这些设置。我假设您的AuthenticationConfiguration是一个ConfigurationSectionConfiguration对象,这样您就可以为调试和生产使用不同的配置。确保您安全地存储您的钥匙!可以是任何字符串。

    var keySecret = authenticationConfiguration["JwtSigningKey"];
    var symmetricKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(keySecret));
    
    services.AddTransient(_ => new JwtSignInHandler(symmetricKey));
    
    services.AddAuthentication(options =>
    {
        // This causes the default authentication scheme to be JWT.
        // Without this, the Authorization header is not checked and
        // you'll get no results. However, this also means that if
        // you're already using cookies in your app, they won't be 
        // checked by default.
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    })
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters.ValidateIssuerSigningKey = true;
            options.TokenValidationParameters.IssuerSigningKey = symmetricKey;
            options.TokenValidationParameters.ValidAudience = JwtSignInHandler.TokenAudience;
            options.TokenValidationParameters.ValidIssuer = JwtSignInHandler.TokenIssuer;
        });
    

    我见过其他答案更改其他设置,如clockskew;默认值的设置使它能够适用于时钟不完全同步的分布式环境。这些是您需要更改的唯一设置。

    设置身份验证。您应该在任何需要用户信息的中间件(如app.useMVC())之前有这一行。

    app.UseAuthentication();
    

    请注意,这不会导致您的令牌与SigninManager或其他任何东西一起发出。您将需要提供自己的机制来输出您的JWT-请参见下面。

    您可能希望指定authorizationpolicy。这将允许您使用[authorize(“barer”)]指定仅允许承载令牌作为身份验证的控制器和操作。

    services.AddAuthorization(auth =>
    {
        auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
            .AddAuthenticationTypes(JwtBearerDefaults.AuthenticationType)
            .RequireAuthenticatedUser().Build());
    });
    

    棘手的部分来了:构建令牌。

    class JwtSignInHandler
    {
        public const string TokenAudience = "Myself";
        public const string TokenIssuer = "MyProject";
        private readonly SymmetricSecurityKey key;
    
        public JwtSignInHandler(SymmetricSecurityKey symmetricKey)
        {
            this.key = symmetricKey;
        }
    
        public string BuildJwt(ClaimsPrincipal principal)
        {
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
    
            var token = new JwtSecurityToken(
                issuer: TokenIssuer,
                audience: TokenAudience,
                claims: principal.Claims,
                expires: DateTime.Now.AddMinutes(20),
                signingCredentials: creds
            );
    
            return new JwtSecurityTokenHandler().WriteToken(token);
        }
    }
    
    [HttpPost]
    public string AnonymousSignIn([FromServices] JwtSignInHandler tokenFactory)
    {
        var principal = new System.Security.Claims.ClaimsPrincipal(new[]
        {
            new System.Security.Claims.ClaimsIdentity(new[]
            {
                new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Name, "Demo User")
            })
        });
        return tokenFactory.BuildJwt(principal);
    }
    

    如果您在HTML页面上的部分视图中结合.NET4.5中的仅承载身份验证呈现这一点,那么现在可以使用ViewComponent来完成同样的操作。它与上面的控制器操作代码基本相同。

  •  类似资料:
    • 问题内容: 我有一个REST API,我正在使用Spring Security基本授权进行身份验证,客户端会为每个请求发送用户名和密码。现在,我想实现基于令牌的身份验证,当用户最初通过身份验证时,我将在响应标头中发送令牌。对于进一步的请求,客户端可以在令牌中包含该令牌,该令牌将用于对资源进行用户身份验证。我有两个身份验证提供程序tokenAuthenticationProvider和daoAuth

    • 在daoAuthenticationProvider中,我设置了自定义userDetailsService并通过从数据库中获取用户登录详细信息对其进行身份验证(只要使用授权传递用户名和密码就可以正常工作:basic bgllqxbpvxnlcjogn21wxidmqjrdturtr04pag==作为头) 但是当我使用X-AUTH-TOKEN(即constants.auth_header_name)

    • 问题内容: 我正在PHP Lumen中构建一个应用程序,该应用程序在登录时会返回令牌。我不知道如何继续进行。 我应该如何使用这些令牌维护会话? 具体来说,如果我使用reactjs或原始HTML / CSS / jQuery,如何将令牌存储在客户端,并在我为Web应用程序的安全部分提出的每个请求中发送令牌? 问题答案: 我通常要做的是将令牌保留在本地存储中,这样即使用户离开站点,我也可以保留令牌。

    • 我正在PHP Lumen中构建一个应用程序,它在登录时返回令牌。我不知道如何继续。 我应该如何使用这些令牌维护会话? 具体来说,如果我使用reactjs或vanilla HTML/CSS/jQuery,我如何在客户端存储令牌,并在我为web应用程序的安全部分发出的每个请求中发送它们?

    • 我读了一些关于“JWT vs Cookie”的帖子,但它们只会让我更加困惑…… > 我想澄清一下,当人们谈论“基于令牌的身份验证与cookie”时,这里的cookie仅指会话cookie?我的理解是,cookie就像一个介质,它可以用来实现基于令牌的身份验证(在客户端存储可以识别登录用户的东西)或者基于会话的身份验证(在客户端存储与服务器端会话信息匹配的常量) 为什么我们需要JSON web令牌?