In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
How to obtain ASP.NETCoreToken certification, many novices are not very clear about this, in order to help you solve this problem, the following editor will explain in detail for you, people with this need can come to learn, I hope you can gain something.
Token authentication (Token Authentication) has become the de facto standard for single page applications (SPA) and mobile applications. Even the traditional Bhand S application can take advantage of its advantages. The advantages are clear: little server-side data management, scalability, and the ability to separate the authentication server from the application server.
If you don't know much about token, you can read this article (overview of token authentication and JWTs)
Token authentication is integrated in asp.net core. This includes the routing capabilities to protect Bearer Jwt, but removes the parts that generate token and verify token, which can be customized or implemented using third-party libraries, and MVC and Web api projects can use token authentication, which is simple. The following will be implemented step by step, and the code can be downloaded from (source code).
ASP.NET Core token authentication
First, background knowledge: authentication tokens, such as JWTs, are passed through the http authentication header, for example:
GET / fooAuthorization: Bearer [token]
Tokens can be accessed through the browser cookies. The delivery method is header or cookies depending on the application and the actual situation. For mobile app, use headers. For web, it is recommended to use cookies in html5 storage to prevent xss attacks.
Asp.net core's authentication of jwts tokens is simple, especially if you pass it through header.
1. Generate SecurityKey. For this example, I generate a symmetric key to verify jwts through HMAC-SHA256 encryption, in startup.cs:
/ / secretKey contains a secret passphrase only your server knowsvar secretKey = "mysupersecretsecretsecretkeykeeper 123"; var signingKey = new SymmetricSecurityKey (Encoding.ASCII.GetBytes (secretKey))
Verify the JWTs passed in header
In Startup.cs, use the UseJwtBearerAuthentication method in Microsoft.AspNetCore.Authentication.JwtBearer to get the jwt that is valid for a protected api or mvc route.
Var tokenValidationParameters = new TokenValidationParameters {/ / The signing key must match! ValidateIssuerSigningKey = true, IssuerSigningKey = signingKey, / / Validate the JWT Issuer (iss) claim ValidateIssuer = true, ValidIssuer = "ExampleIssuer", / / Validate the JWT Audience (aud) claim ValidateAudience = true, ValidAudience = "ExampleAudience", / / Validate the token expiry ValidateLifetime = true, / / If you want to allow a certain amount of clock drift, set that here: ClockSkew = TimeSpan.Zero}; app.UseJwtBearerAuthentication (new JwtBearerOptions {AutomaticAuthenticate = true, AutomaticChallenge = true, TokenValidationParameters = tokenValidationParameters})
Through this middleware, any [Authorize] request requires a valid jwt:
The signature is valid
Expiration time
Effective time
Issuer declaration equals "ExampleIssuer"
Subscriber claims to be equal to "ExampleAudience"
If it is not a legitimate JWT, request termination, issuer declaration and subscriber declaration are not required, they are used to identify the application and the client.
Verify JWTs in cookies
Cookies authentication in ASP.NET Core does not support passing jwt. You need to customize the class that implements the ISecureDataFormat interface. Now, you just validate the token, not generate them, just implement the Unprotect method, and leave the rest to the System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler class.
Using System;using System.IdentityModel.Tokens.Jwt;using System.Security.Claims;using Microsoft.AspNetCore.Authentication;using Microsoft.AspNetCore.Http.Authentication;using Microsoft.IdentityModel.Tokens; namespace SimpleTokenProvider {public class CustomJwtDataFormat: ISecureDataFormat {private readonly string algorithm; private readonly TokenValidationParameters validationParameters; public CustomJwtDataFormat (string algorithm, TokenValidationParameters validationParameters) {this.algorithm = algorithm; this.validationParameters = validationParameters;} public AuthenticationTicket Unprotect (string protectedText) = > Unprotect (protectedText, null) Public AuthenticationTicket Unprotect (string protectedText, string purpose) {var handler = new JwtSecurityTokenHandler (); ClaimsPrincipal principal = null; SecurityToken validToken = null; try {principal = handler.ValidateToken (protectedText, this.validationParameters, out validToken); var validJwt = validToken as JwtSecurityToken; if (validJwt = = null) {throw new ArgumentException ("Invalid JWT") } if (! validJwt.Header.Alg.Equals (algorithm, StringComparison.Ordinal)) {throw new ArgumentException ($"Algorithm must be'{algorithm}');} / / Additional custom validation of JWT claims here (if any)} catch (SecurityTokenValidationException) {return null;} catch (ArgumentException) {return null } / / Validation passed. Return a valid AuthenticationTicket: return new AuthenticationTicket (principal, new AuthenticationProperties (), "Cookie");} / This ISecureDataFormat implementation is decode-only public string Protect (AuthenticationTicket data) {throw new NotImplementedException ();} public string Protect (AuthenticationTicket data, string purpose) {throw new NotImplementedException ();}
Call in startup.cs
Var tokenValidationParameters = new TokenValidationParameters {/ / The signing key must match! ValidateIssuerSigningKey = true, IssuerSigningKey = signingKey, / / Validate the JWT Issuer (iss) claim ValidateIssuer = true, ValidIssuer = "ExampleIssuer", / / Validate the JWT Audience (aud) claim ValidateAudience = true, ValidAudience = "ExampleAudience", / / Validate the token expiry ValidateLifetime = true, / / If you want to allow a certain amount of clock drift, set that here: ClockSkew = TimeSpan.Zero} App.UseCookieAuthentication (new CookieAuthenticationOptions {AutomaticAuthenticate = true, AutomaticChallenge = true, AuthenticationScheme = "Cookie", CookieName = "access_token", TicketDataFormat = new CustomJwtDataFormat (SecurityAlgorithms.HmacSha256, tokenValidationParameters)})
If the request contains a cookie named access_token that is validated as valid JWT, the request will return the correct result. If necessary, you can add additional jwt chaims, or copy jwt chaims to ClaimsPrincipal. In the CustomJwtDataFormat.Unprotect method, the above is the verification token, and the following token will be generated in the asp.net core.
ASP.NET Core generates Tokens
In asp.net 4.5, this UseOAuthAuthorizationServer middleware can easily generate tokens, but it is cancelled in asp.net core, so write a simple token generation middleware below, and finally, there are several links to off-the-shelf solutions for you to choose from.
Simple token generation node
First, generate the option for POCO to save the middleware. Generate class: TokenProviderOptions.cs
Using System;using Microsoft.IdentityModel.Tokens; namespace SimpleTokenProvider {public class TokenProviderOptions {public string Path {get; set;} = "/ token"; public string Issuer {get; set;} public string Audience {get; set;} public TimeSpan Expiration {get; set;} = TimeSpan.FromMinutes (5); public SigningCredentials SigningCredentials {get; set;}
Now add your own middleware. The middleware class of asp.net core generally looks like this:
Using System.IdentityModel.Tokens.Jwt;using System.Security.Claims;using System.Threading.Tasks;using Microsoft.AspNetCore.Http;using Microsoft.Extensions.Options;using Newtonsoft.Json;namespace SimpleTokenProvider {public class TokenProviderMiddleware {private readonly RequestDelegate _ next; private readonly TokenProviderOptions _ options; public TokenProviderMiddleware (RequestDelegate next, IOptions options) {_ next = next; _ options = options.Value } public Task Invoke (HttpContext context) {/ / If the request path doesn't match, skip if (! context.Request.Path.Equals (_ options.Path, StringComparison.Ordinal)) {return _ next (context) } / / Request must be POST with Content-Type: application/x-www-form-urlencoded if (! context.Request.Method.Equals ("POST") | |! context.Request.HasFormContentType) {context.Response.StatusCode = 400; return context.Response.WriteAsync ("Bad request.");} return GenerateToken (context);}
This middleware class takes TokenProviderOptions as a parameter. When there is a request and the request path is the set path (token or api/token), the Invoke method executes, and the token node only requests POST and includes the form-urlencoded content type (Content-Type: application/x-www-form-urlencoded), so you need to check the content type before calling.
The most important thing is GenerateToken, which needs to verify the user's identity, generate jwt, and return jwt:
Private async Task GenerateToken (HttpContext context) {var username = context.Request.Form ["username"]; var password = context.Request.Form ["password"]; var identity = await GetIdentity (username, password); if (identity = = null) {context.Response.StatusCode = 400; await context.Response.WriteAsync ("Invalid username or password."); return;} var now = DateTime.UtcNow; / / Specifically add the jti (random nonce), iat (issued timestamp), and sub (subject/user) claims. / / You can add other claims here, if you want: var claims = new Claim [] {new Claim (JwtRegisteredClaimNames.Sub, username), new Claim (JwtRegisteredClaimNames.Jti, Guid.NewGuid (). ToString ()), new Claim (JwtRegisteredClaimNames.Iat, ToUnixEpochDate (now). ToString (), ClaimValueTypes.Integer64)} / / Create the JWT and write it to a string var jwt = new JwtSecurityToken (issuer: _ options.Issuer, audience: _ options.Audience, claims: claims, notBefore: now, expires: now.Add (_ options.Expiration), signingCredentials: _ options.SigningCredentials); var encodedJwt = new JwtSecurityTokenHandler (). WriteToken (jwt); var response = new {access_token = encodedJwt, expires_in = (int) _ options.Expiration.TotalSeconds} / / Serialize and return the response context.Response.ContentType = "application/json"; await context.Response.WriteAsync (JsonConvert.SerializeObject (response, new JsonSerializerSettings {Formatting = Formatting.Indented});}
Most of the code is official, the JwtSecurityToken class generates jwt,JwtSecurityTokenHandler to encode the jwt, and you can add any chaims to the claims. Verifying the user's identity is just a simple verification. This is certainly not the case. You can integrate identity framework or other things. For this example, it's just simple hard coding:
Private Task GetIdentity (string username, string password) {/ / DON'T do this in production, obviously! If (username = = "TEST" & & password = = "TEST123") {return Task.FromResult (new ClaimsIdentity (new System.Security.Principal.GenericIdentity (username, "Token"), new Claim [] {});} / / Credentials are invalid, or account doesn't exist return Task.FromResult (null);}
Add a method to generate timestamp from DateTime:
Public static long ToUnixEpochDate (DateTime date) = > (long) Math.Round ((date.ToUniversalTime ()-new DateTimeOffset (1970, 1, 1, 0, 0, 0, TimeSpan.Zero)) .TotalSeconds)
Now you can add this middleware to startup.cs:
Using System.Text;using Microsoft.AspNetCore.Builder;using Microsoft.AspNetCore.Hosting;using Microsoft.Extensions.Configuration;using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Logging;using Microsoft.Extensions.Options;using Microsoft.IdentityModel.Tokens; namespace SimpleTokenProvider {public partial class Startup {public Startup (IHostingEnvironment env) {var builder = new ConfigurationBuilder () .AddJsonFile ("appsettings.json", optional: true); Configuration = builder.Build ();} public IConfigurationRoot Configuration {get; set } public void ConfigureServices (IServiceCollection services) {services.AddMvc ();} / / The secret key every token will be signed with. / / In production, you should store this securely in environment variables / / or a key management tool. Don't hardcode this into your application! Private static readonly string secretKey = "mysupersecretsecretsecretkeyholders 123"; public void Configure (IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {loggerFactory.AddConsole (LogLevel.Debug); loggerFactory.AddDebug (); app.UseStaticFiles (); / / Add JWT generation endpoint: var signingKey = new SymmetricSecurityKey (Encoding.ASCII.GetBytes (secretKey)) Var options = new TokenProviderOptions {Audience = "ExampleAudience", Issuer = "ExampleIssuer", SigningCredentials = new SigningCredentials (signingKey, SecurityAlgorithms.HmacSha256),}; app.UseMiddleware (Options.Create (options)); app.UseMvc ();}
To test it, it is recommended to use chrome's postman:
POST / tokenContent-Type: application/x-www-form-urlencodedusername=TEST&password=TEST123
Results:
OK
Content-Type: application/json
{
"access_token": "eyJhb..."
"expires_in": 300
}
You can use the jwt tool to view the generated jwt content. If you are developing a mobile application or a single-page application, you can store jwt in the header of subsequent requests. If you need to store it in cookies, you need to modify the code and add the returned jwt string to the cookie.
Test:
Is it helpful for you to read the above content? If you want to know more about the relevant knowledge or read more related articles, please follow the industry information channel, thank you for your support.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.