在服务到服务的Oauth通信中,我尝试向外部Oauth令牌端点发送令牌请求,并将令牌用作Microsoft解决方案(Dynamics CRM v.9.1 On-Premises)的承载。所使用的平台不应该如此相关,因为我们正在谈论OAuth,这是一个RFC文档化的协议。到目前为止,我用来获取令牌并向资源服务器发出请求的代码是下面粘贴的代码。
当我向资源服务器发出请求时,我得到以下错误。
Bearer error=invalid_token, error_description=Error during token validation!,
authorization_uri=https://mytokenserver/login,
resource_id=https://myresourceserver/
字符串
响应中的问题是它显示了一个“authorization_uri”,它是https://mytokenserver/login,这是错误的。我的授权URI是:https://mytokenserver/oauth2/authorize
我在微软的crm平台中找不到任何设置,所以我最好的猜测是我在下面的代码中生成了一个错误的AssertJWT。
有这方面的经验吗?(只是一个小细节,OAuth令牌服务器是用Java编写的)
static private string clientId = "rb7ddjkjWd8djkjlk";
static private string pfxFile = "C:\\keystore.p12";
static private string pass = "blabla";
static private string authorityUri = "https://mytokenserver/oauth2/token";
static private Uri environmentUri = new Uri("https://myresourceserver/api/data/v9.1");
static async Task<string> RequestTokenAndSendRequestToResourceServerAsync()
{
if (tokenCache != "")
return tokenCache;
var client = new HttpClient();
var clientToken = GetJwtToken(pfxFile, pass, clientId, authorityUri, 180);
Console.WriteLine("JWT Token is: " + clientToken);
Parameters parameters = new Parameters
{
new KeyValuePair<string, string>("audience", clientId),
new KeyValuePair<string, string>("requested_token_type", "urn:ietf:params:oauth:token-type:access_token")
};
ClientCredentialsTokenRequest clientCredentialsRequest = new ClientCredentialsTokenRequest
{
Parameters = parameters,
GrantType = OidcConstants.GrantTypes.ClientCredentials,
Address = authorityUri,
ClientAssertion =
{
Type = OidcConstants.ClientAssertionTypes.JwtBearer,
Value = clientToken
}
};
clientCredentialsRequest.ClientCredentialStyle = ClientCredentialStyle.PostBody;
var response = await client.RequestClientCredentialsTokenAsync(clientCredentialsRequest);
if (response.IsError)
{
Console.WriteLine(response.HttpStatusCode);
Console.WriteLine(response.ErrorDescription);
Console.WriteLine(response.ErrorType.ToString());
throw response.Exception;
}
Console.WriteLine("Access Token is: " + response.AccessToken);
// Set up the HTTP client
var httpclient = new HttpClient
{
BaseAddress = new Uri("https://myresourceserver"),
Timeout = new TimeSpan(0, 2, 0) // Standard two minute timeout.
};
HttpRequestHeaders headers = httpclient.DefaultRequestHeaders;
headers.Authorization = new AuthenticationHeaderValue("Bearer", response.AccessToken);
headers.Add("OData-MaxVersion", "4.0");
headers.Add("OData-Version", "4.0");
headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Web API call
var result = httpclient.GetAsync("WhoAmI").Result;
var jsonResponse = await result.Content.ReadAsStringAsync();
Console.WriteLine(result.ReasonPhrase);
Console.WriteLine(jsonResponse);
result.EnsureSuccessStatusCode();
return response.AccessToken;
}
public static string GetJwtToken(string pfxFilePath, string password, string issuer, string audience, int expiryInMinutes)
{
Console.WriteLine("Creating JWT Token");
string jwtToken = string.Empty;
JwtSecurityToken jwtSecurityToken;
X509Certificate2 signingCert = new X509Certificate2(pfxFilePath, password);
X509SecurityKey privateKey = new X509SecurityKey(signingCert);
var descriptor = new SecurityTokenDescriptor
{
// Audience = auth2/token endpoint, Issuer = clientId
Issuer = issuer,
Audience = audience,
IssuedAt = DateTime.UtcNow,
Expires = DateTime.UtcNow.AddMinutes(expiryInMinutes),
Subject = new ClaimsIdentity(new List<Claim>
{
new Claim(JwtClaimTypes.Subject, issuer),
new Claim(Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
}),
SigningCredentials = new SigningCredentials(privateKey, SecurityAlgorithms.RsaSha256)
};
var handler = new JwtSecurityTokenHandler();
handler.SetDefaultTimesOnTokenCreation = false;
jwtSecurityToken = handler.CreateJwtSecurityToken(descriptor);
jwtSecurityToken.Header.Remove("kid");
jwtToken = handler.WriteToken(jwtSecurityToken);
return jwtToken;
}
型
1条答案
按热度按时间vmdwslir1#
我猜您正在调用的资源服务器不允许客户端凭据访问令牌。它可能要求用户成为令牌的主体,而不是您的服务。这可以解释错误消息。服务器期望授权代码请求的端点是令牌中存在的端点。您拥有令牌端点(在客户端凭据流中使用)。