【问题标题】:ODataController BearerToken Authorization deniedODataController BearerToken 授权被拒绝
【发布时间】:2015-04-08 13:51:39
【问题描述】:

我正在尝试为我的 WebApi 服务实现身份验证提供程序。 我正在使用本指南:http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/ 出于测试目的,我在一个单独的 webapi-project 中实现了两个控制器:

public class TestApiController : ApiController
{
    [Authorize]
    public string Get()
    {
        return "Secure";
    }

    public string Get(int id)
    {
        return "Not Secure";
    }
} 

public class TestODataController : ODataController
{
    [Authorize]
    [EnableQuery]
    public HttpResponseMessage Get()
    {
       return new HttpResponseMessage(HttpStatusCode.OK); 
    }
}

我的目标是最终使用 Odata 控制器。

当我调用 localhost:Port/api/TestApi 并在标头中设置承载令牌时,一切正常。当我调用 localhost:Port/odata/TestOData 并添加令牌时,我会收到消息:

此请求的授权已被拒绝。

我是否在标头中设置令牌都没有关系。如果我删除 Authorize 属性一切正常。 如果有任何兴趣,我正在使用 Postman 调用这些方法。 目前我正在使用 Visual Studio 中的 iis-express 来托管控制器,但 iis 已经配置但会产生相同的消息。

我的 Startup.cs(有趣的部分...)

public void Configuration(IAppBuilder app)
{
    var config = new HttpConfiguration();

    ConfigureOAuth(app);

    FilterConfig.Register(config);
    ODataConfig.Register(config);
    WebApiConfig.Register(config);

    app.UseCors(CorsOptions.AllowAll);
    app.UseWebApi(config);
}

public void ConfigureOAuth(IAppBuilder app)
{
    //Token consumption
    app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
    {});
}

OData 和 WebConfig:

public class ODataConfig
{
    public static void Register(HttpConfiguration config)
    {
        ODataConventionModelBuilder modelBuilder = new ODataConventionModelBuilder();
        modelBuilder.EntitySet<MyModel>("MyModel");

        var conventions = ODataRoutingConventions.CreateDefault();

        var route = config.Routes.MapODataRouteFixed(
            routeName: "ODataRoute",
            routePrefix: "odata",
            model: modelBuilder.GetEdmModel(),
            conventions: conventions) as Route;
    }
}

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    }
}

添加新用户的帐户控制器在另一个项目中。数据库看起来不错,并且令牌生成也有效。它与 bitoftech-demo 中的示例代码几乎相同。

我看不出这些控制器之间的区别。控制器识别了Authorize 属性……但还有其他问题。 任何提示将不胜感激。

更新 经过一些研究和第一个答案后,我更新了我的启动值。旧选项仅对代币生成而非代币消费是必需的。但是 api 控制器仍然有效,并且 OdataController 抛出“授权被拒绝”。

更新2 它现在起作用了。但我不太清楚为什么。我从我的 FilterConfig 中删除了所有内容:

public class FilterConfig
{
    public static void Register(HttpConfiguration config)
    {
        //config.SuppressDefaultHostAuthentication();
        //config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
    }
}

但我不知道为什么它之前使用 api 控制器而不是 odata 控制器...

【问题讨论】:

    标签: asp.net-web-api odata owin


    【解决方案1】:

    如果您使用一个项目获取令牌,另一个项目获取 webApi,则两者在 web.config 中必须具有相同的机器密钥。

    在您关注的同一系列的下一篇文章中解释了如何做到这一点:Decouple OWIN Authorization Server from Resource Server

    例子:

    <system.web>
    ...
    <machineKey validationKey="57B449BBA8F9E656087FF7848727E122C5F5966F65AC0FC25FB3532193B59CFCD13B370883FFC184C1F1500638F33E6F67B37CAED1D9BC65BBC6CFFB232BFD0B" decryptionKey="6D9FBE88D16B3FA5B5E6B37460BBE50DA85D5B4C482159006B5A337C58AA9E79" validation="SHA1" decryption="AES" />
    ...
    </system.web>
    

    【讨论】:

    • 您好,感谢您的回答。目前,这两个项目(身份验证和带有两个控制器的 WebApi)在同一台机器上的一个解决方案中。如果令牌有问题,ApiController 也不应该工作。还是我误会了什么?
    • @dope85 即使他们在同一个解决方案中,如果他们在不同的项目中,您必须在 web.config 文件中为 machinekey 标签设置相同的值。在其他情况下,在自动化过程中创建令牌的方式将与解密以在您的 Web api 控制器中验证的方式不同。
    • @Freerider 如果项目在同一台机器上,则无需在 web.config 中统一 mahcineKey,它们将工作并且将使用 machine.config 而不是 web.config
    • 嗨,我在两个配置中都添加了机器键元素。仍然相同的错误:ApiController 工作,ODataController 返回“此请求的授权已被拒绝。”
    • @TaiseerJoudeh 当然,您可以在计算机级别 (machine.config) 和 IIS 级别 (aspnet.config) 配置 machineKey 标签。在这些情况下,同一台计算机上的所有项目都将共享 machineKey,但是仅在授权服务器 web.config 中配置 machineKey 标签是一个常见错误,这会导致其他项目中的 webApi 无法正确验证。
    【解决方案2】:

    为什么你同时使用app.UseCookieAuthentication(new CookieAuthenticationOptions());app.UseOAuthAuthorizationServer(OAuthOptions);,我猜这只是没有MVC 的API 项目,对吧? 删除app.UseOAuthAuthorizationServer(OAuthOptions); 并重试。

    当您收到 401 时,响应标头 (WWW-Authenticate) 中的值是多少?不记名还是别的什么?

    【讨论】:

    • 删除线后,还是一样的错误。我认为这是使用 cookie 和 Bearer 的附加选项。没有之一。邮递员的标题:Access-Control-Allow-Origin → * Cache-Control → no-cache Content-Length → 97 Content-Type → application/json; odata.metadata=minimal Date → Thu, 09 Apr 2015 05:53:14 GMT Expires → -1 OData-Version → 4.0 Pragma → no-cache Server → Microsoft-IIS/8.5 X-AspNet-Version → 4.0.30319 X-Powered-By → ASP.NET 和正文 { "error": { "code": "", "message": "Authorization has been denied for this request." } }
    【解决方案3】:

    我遇到了类似的问题,并在 Telerik 网站上找到了这个答案,它对我有用。它需要将 dataType 设置为“json”。

    transport: {
        type: "odata",
         read: {
             url: "http://........",
             dataType: "json",
             beforeSend: function (xhr) {
                 var auth = 'Bearer ' + token;
                 xhr.setRequestHeader('Authorization', auth);
             }
         },
    
     },
    

    这是网址: http://www.telerik.com/forums/odata-not-working-with-custom-authorization-header

    【讨论】:

    • 记得选择文本并按下工具栏中的{}按钮来格式化代码,这样阅读代码会更容易。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-26
    • 2011-10-17
    • 1970-01-01
    • 2011-08-28
    • 2012-12-03
    • 2019-03-10
    • 1970-01-01
    相关资源
    最近更新 更多