ASP.net Core 2.2 Jwt in use and verification of applications in the micro-channel applet

Jwt brief

What is Jwt

Json web token (JWT), is a statement in order to pass between the network application execution environment based on open standards JSON ((RFC 7519). The token is designed to be compact and safe, especially for single-distributed sites sign-on (SSO) scenario .JWT statements are typically used to provide and service providers transfer between the user identity is authenticated identity information in order to obtain resources from the server, you can also add some extra other business logic that must be statement information, the token can be directly used for authentication may be encrypted.

Above Jane book from below the big brother, it is strongly recommended you peers to have read it.

Author: Dearmadman

Link: HTTPS: //www.jianshu.com/p/576dbf44b2ae
Jwt composed of three pieces of information, namely: a head (Header), payload (Payload), visa information (signature). Three or more portions of the head with the encryption algorithm and is declared '' is connected became Jwt string.

The head is stored in the information statement, statements and declarations which are Jwt encryption algorithm.

Save our server load information to the user, usually assigned a valid Guid specific information identifying the user and the Token's.

Saved visa information is related to the encryption algorithm information, which can be called directly generate ready-made method in ASP.Net Core in.

Jwt it safe

First of all, from the point of view server, Jwt server itself is made out of, for identifying a particular user's login token, no matter who that is, as long as the interception to the login token can request forgery.

From the client's perspective, this is just a string token login, when a request to bring a non-public interface to get away in the Header Http request, do not take the token analyzing data acquired load information inside. Unless the client is also in the Visa Information Jwt, you can also generate a valid token own, but too dangerous to hold a visa information in the client.

So, we can intercept logon token to do this? If http request, then, is able to easily crawl, but if the request is https if not simple, because range https encryption is to include a request Header and Body, as long as you do not pass the token can be in the form of url to be encrypted. So Jwt or should be used in conjunction with https, but these are not anti-anti-villain gentleman, anything on the network transmission can not be absolutely safe.

In ASP.NET Core in Jwt

Authorization and authentication

Before the code, there are some concepts must be understood clearly. The concept of authorization (Authorization) and authentication (Authentication) must be understood. These two things are Auth beginning, the end tion, not looking really hard to distinguish.

First, before access to non-public interfaces must first be certified and then to verify authorization. For example, certification is like a log in the game, but the game can not use the VIP privilege to go through the authorization verification. Authentication (Authentication) just to show that you are a legitimate user, but not every user has permission to perform this action, which requires authorization (Authorization).

For non-public interface, there must be certification, but does not have to authorize (no VIP players can not even brush picture does not make it?).

Three-step code examples

ASP.Net Core 2.2 is used Jwt certification in three steps.
If no custom authorization and authentication can ignore the second step.

Generate Jwt

First, we need to edit a login interface after a user logs in successfully Jwt give him a token, after access to all non-public interfaces identify the user by the token. Token contains a Guid, Guid record associated with it and the user login information is successful, the subsequent operations according to the user information acquired Guid.

[HttpPost("login")]
public IActionResult Login([FromBody]Client user)
{
    IActionResult ret = null;    // 用户登录验证
    if(CheckUser(user))
    {
        // 验证通过,生成唯一识别码放到Token的Payload(载荷)里面
        string guid = Guid.NewGuid().ToString();
	
	List<Claim> payloadList = new List<Claim>();
	payloadList.Add(new Claim("Guid", guid));
	// payloadList.Add(new Claim("Other", data));   // 根据需要继续添加

	Claim[] payload = payloadList.ToArray();

	string securityKey = _configuration["SecurityKey"];
	// sign the token using a secret key.This secret will be shared between your API and anything that needs to check that the token is legit.
	// 读取配置文件中的秘钥
	var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(securityKey));
	// 设置加密算法(签证信息)
	var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

	// 把设置填到token里(这里我省略了发布者和使用者的验证)
	JwtSecurityToken token = new JwtSecurityToken(
		claims: payload,                            // payload
		signingCredentials: creds,                  // 签证信息
		expires: DateTime.Now.AddMinutes(60));       // 过期时间

	string tokenStr = new JwtSecurityTokenHandler().WriteToken(token);
	
	// 把该用户和该Token中的guid关联起来,其他接口根据Token中的guid获取用户信息
	SetUserGuid(user, guid);
	
	// 回送Token和有效时长
	ret = Ok(new { Token = tokenStr, Expire = 60 });     //做回送
    }
    else
    {
    	ret = BadRequest();
    }
    return ret;
}

Edit authorization policies

It should create two classes, one class authorization verification strategy, a strategy is needed to verify the conditions of the authorization class.
There do not understand is recommended to view Microsoft's official documentation.
https://docs.microsoft.com/zh-cn/aspnet/core/security/authorization/iauthorizationpolicyprovider?view=aspnetcore-2.2

Explain, here is the Client class to write their own user class, user name and password or something.
After authentication failure unified redirected to the specified method, which directly call Forbid () returns a 403 error code.

/// <summary>
/// 授权验证策略条件(可以理解为验证该授权需要的东西)
/// </summary>
public class PermissionRequirement : IAuthorizationRequirement
{
	public bool CheckPermission(Client user)
	{
		bool ret = true;
		// 检查用户权限
		// Coding...
		return ret;
	}
}

/// <summary>
/// 授权验证策略
/// </summary>
public class TokenPolicy : AuthorizationHandler<PermissionRequirement>
{
	protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
	{
		var httpContext = (context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext).HttpContext;
		string guid = "";
		if (httpContext.User.Identity.IsAuthenticated)
		{
			var auth = httpContext.AuthenticateAsync().Result.Principal.Claims;
			var guidClaim = auth.FirstOrDefault(s => s.Type == "Guid");
			
			if (guidClaim != null)
			{
				guid = guidClaim.Value;
				// 根据Guid获取用户信息(该方法是自己编写的)
				if (GetUserByGuid(guid, out Client user))
				{
					// 验证成功且拥有权限
					if(requirement.CheckPermission(user))
					{
						context.Succeed(requirement);
					}
					else
					{
						// 验证成功但权限不足
						httpContext.Response.Redirect($"api/identify/forbidden");
					}
				}
				else
				{
					// 验证成功,但Guid非法
					httpContext.Response.Redirect($"api/identify/forbidden");
				}
			}
			else
			{
				// 验证成功,但没有包含Guid
				httpContext.Response.Redirect($"api/identify/forbidden");
			}
		}
		else
		{
			// 验证失败,没有包含验证信息
			httpContext.Response.Redirect($"api/identify/forbidden");
		}
		
		return Task.CompletedTask;
	}
}

In the configuration StartUp

Registration Jwt certification and our custom authorization verification method ConfigureServices method StartUp class.
If no custom authorization verification, you can not call AddAuthorization method.

public void ConfigureServices(IServiceCollection services)
{
	// 注册自定义的授权验证方法
	services.AddAuthorization(options =>
	{
		options.AddPolicy("Permission", policy => policy.Requirements.Add(new PermissionRequirement()));
	})
	.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)	// 注册Jwt认证
	.AddJwtBearer(option =>
	{
		// 读取配置文件中的秘钥
		string securityKey = Config["SecurityKey"];
		option.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
		{
			ValidateLifetime = true,
			ValidateIssuer = false,
			ValidateIssuerSigningKey = true,
			ValidateAudience = false,
			IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(securityKey))
		};
	});
	
	// 不需要自定义授权验证的可以不添加这个单例
	services.AddSingleton<IAuthorizationHandler, TokenPolicy>();
	services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Finally, add our approach StartUp class Configure method. Here we must note first UseAuthentication () again UserMvc ()

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
	if (env.IsDevelopment())
	{
		app.UseDeveloperExceptionPage();
	}
	app.UseAuthentication();
	app.UseMvc();
}

Add properties

After the bin we can add more steps on the need to verify the interface or Controller [Authorize ( "{name} licensing strategy")] feature. Controller of this nature or the interface will automatically execute Jwt authentication and authorization policies HandleRequirementAsync custom method before calling.
Jwt obtaining load included (Payload) with User.Claims.First () method in the interface method

[Authorize("Permission")]
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
	//if (User.HasClaim(s => s.Type == "Guid"))
	string guid = User.Claims.First(s => s.Type == "Guid").Value;
	// 根据guid获取用户信息继续操作
	return guid;
}

Add no custom authorization method of [Authorize] characteristics can be, without specifying authorization verification strategy.

Clients use

Test shots.

Login first method, to obtain a valid token and Jwt time after user login authentication.
Here Insert Picture Description
Then we try to do the interface with the access token validation rules
Here Insert Picture Description
returned 401 tips need to be logged.

Then we have just acquired Jwt token, add the Header Authorization request access once again.
Note here that the value of Authorization Bearer To begin with, a space, and then fill just acquired Jwt token, this is Jwt validation rules inside the default.
Here Insert Picture Description
Request was successful.

Applet using micro-channel

If you have something to add to this period in time, then made a string Jwt, util.js inside the applet may require a timed refresh method Jwt of.

// 定时刷新句柄全局变量
var refreshHandle = 0;

function TokenRefresh(min){
	refreshHandle = setInterval(function(){
	  var app = getApp();
	  var user = app.globalData.userInfo;	//保存在全局变量里的用户信息
	  wx.request({
	        url: domain + 'values/login',      
	        method: 'POST',      
	        data: user,      
	        dataType: 'json',      
	        responseType: 'text',      
	        success: function (data) {
	        	var result = data.data;
	        	// 登录成功
	        	if (data.statusCode == 200) {
	        		app.globalData.jwtToken = result.token;
	        	}
	        	else{
	        		// 登录失败
	        	}	        	
	        }
	    })	
	},(min-2) * 60 * 1000);	// 这里提前两分钟刷新
}

// 用户登出时停止自动刷新
function StopRefresh(){
	clearInterval(refreshHandle);
}

User login method

  UserLogin:function(usrName,psd){    
  	var user = {      
  		UserName: usrName,      
  		Password: psd    
  	}
  	wx.request({      
  		url: domain + 'values/login',      
  		method: 'POST',      
  		data: user,      
  		dataType: 'json',      
  		responseType: 'text',      
  		success: function (data) {        
  			var result = data.data;        
  			// 登录成功        
  			if (data.statusCode == 200) {          
	  			// 有效时间          
  				let expire = result.expire;          
  				// 定时刷新Token          
  				Utils.TokenRefresh(expire);          
  				// 记在全局变量里面          
  				getApp().globalData.jwtToken = result.token;        
  			}
  			else {
  			          // 登录失败       
  			}      
  		},
  		fail: function () {
  		        // 连接错误      
  		},
  		complete: function () {}
  	})
 },

Access to non-public interface

  Test:function(){
      let token = getApp().globalData.jwtToken;     
      // 在Header中带上验证信息    
      var head = {      
      	'content-type': 'application/json;charset=utf-8',
      	'Authorization': 'Bearer ' + token    
      }
      wx.request({
            url: domain + '/values/66',      
            method: 'GET',      
            header: head,      
            dataType: 'json',      
            responseType: 'text',      
            success: function (data) {
                    // Coding      
            },
            fail:function(){      },
            complete:function(){      }
      })
    }

Reference material

Asp.net Core use jwt
https://www.jianshu.com/p/294ea94f0087

jwt introduction
https://www.jianshu.com/p/576dbf44b2ae

Published 15 original articles · won praise 2 · Views 4860

Guess you like

Origin blog.csdn.net/weixin_38138153/article/details/99170994