如何获取访问令牌并将其从 signin-oidc 存储在客户端 ASP.NET Core 2.0?

How can I get access token and store it from signin-oidc on client side ASP.NET Core 2.0?

我有 3 个项目

1) 身份服务器。它是 netcoreapp1.1 和 identityserver4。它的 URL 是 http://localhost:9000

这是我的客户端应用配置。

new Client
            {
                ClientId = "customer.api",
                ClientName = "Customer services",
                AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
                RequireConsent = false,
                AllowAccessTokensViaBrowser = true,

                RedirectUris = validClientUris.CustomerClientUris
                    .Select(baseUri => baseUri + "signin-oidc")
                    .ToList(),
                PostLogoutRedirectUris = validClientUris.CustomerClientUris.ToList(),

                ClientSecrets = new List<Secret>
                {
                    new Secret("testsecret".Sha256())
                },
                AllowedScopes = new List<string>
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    IdentityServerConstants.StandardScopes.Email,
                    IdentityServerConstants.StandardScopes.OfflineAccess,
                    HydraScopes.CustomerPrivateLinesVNApi, //"customerprivatelinesvn.api"                       
                },
                AllowOfflineAccess = true,
                AlwaysIncludeUserClaimsInIdToken = true,
                AllowedCorsOrigins = validClientUris.CustomerClientUris
            });

2) REST API 项目。这是 ASP.NET 核心 2.0。它的 URL 是 http://localhost:60001

这里是启动的ConfigureServicesclass

public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddCustomerManagementCoreServices()
            .AddRavenStoreServices(Configuration);

        services.AddCors();

        services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme) // "Bearer"
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority = "http://localhost:9000/";
                options.ApiName = "customerprivatelinesvn.api";
                options.RequireHttpsMetadata = false;
            });

        services.AddMvc(setupAction =>
        {
            setupAction.ReturnHttpNotAcceptable = true;                
        });

        services.AddApiVersioning(setupAction =>
        {
            setupAction.ReportApiVersions = true;
        });            
    }

3) Angular 网络应用程序。它的 URL 是 http://localhost:60002

我使用 Visual Studio 2017 年的 Angular 模板如下。

这里是 Angular web

的 Startup class 的 ConfigureServices
public void ConfigureServices(IServiceCollection services)
    {
        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();            

        services.AddAuthentication(options =>
        {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; // "Cookies"
            options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; // "OpenIdConnect"
            options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; // "Cookies"
        })
        .AddCookie()
        .AddOpenIdConnect(options =>
        {
            Configuration.GetSection("OpenIdConnect").Bind(options);                
        });

        services.AddMvc();
    }

这里是OpenIdConnect的配置

"OpenIdConnect": {
"Authority": "http://localhost:9000/",
"RequireHttpsMetadata": false,
"ClientId": "customer.api",
"ClientSecret": "testsecret",
"Scope": [ "customerprivatelinesvn.api", "offline_access" ],      
"PostLogoutRedirectUri": "http://localhost:60002",
"CallbackPath": "/signin-oidc",
"ResponseType": "code id_token token",
"GetClaimsFromUserInfoEndpoint": true,
"SaveTokens":  true}

使用上面的配置,当用户浏览到Angular web (http://localhost:60002) 时,它将重定向到Identity Server 的登录页面。用户输入 username/password 后,它将 return 到 Angular 应用程序,并将经过身份验证的信息存储在 cookies (http://localhost:60002) 中。

我相信访问令牌也存储在 cookie 中。因为我可以在 localhost:60002/signin-oidc.

的 Fiddler 中看到它

我有一些问题

1) 如何从 cookie 获取访问令牌,以便我可以将其添加到请求 header 以便能够在 Angular 上调用 REST API ] 组件?

2) 我们可以将访问令牌存储到本地存储而不是 Cookie 吗?以及如何存储?

3) 当访问令牌过期时,如何存储和使用刷新令牌来获取新的访问令牌?

非常感谢。

此致,

凯文

我们可以在视图中调用HttpContext.GetTokenAsync()

@if (User.Identity.IsAuthenticated)
{
    <input id="access_token" type="hidden" value="@ViewContext.HttpContext.GetTokenAsync("access_token").Result" />    
}

或者我们可以将访问令牌存储在 LocalStorage

@section scripts {
    <script src="~/dist/main-client.js" asp-append-version="true"></script>
    <script>
        var key = "My_app_Access_Token";
        var accessToken = document.getElementById("access_token");
        localStorage.setItem(key, accessToken.value);
    </script>
}