Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: dope85Ответов: 3

Я пытаюсь реализовать поставщика аутентификации для своих служб 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 ...

odataowin

Ответы

Ответ 1 · Xavier Egea

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

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

Пример:

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

Ответ 2 · Taiseer Joudeh

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

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

Ответ 3 · pakaraima

У меня была аналогичная проблема, и я нашел этот ответ на веб-сайте 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.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы