asp.net core integrated JWT

[What is] JWT

  JSON Web Token (JWT) is the most popular cross-domain authentication solutions.

  JWT's official website address: https://jwt.io/

  Colloquially speaking, JWT is able to represent the user's identity tokens, tokens can be used in identity JWT api user interface check to confirm whether the user has access to the api.

  JWT contains parameters necessary for authentication and user-defined parameters, JWT using a secret (using HMAC algorithm) or by using RSA or ECDSA public / private key pair were signing .

[When should you use JSON Web Token? ]

  1. Authorization: This is the most common use of JWT program. Once the user logs on, each subsequent request will include the JWT, allowing users to access the token allows routing, services and resources. Single Sign On is a function of JWT now widely used because of its low overhead, and can easily use a different domain.

  2. Information exchange: JSON Web Token is a good way to secure transmission of information between the parties. Because JWT can sign - for example, using public / private key pairs - you can determine the sender is who they say. In addition, the use of headers and payload calculation signature, you can also verify that the content has not been tampered with.

[JWT What are the advantages? ]

  We look at the way our traditional identity verification

  1. User sends the username and password to the server.
  2. After the server is verified, in the current session (session) which holds the relevant data, such as user roles, login time, and so on.
  3. Session_id a server returns to the user, the user writes the Cookie.
  4. The user then every request will by Cookie, the session_id back to the server.
  5. Server receives session_id, find pre-stored data, therefore represents the user's identity.

  The problem with this model is that, scalability (scaling) is not good. Stand-alone course, no problem, if it is a cluster of servers, or cross-domain service-oriented architecture, it requires data sharing session, each server can read the session. If the session storage node hung up, then the whole service will be paralyzed, very bad experience, risks are high.

  In contrast, JWT implementation is user information stored in the client, the server does not save it. Bring regarded each request token to verify the user logged in, this service becomes stateless, server cluster is also very good extension.

[Structure] Token JWT

  In a compact form, JSON Web Tokens by the (DOT .) of three parts separated by composition , are:

  • Header head
  • Payload Payload
  • Signature Signature

  Thus, JWT generally as follows:

  xxxxx.yyyyy.zzzzz

  1.Header head

  Header typically consists of two parts: the token type, i.e. the JWT, and the signature algorithm being used, for example, HMAC SHA256 or RSA.

  E.g:

{
  "alg": "HS256",
  "typ": "JWT"
}

  Then the JSON is coded as Base64Url , forming a first portion of the JWT.

  Payload 2.Payload

  Payload is part of a JSON object, used to store the actual data transfer is required. JWT provides for seven official field for the selection.

  • iss (issuer): issuer

  • exp (expiration time): Expiration Time

  • sub (subject): Theme

  • aud (audience): Audience

  • nbf (Not Before): Effective time

  • iat (Issued At): The issue of time

  • jti (JWT ID): No.

  In addition to the official field, you can also define a private field in this section, the following is an example. E.g:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

  Note, JWT default is not encrypted, anyone can read, so do not put confidential information in this section. The JSON object should use Base64URL algorithm translated into strings.

  3.Signature signature

  Signature is a signature part of the first two parts, prevent data tampering.

  First, you need to specify a key (secret). The key is to know only the server can not be disclosed to the user. Then, using the signature algorithm specified inside Header (default HMAC SHA256), generating a signature in accordance with the following equation.

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

  Signature used to authenticate the message has not been altered during this process, and, in the case of using the private key signature token, it can verify that the sender JWT is what it purports people.  

  All three of them together

  The output is separated by three points Base64-URL string can be easily passed HTML and HTTP environment, and more compact in comparison with standard XML-based (such as SAML).

  The following shows a the JWT, having previously encoded header and a payload, and the use of secret signature. 

  

  If you want to use JWT and these concepts into practice, you can use jwt.io Debugger to decode, verify and generate JWT.

   

[How JSON Web Token work? ]

  In authentication, when a user successfully logs in using their credentials, will return JSON Web Token. As the token is evidence, it must be very careful to prevent security problems. Under normal circumstances, you should not exceed the required time token reserved.

  Whenever the user wants to access a protected resource or routing, user agent should use the bearer mode transmits the JWT, usually Authorization header . A content title to be as follows:

  Authorization: Bearer <token>

  In some cases, this can be no state licensing mechanism. Protection by routing server checks the Authorizationheader of effective the JWT  , if present, allows a user to access a protected resource. If JWT contain the necessary data, you can query the database to reduce the need for certain operations, although it may not always be the case.

  If the standard Authorizationheader sent token , the Cross-Origin Resource Sharing (CORS) will not be a problem, because it does not use cookie.

  The following figure shows how to get JWT API for accessing and or resources:

  

  1. Application requests authorization to the authorization server
  2. Verify user identity verification succeeds, the return token
  3. Applications using the access token to access a protected resource

[ASP.Net Core integrated JWT]

  Earlier we introduced the principle of JWT, let's integrated JWT in asp.net core practical projects.

  First, we create a new empty web project Demo asp.net core

  

  Add simulation data access api, ValuesController

  Wherein api / value1 is directly accessible, api / value2 with authorization check feature tag [the Authorize]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Demo.Jwt.Controllers
{
    [ApiController]
    public class ValuesController : ControllerBase
    {
        [HttpGet]
        [Route("api/value1")]
        public ActionResult<IEnumerable<string>> Get()
        {
            return new string[] { "value1", "value1" };
        }

        [HttpGet]
        [Route("api/value2")]
        [Authorize]
        public ActionResult<IEnumerable<string>> Get2()
        {
            return new string[] { "value2", "value2" };
        }
    }
}

  Add simulated landing, Token generate the api, AuthController

  Here simulate what landing check, only to verify the user's password is not empty, ie by check, real perfect environment to check user and password logic.

using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;

namespace Demo.Jwt.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AuthController : ControllerBase
    {
        [AllowAnonymous]
        [HttpGet]
        public IActionResult Get(string userName, string pwd)
        {
            if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(pwd))
            {
                var claims = new[]
                {
                    new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,
                    new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddMinutes(30)).ToUnixTimeSeconds()}"),
                    new Claim(ClaimTypes.Name, userName)
                };
                var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Const.SecurityKey));
                var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
                var token = new JwtSecurityToken(
                    issuer: Const.Domain,
                    audience: Const.Domain,
                    claims: claims,
                    expires: DateTime.Now.AddMinutes(30),
                    signingCredentials: creds);

                return Ok(new
                {
                    token = new JwtSecurityTokenHandler().WriteToken(token)
                });
            }
            else
            {
                return BadRequest(new { message = "username or password is incorrect." });
            }
        }
    }
}

  Startup add JWT authentication configuration

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Text;


namespace Demo.Jwt
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // add jwt verification: 
            services.AddAuthentication (JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options => {
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuer = to true , // verify Issuer 
                        ValidateAudience = to true , // verify Audience 
                        ValidateLifetime = to true , // verify failure time 
                        ClockSkew = TimeSpan.FromSeconds ( 30 ),
                        ValidateIssuerSigningKey = to true , // verify SecurityKey 
                        ValidAudience = Const.Domain, // Audience 
                        ValidIssuer = Const.Domain, // Issuer, both issued and disposed in front of the same jwt 
                        IssuerSigningKey = new new SymmetricSecurityKey (Encoding.UTF8.GetBytes (Const .SecurityKey)) // get SecurityKey 
                    };
                });

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            /// Add jwt verification 
            app.UseAuthentication ();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                        template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

  Finally, some constants related to the code which used also pasted, Const.cs

namespace Demo.Jwt
{
    public class Const
    {
        ///  <the Summary> 
        /// Here To demonstrate, write the death of one key. Production environments can be read from the configuration file, this is just a tool generating line key
         ///  </ Summary> 
        public  const  String SecurityKey = " MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2a2EJ7m872v0afyoSDJT2o1 SitIeJSWtLJU8 + / + Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI543nNDAPfnJsas96mSA7L Wz2m7gStexajkeD / mD7RTE2drj6hf3oZjJpMPZUQI / B1Qjb5H3K3PNwIDAQAB " ;
         public  const  String = Domain " HTTP: // localhost: 5000 " ;
    }
}

  Here, we have all the code of the project.

  If you need to complete the project code, Github Address: https://github.com/sevenTiny/Demo.Jwt

JWT [Test]

   We are looking for a tool conveniently, such as fiddler, and our web site up and running

  First call without permission interface: http: // localhost: 5000 / api / value1

  

  

  Correctly return the data, then the next we test JWT process

  1. No authority

  First, we have nothing to add call interface: http: // localhost: 5000 / api / value2

  

  

  It returns a status code 401, which is Unauthorized: Access is denied due to invalid credentials. Description JWT check into effect, we received a protection interface.

  2. Get Token

  Call simulated landing authorization interface: http: // localhost: 5000 / api / Auth userName = zhangsan & pwd = 123?

  Here the user password is just to write, because we only check a simulated landing is not empty, so what can write by

  

  Success was echoed

  

  

  Then we got a token value xxx.yyy.zzz format. We copied out token

  3. Add the parameters JWT in just 401 interface HEADER request, the token add to our

  We called again analog data interface, but this time we added a HEADER: http: // localhost: 5000 / api / value2

  

  The contents stick out

User-Agent: Fiddler
Host: localhost:5000
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOiIxNTYwMzQ1MDIxIiwiZXhwIjoxNTYwMzQ2ODIxLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiemhhbmdzYW4iLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjUwMDAiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjUwMDAifQ.x7Slk4ho1hZc8sR8_McVTB6VEYLz_v-5eaHvXtIDS-o

  It should be noted that there is a space behind Bearer, and then what we get to the last step of the token

  

  

  Ah, no 401, and successfully returned data

  4.JWT of Token expired

  Let us pour a cup of boiling water, wait 30 minutes (the expiration time we set in code), then call data interface again: http: // localhost: 5000 / api / value2

  

  

  It is a 401, look at our detailed return data

  

  There tagging, error description token expired, indicating token expiration time we set the entry into force

【End】

  Here, we profile and asp.net core JWT JWT has integrated perfectly completed, of course, this is just a demo, where it is needed to supplement and improve the practical application as well.

  If you want the complete project source code, you can refer to the address: https://github.com/sevenTiny/Demo.Jwt

  If fortunate enough to be able to help you, spare a star point it ~

Guess you like

Origin www.cnblogs.com/7tiny/p/11012035.html