ODataController BearerToken авторизация отклонена

Я пытаюсь реализовать поставщика аутентификации для своих служб WebApi. Я использую это руководство: http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/ Для тестирования Я реализовал два контроллера в отдельном webapi-проекте:

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 Controller.

Когда я вызываю localhost: Port / api / TestApi и устанавливаю токен-носитель в заголовке, все работает нормально. Когда я вызываю localhost: Port / odata / TestOData и добавляю токен, я получаю сообщение:

В авторизации для этого запроса отказано.

Неважно, установил ли я токен в заголовке или нет. Если я удалю атрибут Authorize, все будет работать нормально. Я использую Postman для вызова методов, если это интересно. На данный момент я использую iis-express из Visual Studio для размещения контроллеров, но 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.

Я не вижу разницы между этими контроллерами. Атрибут Auhtorize распознается контроллером ... но что-то еще не так. Любые подсказки будут оценены.

Обновление. После некоторых исследований и первых ответов я обновил свои значения запуска. Старые параметры необходимы только для генерации токенов, а не для потребления токенов. Но все же контроллеры api работают, а OdataController выдает сообщение «Авторизация запрещена».

Update2 Теперь это сработало. Но я не совсем понимаю, почему. Я удалил все из своего FilterConfig:

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

Но я понятия не имею, почему он работал раньше с контроллером api, а не с контроллером odata ...


person dope85    schedule 08.04.2015    source источник


Ответы (3)


Если вы используете один проект для получения токена, а другой - для webApi, оба должны иметь одинаковый машинный ключ в web.config.

В следующем посте того же сериала, за которым вы следите, объясняется, как это сделать: Отделить сервер авторизации OWIN от сервера ресурсов

Пример:

<system.web>
...
<machineKey validationKey="57B449BBA8F9E656087FF7848727E122C5F5966F65AC0FC25FB3532193B59CFCD13B370883FFC184C1F1500638F33E6F67B37CAED1D9BC65BBC6CFFB232BFD0B" decryptionKey="6D9FBE88D16B3FA5B5E6B37460BBE50DA85D5B4C482159006B5A337C58AA9E79" validation="SHA1" decryption="AES" />
...
</system.web>
person Xavier Egea    schedule 08.04.2015
comment
Привет спасибо за ответ Два проекта (Authentication и WebApi с двумя контроллерами) на данный момент находятся в одном решении на одной машине. Если с токеном что-то не так, ApiController тоже не должен работать. Или я что-то недопонимаю? - person dope85; 08.04.2015
comment
@ dope85 Даже если они находятся в одном решении, если они находятся в разных проектах, вы должны установить одно и то же значение для тега machinekey в файле web.config. В другом случае способ создания токена в процессе авторизации будет отличаться от способа расшифровки для проверки в ваших контроллерах веб-API. - person Xavier Egea; 08.04.2015
comment
@Freerider Нет необходимости унифицировать mahcineKey в web.config, если проекты находятся на одном компьютере, они будут работать и будут использовать machine.config, а не web.config - person Taiseer Joudeh; 08.04.2015
comment
Привет, я добавил ключевой элемент машины в обе конфигурации. Все та же ошибка: ApiController работает, ODataController возвращает. Авторизация была отклонена для этого запроса. - person dope85; 09.04.2015
comment
@TaiseerJoudeh Конечно, вы можете настроить тег machineKey на уровне компьютера (machine.config) и на уровне IIS (aspnet.config). В этих случаях все проекты на одном компьютере будут совместно использовать machineKey, однако распространенная ошибка заключается в настройке тега machineKey только в сервере авторизации web.config, из-за чего webApi в других проектах не аутентифицируется правильно. - person Xavier Egea; 09.04.2015

Почему вы используете app.UseCookieAuthentication(new CookieAuthenticationOptions()); и app.UseOAuthAuthorizationServer(OAuthOptions); одновременно, я думаю, это всего лишь проект API без MVC, верно? Удалите app.UseOAuthAuthorizationServer(OAuthOptions); и попробуйте еще раз.

Какое значение будет в заголовке ответа (WWW-Authenticate), когда вы получите 401? Предъявитель или что-то еще?

person Taiseer Joudeh    schedule 08.04.2015
comment
После удаления строки все та же ошибка. Я подумал, что это дополнительная возможность использовать файлы cookie и носитель. Ни один из них. Заголовки от Postman: 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." } } - person dope85; 09.04.2015

У меня была аналогичная проблема, и я нашел этот ответ на веб-сайте Telerik, и он сработал для меня. Требовалось установить для параметра dataType значение «json».

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

 },

Это URL: http://www.telerik.com/forums/odata-not-working-with-custom-authorization-header.

person pakaraima    schedule 17.10.2015
comment
Не забудьте отформатировать код, выделив текст и нажав кнопку {} на панели инструментов, это значительно упрощает чтение кода. - person Lima; 17.10.2015