未在OwinContext

时间:2016-04-19 20:39:44

标签: iis cors asp.net-web-api2 owin jwt

我使用本文here创建了一个使用JWT系统的web api。从REST客户端调用API时,它可以正常工作。但是,当尝试从浏览器访问它时,它会发出CORS错误,因为它没有发出正确的响应标头。

Startup.cs

app.UseCors(CorsOptions.AllowAll);

请注意,在我的控制器上CORS工作得很好,它只是打破了OAuthAuthorizationServer。

CustomOAuthProvider.cs

public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
    context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

    var user = Database.Users.FirstOrDefault(u => u.Email == context.UserName);

    if (user == null || !BCrypt.Net.BCrypt.Verify(context.Password, user.Password))
    {
        context.SetError("invalid_grant", "The user name or password is incorrect.");
        return Task.FromResult<object>(null);
    } 

    var companyId = int.Parse(context.OwinContext.Get<string>("company_id"));
    var company = user.Companies.FirstOrDefault(c => c.Id == companyId);

    if (company == null)
    {
        context.SetError("invalid_grant", "You don't belong to that company!");
        return Task.FromResult<object>(null);
    } 

    var identity = new ClaimsIdentity("JWT");
    identity.AddClaim(new Claim("uue", user.Email));

    var props = new AuthenticationProperties(new Dictionary<string, string>
    {
        { "audience", company.ServerUrl }
    });

    var ticket = new AuthenticationTicket(identity, props);

    context.Validated(ticket);
    return Task.FromResult<object>(null);
}

然而,在进行调用以获取令牌之后,我只收回这些响应头。

Content-Length:1245
Content-Type:text/html
Date:Wed, 20 Apr 2016 20:34:40 GMT
Server:Microsoft-IIS/8.5
X-Powered-By:ASP.NET

我做错了吗?

2 个答案:

答案 0 :(得分:1)

注意:我假设您使用的是相似教程中定义的相同Startup.cs代码。

尝试将调用转移到app.UseCors(CorsOptions.AllowAll);Configuration方法顶部的Startup.cs

public void Configuration(IAppBuilder app)
{
   app.UseCors(CorsOptions.AllowAll);

   HttpConfiguration config = new HttpConfiguration();

   // Web API routes
   config.MapHttpAttributeRoutes();

   ConfigureOAuth(app);

   app.UseWebApi(config);

}

在Owin中,只有前面的中间件通过调用才会执行管道中的每个中间件。出于这个原因,app.UseCors仅在AuthenticationMiddleware(在您的情况下为OAuthAuthorizationServer)之后执行,并且仅在它不会停止管道中的流程时执行(例如OAuth返回响应)。

在其他中间件之前移动Cors中间件声明可确保为每个请求执行它。

答案 1 :(得分:0)

确保在Web配置中允许CORS

<httpProtocol>
      <customHeaders>
        <clear />
        <add name="Access-Control-Allow-Methods" value="GET,PUT,POST,OPTIONS,DEBUG" />
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="authorization,content-type" />
      </customHeaders>
    </httpProtocol>