Use JWT to protect our asp.net Core Web api__.net

Source: Internet
Author: User
Tags assert auth

In the previous blog, I wrote a middleware to handle the authorization validation of the API, and now I have another way to deal with the issue of authorization verification, which is now

There are a lot of open source things can be used, today with the JWT.

What is JWT? The full name of JWT is the JSON WEB tokens, a self-contained token format. Official website: https://jwt.io/, more or less should have heard this.

Let's take a look at the following two graphs:

The site is RPC to access the way the API to obtain resources, when the site is a direct access to the API, did not get access to the token, then the site is not to get the relevant data resources.

As shown on the left, the request was made but not the desired result, and when the site first went to the authorized server and got the Access_token (token) To access the API, it passed the

Access_token access to API,API will not return the protected data resource.

This is the approximate process based on token verification. It can be seen that the authorization server occupies a very important position.

Let's take a look at what the licensing server does and how to implement a simple authorization.

Done what. The role of the authorization server throughout the process is to receive a client request for Access_token and verify the legality of its identity, eventually returning a containing

Access_token the JSON string.

How to achieve it. We still can not leave the middleware this thing. This time we wrote a tokenprovidermiddleware, mainly to look at the Invoke method and generate Access_token

The method.

1         ///<summary>
 2         ///invoke the middleware
 3         ///</summary>
 4         ///<param Name= ' context ' ></param>
 5         ///<returns></returns>
 6 public         Async Task Invoke (HttpContext context)
 7         {           
 8             if (!context). Request.Path.Equals (_options. Path, StringComparison.Ordinal))
 9             {                 await _next (context);
One             //Request must is POST with content-type:application/x-www-form-urlencoded
14             if (!context. Request.Method.Equals ("POST")                | |!context. Request.hasformcontenttype)             {                 await returnbadrequest (context);             await generateauthorizedresult (context);         }

The Invoke method is actually needless to say, but here we have a control that receives only the POST request and is only receiving the data submitted in form, GET request and its

His contenttype type is an illegal request and will return the status of bad requests.

Here are some of the more important things about authorization, the generation of Access_token.

 1///<summary> 2///get the JWT 3///</summary> 4///<param name= "u Sername "></param> 5///<returns></returns> 6 private string GETJWT (string username
 ) 7 {8 var now = Datetime.utcnow; 9 var claims = new claim[] One {new Claim (jwtregisteredclaimnames.sub, user Name), new Claim (JWTREGISTEREDCLAIMNAMES.JTI, Guid.NewGuid (). ToString ()), New Claim (Jwtregisteredclaimnames.iat, now. ToUniversalTime ().
ToString (), claimvaluetypes.integer64) 16}; 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 EX pires_in = (int) _options.   
Expiration.totalseconds, Token_type = "bearer" 32}; Jsonconvert.serializeobject (response, new jsonserializersettings {formatting = formatting.indented
}); 34}

Claims contains a number of claim that you want to add to your needs, jwtregisteredclaimnames is a structure that contains all the optional options.

 1 public struct Jwtregisteredclaimnames 2 {3 Public const string ACR = "ACR";
 4 Public Const string actort = "Actort";
 5 Public Const string AMR = "AMR";
 6 Public Const string Athash = "At_hash";
 7 Public Const String AUD = "AUD";
 8 Public Const String authtime = "Auth_time";
9 Public Const String AZP = "AZP";
Ten Public const string birthdate = "Birthdate";
One public const string chash = "C_hash";
Public Const string email = "Email";
The public const string EXP = "Exp";
Public Const string familyname = "Family_name";
Public Const string Gender = "Gender";
Public Const string givenname = "Given_name";
The public const string IAT = "IAT";
Public Const string ISS = "ISS";
Public Const string Jti = "Jti";
Public Const string NameId = "NameId";
Public Const string NBF = "NBF"; Public Const STring Nonce = "Nonce";
Public Const string PRN = "Prn";
Public const string SID = "Sid";
The public const string SUB = "Sub";
Num Public const string TYP = "Typ";
The public const string uniquename = "Unique_name";
Public Const string Website = "Website"; 29}
Jwtregisteredclaimnames

Also need a Jwtsecuritytoken object, this object is critical. With the time, claims, and Jwtsecuritytoken objects, just call Jwtsecuritytokenhandler

Writetoken can get an encrypted string similar to this one, which consists of 3 parts with '. ' Separated . Each part represents what can go to the official website to look up.

EyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBa B30rmhrhdcefxjoyzgefonfh7hgq

Finally, we'll return this access_token, Access_token, and some other information in JSON form.

We also need to call our middleware in the Configure method of startup.

1             var audienceconfig = configuration.getsection ("Audience");
 2             var symmetricKeyAsBase64 = audienceconfig["Secret"];
 3             var keybytearray = Encoding.ASCII.GetBytes (symmetricKeyAsBase64);
 4             var signingkey = new Symmetricsecuritykey (keybytearray);
 5 
 6             app. Usetokenprovider (New tokenprovideroptions
 7             {
 8                 audience = "Catcher Wong",
 9                 issuer = "http://catcher1994.cnblogs.com/",                 signingcredentials = new Signingcredentials (Signingkey, securityalgorithms.hmacsha256),
one             });

Here, our authorized Service site is already done. Here's a few unit tests to verify this authorization.

Test one: The Authorized Service site can generate the correct JWT.

1         [Fact]
 2 public         async Task authorized_server_should_generate_token_success ()
 3         {
 4             Arrange
 5             var data = new dictionary<string, string> ();
 6             data. ADD ("username", "member");
 7             data. ADD ("password", "123");
 8             httpcontent ct = new formurlencodedcontent (data);
 9             //act one             System.Net.Http.HttpResponseMessage Message_token = await _client. Postasync ("Http://127.0.0.1:8000/auth/token", CT);
A             string res = await Message_token. Content.readasstringasync ();             var obj = newtonsoft.json.jsonconvert.deserializeobject<token> (res);             //assert             assert.notnull (obj);             assert.equal ("obj.expires_in",);             assert.equal (3, Obj.access_token. Split ('. '). Length);             assert.equal ("bearer", obj.token_type);         }

Test Two: The Authorized Service site cannot generate the correct JWT because the user name or password is incorrect.

1         [Fact]
 2 public         async Task Authorized_server_should_generate_token_fault_by_invalid_app ()
 3         {
 4             //arrange
 5             var data = new dictionary<string, string> ();
 6             data. ADD ("username", "member");
 7             data. ADD ("Password", "123456");
 8             httpcontent ct = new formurlencodedcontent (data);
 9             //act one             System.Net.Http.HttpResponseMessage Message_token = await _client. Postasync ("Http://127.0.0.1:8000/auth/token", CT);             var res = await Message_token. Content.readasstringasync ();             Dynamic obj = Newtonsoft.Json.JsonConvert.DeserializeObject (res);             //assert             assert.equal ("Invalid_grant", (string) obj.error);             assert.equal (Httpstatuscode.badrequest, Message_token. StatusCode);
/         }

Test Three: The Authorized Service site cannot generate the correct JWT because it is not a POST request.

1         [Fact]
 2 public         async Task Authorized_server_should_generate_token_fault_by_invalid_httpmethod ()
 3         {
 4             //arrange
 5             uri uri = new Uri ("http://127.0.0.1:8000/auth/token?username=Member&password= 123456 ");
 6 
 7             //act
 8             System.Net.Http.HttpResponseMessage Message_token = await _client. Getasync (URI);
 9             var res = await Message_token. Content.readasstringasync ();             Dynamic obj = Newtonsoft.Json.JsonConvert.DeserializeObject (res);             //assert             assert.equal ("Invalid_grant", (string) obj.error);             assert.equal (Httpstatuscode.badrequest, Message_token. StatusCode);         }

Take another look at the results of the test: all passed.

Breakpoint take a access_token to http://jwt.calebb.net/decipher look

Eyjhbgcioijiuzi1niisinr5cci6ikpxvcj9.eyjzdwiioijnzw1izxiilcjqdgkioii2mzi1mme1my0ymjy5ltq4yzetymqwni1lowrimzdmmtrmytqilcjp Yxqioiiymde2lzexlzeyidi6ndg6mtcilcjuymyioje0nzg5mtg4otcsimv4cci6mtq3odkxotq5nywiaxnzijoiahr0cdovl2nhdgnozxixotk0lmnuymxvz 3muy29tlyisimf1zci6iknhdgnozxigv29uzyj9.cu2vtj4jahgbjgzwv2jcmvz17hcyosrntjktiea0ebq

The following is the development of the API.

Here is a demo of the Valuecontroller generated directly with the new API project, after all, with the ASP.net Web API is

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.