简体   繁体   English

使用不带身份的承载/ Jwt授权

[英]Using Bearer/Jwt authorization without Identity

I'm developing a Web API with Asp 5 and reading some documents about Web API realize I need Bearer authorization. 我正在使用Asp 5开发Web API并阅读有关Web API的一些文档,因此我需要获得Bearer授权。

After searching I can't find any document or sample that use authorization without Aspnet.Identity . 搜索后,我发现没有Aspnet.Identity使用授权的任何文档或样本。 I have my own membership and I don't want to use Identity 我有自己的会员资格,我不想使用Identity
Should I use Identity library? 我应该使用Identity库吗? or is there a way to implement authorization in my membership. 或者有没有办法在我的会员资格中实施授权。

One little side question: 一个小问题:
if I'm forced to use Identity how can I change EntityFramework to something like dapper or ADO.NET for my DBContext ? 如果我被迫使用Identity,我怎样才能将EntityFramework更改为dapper或ADO.NET以用于我的DBContext

To issue your own JWT tokens, you can use OpenIddict : 要发布自己的JWT令牌,可以使用OpenIddict

project.json project.json

{
  "dependencies": {
    // ...
    "AspNet.Security.OAuth.Validation": "1.0.0-*",
    "OpenIddict": "1.0.0-*",
    "OpenIddict.EntityFrameworkCore": "1.0.0-*",
    "OpenIddict.Mvc": "1.0.0-*"
  }
}

Startup.cs Startup.cs

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

        services.AddDbContext<DbContext>(options =>
        {
            // Configure the context to use an in-memory store.
            options.UseInMemoryDatabase();

            // Register the entity sets needed by OpenIddict.
            // Note: use the generic overload if you need
            // to replace the default OpenIddict entities.
            options.UseOpenIddict();
        });

        services.AddOpenIddict(options =>
        {
            // Register the Entity Framework stores.
            options.AddEntityFrameworkCoreStores<DbContext>();

            // Register the ASP.NET Core MVC binder used by OpenIddict.
            // Note: if you don't call this method, you won't be able to
            // bind OpenIdConnectRequest or OpenIdConnectResponse parameters.
            options.AddMvcBinders();

            // Enable the token endpoint.
            options.EnableTokenEndpoint("/connect/token");

            // Enable the password flow.
            options.AllowPasswordFlow();

            // During development, you can disable the HTTPS requirement.
            options.DisableHttpsRequirement();
        });
    }

    public void Configure(IApplicationBuilder app)
    {
        // Register the validation middleware, that is used to decrypt
        // the access tokens and populate the HttpContext.User property.
        app.UseOAuthValidation();

        // Register the OpenIddict middleware.
        app.UseOpenIddict();

        app.UseMvcWithDefaultRoute();
    }
}

AuthorizationController.cs AuthorizationController.cs

public class AuthorizationController : Controller
{
    [HttpPost("~/connect/token"), Produces("application/json")]
    public IActionResult Exchange(OpenIdConnectRequest request)
    {
        if (request.IsPasswordGrantType())
        {
            // Validate the user credentials.
            // Note: to mitigate brute force attacks, you SHOULD strongly consider
            // applying a key derivation function like PBKDF2 to slow down
            // the password validation process. You SHOULD also consider
            // using a time-constant comparer to prevent timing attacks.
            if (request.Username != "alice@wonderland.com" ||
                request.Password != "P@ssw0rd")
            {
                return Forbid(OpenIdConnectServerDefaults.AuthenticationScheme);
            }

            // Create a new ClaimsIdentity holding the user identity.
            var identity = new ClaimsIdentity(
                OpenIdConnectServerDefaults.AuthenticationScheme,
                OpenIdConnectConstants.Claims.Name,
                OpenIdConnectConstants.Claims.Role);

            // Add a "sub" claim containing the user identifier, and attach
            // the "access_token" destination to allow OpenIddict to store it
            // in the access token, so it can be retrieved from your controllers.
            identity.AddClaim(OpenIdConnectConstants.Claims.Subject,
                "71346D62-9BA5-4B6D-9ECA-755574D628D8",
                OpenIdConnectConstants.Destinations.AccessToken);

            identity.AddClaim(OpenIdConnectConstants.Claims.Name, "Alice",
                OpenIdConnectConstants.Destinations.AccessToken);

            // ... add other claims, if necessary.
            var principal = new ClaimsPrincipal(identity);

            // Ask OpenIddict to generate a new token and return an OAuth2 token response.
            return SignIn(principal, OpenIdConnectServerDefaults.AuthenticationScheme);
        }

        throw new InvalidOperationException("The specified grant type is not supported.");
    }
}

Request 请求

POST /connect/token HTTP/1.1
Host: localhost:7096
Content-Type: application/x-www-form-urlencoded

grant_type=password&username=alice%40wonderland.com&password=P%40ssw0rd

Response 响应

{
  "token_type": "Bearer",
  "access_token": "CfDJ8Ec0ZpniaHhGg0e0UUvOH9BWZSGrPoEwGd0_Lq2cse-T29YOq985IBiT5fEe5tTSgY1vxq2Z2ZJ7Ikwlpmh0Lrc4x9pqhqHBziUzsP_rkGZkn47TkNkOkzKCwZJZK5x-irH3HROwClFFTq0rgWdb8rZ2xriffNzsby4VwhxhN5soFD435KzmVYkdv-VuaLYo3QiSuexbRi2USVO9LK30vomAG6h2SAxZ7R-jYsXgf0f5gAmdYxg7w3yicv9v8DpUSBiGGRRfymTOnvGEsFJjGuuP8OlY5qzMs6wGaRWkOvCyV2CK_RZF_3TMs7LYCdMQ-dqWY5A03-03OmP8blKzlrKJMDZfrPQHuysbS931xxy8b3kjicfjNLmMHqzQzbUO4fecm4kY8PFnKozojDtqajfTp2bYhxS65bmVYROrswYeUWEKYR6LSdS1K__IDaLoMlLa-Wf6x1wjM2CchzgqbHRF0KEtdL5Ks88dAS44mp9BM6iUOEWyL7VkbazsBdlNciM5ZZB1_6qunufDW_tcaR8",
  "expires_in": 3600
}

For more information, you can read this blog post I wrote about OpenIddict: http://kevinchalet.com/2017/01/30/implementing-simple-token-authentication-in-aspnet-core-with-openiddict/ 有关更多信息,请阅读我撰写的关于OpenIddict的博客文章: http ://kevinchalet.com/2017/01/30/implementing-simple-token-authentication-in-aspnet-core-with-openiddict/

There's already a JWT Bearer middleware , you just need to write something that issues bearer tokens. 已经有一个JWT Bearer中间件 ,你只需要写一些发行持有令牌的东西。 That's a little more complicated, depending on what you use as your identity store, and as you indicate it's something custom, it's hard to advise on any approach. 这有点复杂,取决于您使用什么作为您的身份存储,并且当您指出它是定制的时候,很难就任何方法提出建议。 Creating JWT tokens isn't that hard though; 创建JWT令牌并不是那么难;

var now = DateTime.UtcNow;

// Creates new keys automatically, you'd want to store these somewhere
var aes = new AesCryptoServiceProvider();

var signingTokenHandler = new JwtSecurityTokenHandler();
var tokenDescriptor = new SecurityTokenDescriptor
{
    Subject = new ClaimsIdentity(
                new[]
                {
                    new Claim(JwtRegisteredClaimNames.Aud, "YOURWEBSITEURL")                    }),
                    TokenIssuerName = "YourWebSite",
                    Lifetime = new Lifetime(now, now.AddHours(1)),
                    SigningCredentials = new SigningCredentials(
                        new InMemorySymmetricSecurityKey(aes.Key),
                        "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256",
                        "http://www.w3.org/2001/04/xmlenc#sha256")
                };

var token = signingTokenHandler.CreateToken(tokenDescriptor);
var tokenAsString = signingTokenHandler.WriteToken(token);

None of the authorization pieces depend on membership at all, they'll work with any authentication middleware. 任何授权部分都不依赖于成员身份,它们将与任何身份验证中间件一起使用。 None of the documentation for authorization even refers to Identity at all. 授权文档都没有提到身份。

There's an authorization workshop available. 有一个授权研讨会 You can see in the source for that that no-one does identity appear, it's creating user principals on the fly and then storing them in cookies. 您可以在源代码中看到没有人出现身份,它会动态创建用户主体,然​​后将它们存储在cookie中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM