Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Complex JSON Web Token Array in webapi with OWIN

I'm in process of trying to learn JWT and ouath. I have came across form of JWT which would help me in development of my authorization server.

The format I came across is following :

{
  iat: 1416929061, 
  jti: "802057ff9b5b4eb7fbb8856b6eb2cc5b",
  scopes: {
    users: {
      actions: ['read', 'create']
    },
    users_app_metadata: {
      actions: ['read', 'create']
    }
  }
}

However since in adding claims we can only add simple string how something like this can be achieved ?

The only way I have seen till now was to use JSON.serialization - coming from https://stackoverflow.com/a/27279400/2476347

new Claim(someClass,JsonConvert.SerializeObject(result)

any guidelines would be much appreciated! Thanks!

Code used for testing

Class I would like to use in JWT

public class MyTes
{
    public string       area { get; set; }
    public List<string> areapermissions { get; set; }
}

And then I use the following code for token generation

        var identity = new ClaimsIdentity("JWT");

        var cos = new List<string>();

        cos.Add("aaa");
        cos.Add("bbb");

        MyTes vario = new MyTes()
        {
            area = "someregion",
            areapermissions = cos
        };




        identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
        identity.AddClaim(new Claim("sub", context.UserName));
        identity.AddClaim(new Claim(ClaimTypes.Role, "Manager"));
        identity.AddClaim(new Claim(ClaimTypes.Role, "Supervisor"));
        identity.AddClaim(new Claim("scope", "xyz1"));
        identity.AddClaim(new Claim("scope", "xyz2"));
        identity.AddClaim(new Claim("scope", "xyz3"));
        identity.AddClaim(new Claim("APIs", JsonConvert.SerializeObject(cos)));
        identity.AddClaim(new Claim("APIs2", JsonConvert.SerializeObject(vario)));

This gives no errors and when I decode the ticket I get now :

{
  "unique_name": "Rafski",
  "sub": "Rafski",
  "role": [
    "Manager",
    "Supervisor"
  ],
  "scope": [
    "xyz1",
    "xyz2",
    "xyz3"
  ],
  "APIs": "[\"aaa\",\"bbb\"]",
  "APIs2": "{\"area\":\"someregion\",\"areapermissions\":[\"aaa\",\"bbb\"]}",
  "iss": "http://kurwa.mac",
  "aud": "7aaa70ed8f0b4807a01596e2abfbd44d",
  "exp": 1429351056,
  "nbf": 1429349256
}
like image 591
erPe Avatar asked Apr 18 '15 09:04

erPe


2 Answers

Here's how to create a JWT token with complex JSON claims using .Net.

Use Nuget to get the Library: System.IdentityModel.Tokens.Jwt

Then use the following code to create a JWT token.

var keybytes = Convert.FromBase64String(YOUR_CLIENT_SECRET);
        var signingCredentials = new SigningCredentials(
                    new InMemorySymmetricSecurityKey(keybytes),
                    SecurityAlgorithms.HmacSha256Signature,
                    SecurityAlgorithms.Sha256Digest);

        var nbf = DateTime.UtcNow.AddSeconds(-1);
        var exp = DateTime.UtcNow.AddSeconds(120);
        var payload = new JwtPayload(null, "", new List<Claim>(), nbf, exp);

        var users = new Dictionary<string, object>();
        users.Add("actions", new List<string>() { "read", "create" });
        var scopes = new Dictionary<string, object>();
        scopes.Add("users", users);
        payload.Add("scopes", scopes);

        var jwtToken = new JwtSecurityToken(new JwtHeader(signingCredentials), payload);
        var jwtTokenHandler = new JwtSecurityTokenHandler();
        return jwtTokenHandler.WriteToken(jwtToken);

Which would produce a token such as

{
  "typ": "JWT",
  "alg": "HS256"
}    
{
      "exp": 1433254394,
      "nbf": 1433254273,
      "scopes": {
        "users": {
          "actions": [
            "read", "create"
          ]
        }
      }
    }
like image 100
Stephane Avatar answered Sep 23 '22 13:09

Stephane


This has been never an issue these days. It can be solved using the Payload section of the token.

**using System.IdentityModel.Tokens.Jwt;** //Vesrion 5.5.0

Sample code

        public static string Generate()
    {

        IList<User> users = new List<User> {
            new User { Id = 1, Name = "User One" },
            new User { Id = 2, Name = "User Two" },
            new User { Id = 3, Name = "User Three" }
        };

        IList<Company> companies = new List<Company>
        {
            new Company{ Id = 1, Code = "C01", Name = "Company I", Users = users },
            new Company{ Id = 2, Code = "C03", Name = "Company II", Users = null },
            new Company{ Id = 3, Code = "C03", Name = "Company III", Users = users }
        };

        IList<Branch> branches = new List<Branch>
        {
            new Branch{Id = 1, CompanyId = 1, Code="B01", Name = "Branch 1.1"},
            new Branch{Id = 2, CompanyId = 1, Code="B02", Name = "Branch 1.2"},
            new Branch{Id = 3, CompanyId = 1, Code="B03", Name = "Branch 1.3"},
            new Branch{Id = 4, CompanyId = 2, Code="B04", Name = "Branch 2.1"},
            new Branch{Id = 5, CompanyId = 2, Code="B05", Name = "Branch 2.2"},
        };

        var payload = new JwtPayload       {
            { "companies", companies },
            { "branches", branches }
        };

        string key = "eyJjb21wYW5pZXMiOlt7IklkIjoxLCJDb2RlIjoiQzAxIiwiTmFtZSI6IkNvbXBhbnkgSSIsIkJyYW5jaGVzIjpudWxsLCJVc2VycyI6W3siSWQiOjEsIk5hbWUiOiJV";
        var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
        var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
        var header = new JwtHeader(credentials);

        var secToken = new JwtSecurityToken(header, payload);

        var handler = new JwtSecurityTokenHandler();
        var tokenString = handler.WriteToken(secToken);

        Console.WriteLine(secToken);
        Console.WriteLine(tokenString);

        return tokenString;
    }

Output

{
  "companies": [
    {
      "Id": 1,
      "Code": "C01",
      "Name": "Company I",
      "Branches": null,
      "Users": [
        {
          "Id": 1,
          "Name": "User One"
        },
        {
          "Id": 2,
          "Name": "User Two"
        },
        {
          "Id": 3,
          "Name": "User Three"
        }
      ]
    },
    {
      "Id": 2,
      "Code": "C03",
      "Name": "Company II",
      "Branches": null,
      "Users": null
    },
    {
      "Id": 3,
      "Code": "C03",
      "Name": "Company III",
      "Branches": null,
      "Users": [
        {
          "Id": 1,
          "Name": "User One"
        },
        {
          "Id": 2,
          "Name": "User Two"
        },
        {
          "Id": 3,
          "Name": "User Three"
        }
      ]
    }
  ],
  "branches": [
    {
      "Id": 1,
      "CompanyId": 1,
      "Code": "B01",
      "Name": "Branch 1.1"
    },
    {
      "Id": 2,
      "CompanyId": 1,
      "Code": "B02",
      "Name": "Branch 1.2"
    },
    {
      "Id": 3,
      "CompanyId": 1,
      "Code": "B03",
      "Name": "Branch 1.3"
    },
    {
      "Id": 4,
      "CompanyId": 2,
      "Code": "B04",
      "Name": "Branch 2.1"
    },
    {
      "Id": 5,
      "CompanyId": 2,
      "Code": "B05",
      "Name": "Branch 2.2"
    }
  ]
}

Token

eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJjb21wYW5pZXMiOlt7IklkIjoxLCJDb2RlIjoiQzAxIiwiTmFtZSI6IkNvbXBhbnkgSSIsIkJyYW5jaGVzIjpudWxsLCJVc2VycyI6W3siSWQiOjEsIk5hbWUiOiJVc2VyIE9uZSJ9LHsiSWQiOjIsIk5hbWUiOiJVc2VyIFR3byJ9LHsiSWQiOjMsIk5hbWUiOiJVc2VyIFRocmVlIn1dfSx7IklkIjoyLCJDb2RlIjoiQzAzIiwiTmFtZSI6IkNvbXBhbnkgSUkiLCJCcmFuY2hlcyI6bnVsbCwiVXNlcnMiOm51bGx9LHsiSWQiOjMsIkNvZGUiOiJDMDMiLCJOYW1lIjoiQ29tcGFueSBJSUkiLCJCcmFuY2hlcyI6bnVsbCwiVXNlcnMiOlt7IklkIjoxLCJOYW1lIjoiVXNlciBPbmUifSx7IklkIjoyLCJOYW1lIjoiVXNlciBUd28ifSx7IklkIjozLCJOYW1lIjoiVXNlciBUaHJlZSJ9XX1dLCJicmFuY2hlcyI6W3siSWQiOjEsIkNvbXBhbnlJZCI6MSwiQ29kZSI6IkIwMSIsIk5hbWUiOiJCcmFuY2ggMS4xIn0seyJJZCI6MiwiQ29tcGFueUlkIjoxLCJDb2RlIjoiQjAyIiwiTmFtZSI6IkJyYW5jaCAxLjIifSx7IklkIjozLCJDb21wYW55SWQiOjEsIkNvZGUiOiJCMDMiLCJOYW1lIjoiQnJhbmNoIDEuMyJ9LHsiSWQiOjQsIkNvbXBhbnlJZCI6MiwiQ29kZSI6IkIwNCIsIk5hbWUiOiJCcmFuY2ggMi4xIn0seyJJZCI6NSwiQ29tcGFueUlkIjoyLCJDb2RlIjoiQjA1IiwiTmFtZSI6IkJyYW5jaCAyLjIifV19.ysjwBa3YeYNmVB0fVEh95wL0zt8Krb-T4VRpWKWIfbU
like image 25
Lovjith Avatar answered Sep 23 '22 13:09

Lovjith