Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从JavaScript请求IdentityServer3客户端访问令牌?_Javascript_Authentication_Identityserver3_Openid Connect - Fatal编程技术网

如何从JavaScript请求IdentityServer3客户端访问令牌?

如何从JavaScript请求IdentityServer3客户端访问令牌?,javascript,authentication,identityserver3,openid-connect,Javascript,Authentication,Identityserver3,Openid Connect,我有一个基于IdentityServer 3的身份验证服务和一个WebAPI购物者服务,该服务由IdentityServer承载令牌身份验证进行保护。我已经构建了一个简单的MVC客户端应用程序,它可以作为具有访问令牌的客户端应用程序或代表具有身份令牌的经过身份验证的用户访问购物者服务。购物者服务将向经过身份验证的用户返回更多数据。 现在,我正在尝试构建一个JavaScript客户端,它对购物者服务进行相同的两层访问。到目前为止,在一些IdentityServer3JavaScript客户端示例之

我有一个基于IdentityServer 3的身份验证服务和一个WebAPI购物者服务,该服务由IdentityServer承载令牌身份验证进行保护。我已经构建了一个简单的MVC客户端应用程序,它可以作为具有访问令牌的客户端应用程序或代表具有身份令牌的经过身份验证的用户访问购物者服务。购物者服务将向经过身份验证的用户返回更多数据。 现在,我正在尝试构建一个JavaScript客户端,它对购物者服务进行相同的两层访问。到目前为止,在一些IdentityServer3JavaScript客户端示例之后,我已经让JS客户端代表经过身份验证的用户成功地调用了购物者服务。(我可能需要重新组织代码以适应未经身份验证的场景,但这应该不会太困难。)我不知道如何从JavaScript代码中请求来自身份验证服务的客户端访问令牌,即MVC客户端中服务器端TokenClient.RequestClientCredentialsAsync(“购物者服务”)的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;
}
公共异步任务索引()
{
字符串标记值;
var user=用户作为ClaimsPrincipal;
if(user.Identity.IsAuthenticated)
{
tokenValue=user.FindFirst(“访问令牌”).Value;
}
其他的
{
var tokenResponse=await GetTokenAsync();
tokenValue=tokenResponse.AccessToken;
}
var结果=等待CallShopperService(令牌值);
Json=result;
返回视图();
}
私有异步任务GetTokenAsync()
{
var client=新的令牌客户端(
"https://localhost:44332/connect/token",
“mvc示例svc”,
“mvcsamplesecret”);
return wait client.RequestClientCredentialsAsync(“购物者服务”);
}
专用异步任务CallShopperService(字符串令牌)
{
var client=新的HttpClient();
client.SetBearerToken(令牌);
var json=await client.GetStringAsync(“https://localhost:44368/api/Shopper/{5FA13934-AD20-4AB2-A386-11653D71AE55});
返回json;
}

JS隐式客户端也可以取回您的访问令牌,只要您根据粘贴的脚本在
response\u type
中设置
token

Oidc-client.js构建了一个授权质询URL,并将浏览器重定向到该URL,这就是登录流开始的地方。用户登录后,他们会按照相同的重定向路径返回到您的客户端页面。加载客户端页面时(取决于客户端配置的流,默认情况下它应该是散列片段),oidc客户端从URL(在
#
之后的所有内容)获取令牌,并将其转换为JSON对象,然后保存在本地存储中(这意味着您也可以在那里检查它)

我建议使用以下方法帮助您进行调试:

  • 打开流量监控工具(如fiddler),以确保登录后从identity server返回的响应不包含访问令牌(您可以使用解码令牌字符串),如果不包含,请检查授权请求url的格式是否正确

  • 如果从identity server返回的响应包含访问令牌,则可以通过在
    \u signinEnd
    方法处设置断点来调试oidc-client.js javascript

  • 希望能有帮助

    从评论部分更新


    “匿名令牌”senario?如果这就是您要查找的github.com/IdentityServer/IdentityServer3/issues/1953,请参见此示例,您会说“用户登录后…”,我会让该流程正常工作。我想在用户未登录的情况下获取客户端访问令牌。在我的MVC客户端应用程序中,我有两个独立的IdentityServer客户端—MVC sample和MVC sample svc—分别实现不同的流—隐式和ClientCredentials。我想我需要对我的JavaScript客户端应用程序执行类似的操作,但我不确定如何在ClientCredentials流中检索未登录场景的访问令牌。@user3498540客户端凭据流不是为依赖浏览器的客户端设计的,因为它不安全。如果我理解正确的话,你看起来像“匿名令牌”?看看这个例子,如果这是你想要的,谢谢。我想,我所寻找的方法不受支持是有道理的。您提供链接的另一种方法非常不同,但显然是针对同一组需求的,看起来它会起作用。我对此有一些问题,但我将这些问题发布在github线程上。感谢您的帮助。如果您将指向解决方案的指针作为答案而不是评论发布在github上,我将很乐意接受它作为我问题的答案。