我是OAuth的新手,我使用this教程从客户端应用程序生成访问令牌到目标应用程序。代码本身工作正常,但是当我在invalid signature
上解码时,我生成的访问令牌有https://jwt.io/
这是教程中的代码
public class ServicePrincipal
{
/// <summary>
/// The variables below are standard Azure AD terms from our various samples
/// We set these in the Azure Portal for this app for security and to make it easy to change (you can reuse this code in other apps this way)
/// You can name each of these what you want as long as you keep all of this straight
/// </summary>
static string authority = ""; // the AD Authority used for login. For example: https://login.microsoftonline.com/myadnamehere.onmicrosoft.com
static string clientId = ""; // client app's client id
static string clientSecret = ""; // client app's secret key
static string resource = ""; // target app's App ID URL
/// <summary>
/// wrapper that passes the above variables
/// </summary>
/// <returns></returns>
static public async Task<AuthenticationResult> GetS2SAccessTokenForProdMSAAsync()
{
return await GetS2SAccessToken(authority, resource, clientId, clientSecret);
}
static async Task<AuthenticationResult> GetS2SAccessToken(string authority, string resource, string clientId, string clientSecret)
{
var clientCredential = new ClientCredential(clientId, clientSecret);
AuthenticationContext context = new AuthenticationContext(authority, false);
AuthenticationResult authenticationResult = await context.AcquireTokenAsync(
resource, // the resource (app) we are going to access with the token
clientCredential); // the client credentials
return authenticationResult;
}
}
我发现还有另一段代码也可以生成访问令牌:
AuthenticationContext authenticationContext =
new AuthenticationContext({authority});
ClientCredential clientCredential = new ClientCredential({client app id}, {client app secret});
try
{
AuthenticationResult result =
await authenticationContext.AcquireTokenAsync({target app's App ID URL},
clientCredential);
}
catch (Exception e)
{
return false;
}
这两个代码都给了我1.0版本的无效签名访问令牌
这里有两个问题:
"ver": "1.0"
。这是否意味着它正在使用OAuth1.0?因为我想使用OAuth 2.0 ..为什么代码会生成创建OAuth1.0而不是OAuth2.0的令牌?我尝试了与你的相同的代码,得到相同的情况invalid signature
,但当我将jwt ALGORITHM改为HS256时,我得到了Signature Verified
。
签名:
以及RRS256和HS256的差异:
RS256(带SHA-256的RSA签名)是一种非对称算法,它使用公钥/私钥对:身份提供者有一个用于生成签名的私有(秘密)密钥,JWT的消费者获得一个公钥验证签名。由于与私钥相对的公钥不需要保持安全,因此大多数身份提供商使消费者可以轻松获得和使用(通常通过元数据URL)。
另一方面,HS256(HMAC与SHA-256)是对称算法,只有一个(秘密)密钥在双方之间共享。由于使用相同的密钥来生成签名并对其进行验证,因此必须注意确保密钥不受损害。
您是否将密钥发布到jwt.io的表单中?尝试使用授权标头中的令牌进行真正的休息呼叫。如果一切正常并且jwt没有,也许它就在他们身上。
我注意到当我解码访问令牌时,它显示“ver”:“1.0”。这是否意味着它正在使用OAuth1.0?因为我想使用OAuth 2.0 ..为什么代码会生成创建OAuth1.0而不是OAuth2.0的令牌?
您正在使用OAuth2.0,ver:"1.0"
表示由Azure AD V1.0端点发出JWT令牌。
为什么签名无效?
API需要检查由JWT标头(属性alg)指定的算法是否与API预期的算法匹配。 AAD使用RS256
,所以你应该改为RS256
:
通常的方法是从模数和指数构建,从https://login.microsoftonline.com/common/discovery/keys
匹配kid和x5t从令牌中找到它们。任何使用像https://play.golang.org/这样的在线工具来获取公钥都包含两个部分:n和e。您也可以使用x5c
值,点击here样本。