如何从 JavaScript 请求 IdentityServer3 客户端访问令牌?
How to request IdentityServer3 client access token from JavaScript?
我有一个基于 IdentityServer3 的身份验证服务和一个使用 IdentityServer Bearer Token 身份验证保护的 WebAPI Shopper 服务。我已经构建了一个简单的 MVC 客户端应用程序,它可以作为具有访问令牌的客户端应用程序或代表具有身份令牌的经过身份验证的用户访问 Shopper 服务。购物者服务将 return 更多数据提供给经过身份验证的用户。
现在,我正在尝试构建一个 JavaScript 客户端,该客户端对 Shopper 服务执行相同的两层访问级别。到目前为止,按照一些 IdentityServer3 JavaScript 客户端示例,我已经让 JS 客户端代表经过身份验证的用户成功调用 Shopper 服务。 (我可能需要稍微重新组织代码以适应未经身份验证的情况,但这应该不会太困难。)我不知道如何从 JavaScript代码是从身份验证服务 请求客户端访问令牌,即 MVC 客户端中服务器端 TokenClient.RequestClientCredentialsAsync("shopper-service") 的 JavaScript 等价物。有谁知道如何从 JavaScript 请求该令牌或知道如何执行此操作的示例?这是我目前为经过身份验证的案例编写的 JavaScript 代码,下面是工作的 MVC 客户端代码:
function display(selector, data) {
if (data && typeof data === 'string') {
data = JSON.parse(data);
}
if (data) {
data = JSON.stringify(data, null, 2);
}
$(selector).text(data);
}
var settings = {
authority: 'https://localhost:44332',
client_id: 'js-sample',
popup_redirect_uri: 'http://localhost:15264/popup.html',
response_type: 'id_token token',
scope: 'openid orvis-shopper-service',
filterProtocolClaims: false
};
var manager = new Oidc.UserManager(settings);
var user;
manager.events.addUserLoaded(function (loadedUser) {
user = loadedUser;
display('.js-user', user);
});
$('.js-login').on('click', function () {
manager
.signinPopup()
.catch(function (error) {
console.error('error while logging in through the popup', error);
});
});
$('.js-call-api').on('click', function () {
var headers = {};
if (user && user.access_token) {
headers['Authorization'] = 'Bearer ' + user.access_token;
}
$.ajax({
url: 'https://localhost:44368/api/Shopper/{5FA13934-AD20-4AB2-A386-11653D71AE55}',
method: 'GET',
dataType: 'json',
headers: headers
}).then(function (data) {
display('.js-api-result', data);
}).catch(function (error) {
display('.js-api-result', {
status: error.status,
statusText: error.statusText,
response: error.responseJSON
});
});
});
客户端应用程序代码按我的预期运行,如下所示:
public async Task<ActionResult> Index()
{
string tokenValue;
var user = User as ClaimsPrincipal;
if (user.Identity.IsAuthenticated)
{
tokenValue = user.FindFirst("access_token").Value;
}
else
{
var tokenResponse = await GetTokenAsync();
tokenValue = tokenResponse.AccessToken;
}
var result = await CallShopperService(tokenValue);
ViewBag.Json = result;
return View();
}
private async Task<TokenResponse> GetTokenAsync()
{
var client = new TokenClient(
"https://localhost:44332/connect/token",
"mvc-sample-svc",
"mvcsamplesecret");
return await client.RequestClientCredentialsAsync("shopper-service");
}
private async Task<string> CallShopperService(string token)
{
var client = new HttpClient();
client.SetBearerToken(token);
var json = await client.GetStringAsync("https://localhost:44368/api/Shopper/{5FA13934-AD20-4AB2-A386-11653D71AE55}");
return json;
}
JS 隐式客户端也可以取回您的访问令牌,只要您根据粘贴的脚本在 response_type
中设置 token
。
Oidc-client.js 建立授权质询 URL 并将浏览器重定向到它,这是登录流程开始的地方。用户登录后,他们会按照相同的重定向路径返回到您的客户端页面。当您的客户端页面加载时(取决于您的客户端配置的流程,默认情况下它应该是哈希片段),oidc-client 从 URL(#
之后的所有内容)中获取令牌并将其转换为 JSON 对象然后保存在本地存储中(这意味着你也可以在那里检查它)。
我建议使用以下方法来帮助您调试:
打开流量监控工具(例如fiddler)以确保登录后从您的身份服务器返回的响应确实包含访问令牌(您可以使用https://jwt.io/解码令牌字符串),如果不,检查授权请求 url 格式是否正确
如果从身份服务器返回的响应确实包含访问令牌,那么您可以通过在 _signinEnd
方法[=处设置断点来调试 oidc-client.js javascript 15=]
希望对您有所帮助
已更新,来自评论部分
为了 "anonymous token" senario?如果这就是您要查找的内容,请参阅此示例 github.com/IdentityServer/IdentityServer3/issues/1953
我有一个基于 IdentityServer3 的身份验证服务和一个使用 IdentityServer Bearer Token 身份验证保护的 WebAPI Shopper 服务。我已经构建了一个简单的 MVC 客户端应用程序,它可以作为具有访问令牌的客户端应用程序或代表具有身份令牌的经过身份验证的用户访问 Shopper 服务。购物者服务将 return 更多数据提供给经过身份验证的用户。 现在,我正在尝试构建一个 JavaScript 客户端,该客户端对 Shopper 服务执行相同的两层访问级别。到目前为止,按照一些 IdentityServer3 JavaScript 客户端示例,我已经让 JS 客户端代表经过身份验证的用户成功调用 Shopper 服务。 (我可能需要稍微重新组织代码以适应未经身份验证的情况,但这应该不会太困难。)我不知道如何从 JavaScript代码是从身份验证服务 请求客户端访问令牌,即 MVC 客户端中服务器端 TokenClient.RequestClientCredentialsAsync("shopper-service") 的 JavaScript 等价物。有谁知道如何从 JavaScript 请求该令牌或知道如何执行此操作的示例?这是我目前为经过身份验证的案例编写的 JavaScript 代码,下面是工作的 MVC 客户端代码:
function display(selector, data) {
if (data && typeof data === 'string') {
data = JSON.parse(data);
}
if (data) {
data = JSON.stringify(data, null, 2);
}
$(selector).text(data);
}
var settings = {
authority: 'https://localhost:44332',
client_id: 'js-sample',
popup_redirect_uri: 'http://localhost:15264/popup.html',
response_type: 'id_token token',
scope: 'openid orvis-shopper-service',
filterProtocolClaims: false
};
var manager = new Oidc.UserManager(settings);
var user;
manager.events.addUserLoaded(function (loadedUser) {
user = loadedUser;
display('.js-user', user);
});
$('.js-login').on('click', function () {
manager
.signinPopup()
.catch(function (error) {
console.error('error while logging in through the popup', error);
});
});
$('.js-call-api').on('click', function () {
var headers = {};
if (user && user.access_token) {
headers['Authorization'] = 'Bearer ' + user.access_token;
}
$.ajax({
url: 'https://localhost:44368/api/Shopper/{5FA13934-AD20-4AB2-A386-11653D71AE55}',
method: 'GET',
dataType: 'json',
headers: headers
}).then(function (data) {
display('.js-api-result', data);
}).catch(function (error) {
display('.js-api-result', {
status: error.status,
statusText: error.statusText,
response: error.responseJSON
});
});
});
客户端应用程序代码按我的预期运行,如下所示:
public async Task<ActionResult> Index()
{
string tokenValue;
var user = User as ClaimsPrincipal;
if (user.Identity.IsAuthenticated)
{
tokenValue = user.FindFirst("access_token").Value;
}
else
{
var tokenResponse = await GetTokenAsync();
tokenValue = tokenResponse.AccessToken;
}
var result = await CallShopperService(tokenValue);
ViewBag.Json = result;
return View();
}
private async Task<TokenResponse> GetTokenAsync()
{
var client = new TokenClient(
"https://localhost:44332/connect/token",
"mvc-sample-svc",
"mvcsamplesecret");
return await client.RequestClientCredentialsAsync("shopper-service");
}
private async Task<string> CallShopperService(string token)
{
var client = new HttpClient();
client.SetBearerToken(token);
var json = await client.GetStringAsync("https://localhost:44368/api/Shopper/{5FA13934-AD20-4AB2-A386-11653D71AE55}");
return json;
}
JS 隐式客户端也可以取回您的访问令牌,只要您根据粘贴的脚本在 response_type
中设置 token
。
Oidc-client.js 建立授权质询 URL 并将浏览器重定向到它,这是登录流程开始的地方。用户登录后,他们会按照相同的重定向路径返回到您的客户端页面。当您的客户端页面加载时(取决于您的客户端配置的流程,默认情况下它应该是哈希片段),oidc-client 从 URL(#
之后的所有内容)中获取令牌并将其转换为 JSON 对象然后保存在本地存储中(这意味着你也可以在那里检查它)。
我建议使用以下方法来帮助您调试:
打开流量监控工具(例如fiddler)以确保登录后从您的身份服务器返回的响应确实包含访问令牌(您可以使用https://jwt.io/解码令牌字符串),如果不,检查授权请求 url 格式是否正确
如果从身份服务器返回的响应确实包含访问令牌,那么您可以通过在
_signinEnd
方法[=处设置断点来调试 oidc-client.js javascript 15=]
希望对您有所帮助
已更新,来自评论部分
为了 "anonymous token" senario?如果这就是您要查找的内容,请参阅此示例 github.com/IdentityServer/IdentityServer3/issues/1953