没有承载令牌或刷新令牌作为响应,CORS被怀疑 - ServiceStack

时间:2018-02-22 20:35:17

标签: cors servicestack

在我的开发环境中,一切正常。然而,要进行分期,现在我们确实有不同的域和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 auth API获得成功的auth响应,如下所示:

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

这是一个实际的响应截图: enter image description here

就像这个ServiceStack user was experiencing一样。在这个引用的链接中,我看到@mythz说这个,&#34;提供者应该是&#34;凭证&#34;。这让我想知道我是否有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响应意味着凭据是好的: enter image description here

但我们有Preflight Request CORS问题: enter image description here

因此,当我将自己的域列入白名单时,请将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:

enter image description here

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

enter image description here

1 个答案:

答案 0 :(得分:2)

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

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

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

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

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

刷新标记

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

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

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