【问题标题】:No bearer token or refresh token being returned in response, CORS suspected - ServiceStack响应中没有返回承载令牌或刷新令牌,怀疑是 CORS - ServiceStack
【发布时间】:2018-08-02 20:27:55
【问题描述】:

在我的开发环境中,一切正常。但是,要进行暂存,现在我们肯定会遇到不同的域和 CORS 问题,我已经完全解决了这些问题,但可能存在一个问题。

关于我的 API 的 CORS 配置,我正在使用 Microsoft.AspNetCore.Cors Nuget 包,因为我找不到使用 ServiceStack CORS 功能将某些域列入白名单的方法,并且我阅读了 ServiceStack 文档...我现在知道当我实例化ServiceStack 特性有一个重载构造函数:

CorsFeature(ICollection<string> allowOriginWhitelist, string allowedMethods = "GET, POST, PUT, DELETE, PATCH, OPTIONS", string allowedHeaders = "Content-Type", bool allowCredentials = false, string exposeHeaders = null, int? maxAge = null); 

无论如何,所以我使用Microsoft.AspNetCore.Cors。在我的暂存环境中正确配置了 CORS 以满足我的需求,我从我的 ServiceStack 身份验证 API 获得了成功的身份验证响应,如下所示:

{
  "UserId": "1",
  "SessionId": "V8wCKxOooCwLsQ1cn2jp",
  "DisplayName": "foo",
  "ReferrerUrl": "mydomain",
  "ResponseStatus": {}
}

这是一个实际的响应截图:

就像这个 ServiceStack user was experiencing。在这个引用的链接中,我看到@mythz 说,“提供者应该是”凭据“。这让我想知道我是否有 CORS 问题,因为我使用的是 Microsoft.AspNetCore.Cors 而不是 Access-Control-Allow-Credentials 为假的 ServiceStack CORS 功能,并且ServiceStack 代码正在检查这个值,不会返回熊令牌。这是我使用Microsoft.AspNetCore.Cors的配置

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<DbSettings>(options => Configuration.GetSection("DbSettings").Bind(options));
        services.AddTransient<ITsoContext, TsoContext>();
        services.AddTransient<AuthService>();
        services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy",
                builder => builder.AllowAnyOrigin()
                    .SetIsOriginAllowed(CorsHelper.IsOriginAllowed)
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials());
        });
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (EnvironmentHelper.IsDevelopment(env.EnvironmentName) || EnvironmentHelper.IsLocalhost(env.EnvironmentName))
        {
            app.UseDeveloperExceptionPage();

        }

        app.UseCors("CorsPolicy");

        app.UseServiceStack(new AppHost(Configuration, env));
    }

}

所以在我的 AUTH API 中禁用我的 CORS 配置,而是在 AppHost.Configure 方法中使用 ServiceStack CORS:

var corsFeature = new CorsFeature("*", "GET, POST, PUT, DELETE, PATCH, OPTIONS", "Content-Type", true);
Plugins.Add(corsFeature);

最后一个布尔参数将allowCredentials 设置为true。

这会导致 HTTP OK 响应,这意味着凭据是好的:

但是我们有 Preflight Request CORS 问题:

所以当我将我的域列入白名单时,将 allowCredentials 设置为 true 并添加 Authorization allowedHeader:

Plugins.Add(new CorsFeature(allowOriginWhitelist: new[] {  "https://app.staging.mysite.com", "https://auth.staging.mysite.com" }, 
            allowedMethods: "GET, POST, PUT, DELETE, OPTIONS",
            allowCredentials: true,
            allowedHeaders: "Authorization, Content-Type"));

可以说,我们回到第一方,成功的身份验证,使用 ServiceStack 配置 CORS,但响应中仍然没有包含 RefreshToken 或 BearerToken:

经过更多的思考和reading this article,我不太确定这是一个 API 问题,但也许这是一个客户端 CORS 问题。我正在使用 ServiceStack Typescript 客户端,mythz 说这里包含凭据:

【问题讨论】:

    标签: cors servicestack


    【解决方案1】:

    您的问题缺少 AuthFeature 注册,但要使 JWT 令牌能够在 Auth Responses 中返回,您需要包含 JwtAuthProvider 以及您希望支持的任何其他 AuthProviders。

    默认情况下,JWT 配置为RequireSecureConnection,如果您在开发期间未通过https:// 查看此令牌或您通过 SSL 终止,它仅通过安全(即 https://)连接返回 JWT 令牌您需要允许 JWT 通过非安全连接的代理:

    Plugins.Add(new AuthFeature(() => new AuthUserSession(), 
        new IAuthProvider[]
        {
            new JwtAuthProvider(AppSettings){ RequireSecureConnection = false },
        }
    ));
    

    否则,JWT 令牌应在使用 ServiceStack 的内置 AuthProviders 时启用的“身份验证请求”上返回,如果您使用自定义 AuthProvider,您可能需要通过设置指示请求执行身份验证:

    authService.Request.Items[Keywords.DidAuthenticate] = true;
    

    刷新令牌

    对于RefreshTokens to be populated,您需要使用Auth Repository,否则您的Auth Provider 需要实现IUserSessionSource

    将经过身份验证的会话转换为 JWT

    创建 JWT 令牌的另一种方法是通过调用 ConvertSessionToToken 服务到 convert an existing Authenticated Session,或者 Ajax 客户端可以通过 sending a POST Request to /session-to-token 调用它。

    【讨论】:

    • 感谢@mythz 再次及时回复。尽管我对其中一部分感到惊讶,但您的回答是有道理的,在开发 localhost 和 HTTP 开发环境期间,刷新令牌和不记名令牌总是在响应中返回...我认为根据您的回答,我永远不会经历如果一切顺利,不记名令牌将在我的开发环境中做出响应。我在开发环境中的经验是不是因为我的 auth api 一开始就没有注册 AuthFeature?
    • @BrianOgden 如果AuthFeature 未注册,您将根本无法进行身份验证,但如果JwtAuthProvider 未注册,则不会创建任何 JWT 令牌。
    • 你知道@mythz 我可能已经将本地和开发环境的 requiresSecureConnection 设置为 false 是怎么回事,我面前没有代码,但我猜那是必须的案子。对于我的暂存环境,我确实有一个 SSL 终止 NGINX 代理,尽管我没有意识到这是我设置我的第一个代理的方式,直到你这样说
    猜你喜欢
    • 2018-11-14
    • 2016-01-05
    • 2019-01-21
    • 2018-02-24
    • 2021-11-21
    • 2023-02-02
    • 1970-01-01
    • 2020-03-09
    • 1970-01-01
    相关资源
    最近更新 更多