我已经在ASP.Net MVC中发布了一些关于使用JWT的帖子,它指导了如何发布和使用签名的JSON Web令牌。
任何人都可以根据JSON Web加密(JWE)规范指导如何发布和使用加密的JWT,以防我们需要在JWT有效负载中传输一些敏感数据。
答案 0 :(得分:2)
了解JWT
JSON Web令牌(JWT)是一种紧凑的URL安全方式,用于表示要在双方之间转移的声明。 JWT中的声明被编码为JavaScript对象表示法(JSON)对象,该对象用作JSON Web签名(JWS)结构的有效负载或JSON Web加密(JWE)结构的明文,使声明成为可能数字签名或MAC和/或加密。
JWT是什么?
https://jwt.io/introduction/
Json Web令牌标准
https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25
JWT剖析
https://scotch.io/tutorials/the-anatomy-of-a-json-web-token
在JavaScript中创建JSON Web令牌
https://www.jonathan-petitcolas.com/2014/11/27/creating-json-web-token-in-javascript.html
现在,我们了解JWT呼叫以及我们如何从服务器端提供服务。 这里我有HTML页面,我有按钮,还设置了一些自定义参数。
<script src="//cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha256.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"></script>
<script language="JavaScript" type="text/javascript" src="https://kjur.github.io/jsrsasign/jsrsasign-latest-all-min.js"></script>
<script type="text/javascript">
$(function () {
$("#btnJWTApi").click(function () {
// Defining our token parts
// You can use one of these, as alg
// HS256, HS386, HS512
// Always keep type as JWT
var header = {
"alg": "HS256",
"typ": "JWT"
};
var tNow = KJUR.jws.IntDate.getNow();
var tEnd = KJUR.jws.IntDate.getNow() + 60 * 5;
// dynamically pass these data using a function
var data = {
"appId": "yourAppId",
"iat": tNow,
// iat (issued at time) should be set to time when request has been generated
"exp": tEnd,
// exp (expiration) should not be more than 5 minutes from now, this is to prevent Replay Attacks
"method": "TestMethod",
"Q": "test",
"SecretKey": "MySecretKey"
};
// Secret key is used for calculating and verifying the signature.
// The secret signing key MUST only be accessible by the issuer and the User,
// it should not be accessible outside of these two parties.
// Use the Secret you set during user registration from the Plugin
var secret = btoa('MySecret ');
function base64url(source) {
// Encode in classical base64
encodedSource = CryptoJS.enc.Base64.stringify(source);
// Remove padding equal characters
encodedSource = encodedSource.replace(/=+$/, '');
// Replace characters according to base64url specifications
encodedSource = encodedSource.replace(/\+/g, '-');
encodedSource = encodedSource.replace(/\//g, '_');
return encodedSource;
}
var stringifiedHeader = CryptoJS.enc.Utf8.parse(JSON.stringify(header));
var encodedHeader = base64url(stringifiedHeader);
var stringifiedData = CryptoJS.enc.Utf8.parse(JSON.stringify(data));
var encodedData = base64url(stringifiedData);
var signature = encodedHeader + "." + encodedData;
signature = CryptoJS.HmacSHA256(signature, secret);
signature = base64url(signature);
var targetEle = $("#data");
$.ajax(
{
type: "POST",
url: "http://localhost:12345/api/v1/MyController/SecureMethod",
data: '{"token":"' + encodedHeader + "." + encodedData + "." + signature + '"}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
targetEle.html("<pre>" + JSON.stringify(data, null, '\t') + "</pre>");
},
error: function () {
alert('error');
}
});
});
});
</script>
此调用将生成加密令牌,其中包括appId,secret和带有方法名称的有效负载数据。
(这里创建一个常用方法,首先调用然后根据令牌中的传递数据进一步调用方法)
这会调用您的方法SecureMethod
,而不是直接TestMethod
。
并解密令牌。
public string SecureMethod(dynamic tokenObject)
{
//save at a time of user registration.
string applicationID = appSecret get from database;
string secretKey = appSecret get from database;
}
var bytes = Encoding.UTF8.GetBytes(secretKey);
var secret = Convert.ToBase64String(bytes);
var jwtDecryption = JsonWebToken.DecodeToObject(token, secret, true, true);
var jsonObj = JObject.FromObject(jwtDecryption);
string appId = jsonObj["appId"].Value<string>();
if (appId.Equals(applicationID)
{
object restService = new MyController();
var method = restService.GetType().GetMethod(jsonObj["method"].ToString(), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
}
if (method != null)
{
var parameters = method.GetParameters().Select(p => Convert.ChangeType(jsonObj[p.Name].ToString(), p.ParameterType)).ToArray();
object response = method.Invoke(restService, parameters); //your actual method should
return new JavaScriptSerializer().Serialize(response);
}
method.Invoke(restService, parameters);
将包含方法名称和参数,因此它会调用您的方法并传递参数。
public IHttpActionResult TestMethod([FromBody]Response model)
{
// you will get parameters in a model
return Ok();
}
欢迎任何建议!