it-swarm.com.ru

Конечная точка API возвращает "В этом запросе отказано в авторизации". при отправке токена на предъявителя

Я следовал руководству по защите веб-API с помощью OAuth в C #. 

Я делаю несколько тестов, и до сих пор я смог успешно получить токен доступа из /token. Я использую расширение Chrome под названием «Advanced REST Client» для его тестирования. 

{"access_token":"...","token_type":"bearer","expires_in":86399}

Это то, что я получаю от /token. Все выглядит хорошо.

Мой следующий запрос на мой тестовый контроллер API:

namespace API.Controllers
{
    [Authorize]
    [RoutePrefix("api/Social")]
    public class SocialController : ApiController
    {
      ....


        [HttpPost]
        public IHttpActionResult Schedule(SocialPost post)
        {
            var test = HttpContext.Current.GetOwinContext().Authentication.User;

            ....
            return Ok();
        }
    }
}

Запрос является POST и имеет заголовок:

Authorization: Bearer XXXXXXXTOKEHEREXXXXXXX

Я получаю: Authorization has been denied for this request. возвращается в формате JSON.

Я также попытался выполнить GET и получил то, что ожидал, что метод не поддерживается, так как я его не реализовал.

Вот мой поставщик авторизации:

public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
    public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
    }

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {

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

        using (var repo = new AuthRepository())
        {
            IdentityUser user = await repo.FindUser(context.UserName, context.Password);

            if (user == null)
            {
                context.SetError("invalid_grant", "The user name or password is incorrect.");
                return;
            }
        }

        var identity = new ClaimsIdentity(context.Options.AuthenticationType);
        identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
        identity.AddClaim(new Claim(ClaimTypes.Role, "User"));

        context.Validated(identity); 

    }
}

Любая помощь будет отличной. Я не уверен, что это неправильный запрос или код. 

Правка: Вот мой Startup.cs

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();
        WebApiConfig.Register(config);
        app.UseWebApi(config);
        ConfigureOAuth(app);
    }

    public void ConfigureOAuth(IAppBuilder app)
    {
        var oAuthServerOptions = new OAuthAuthorizationServerOptions()
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
            Provider = new SimpleAuthorizationServerProvider()
        };

        // Token Generation
        app.UseOAuthAuthorizationServer(oAuthServerOptions);
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

    }
}
16
Bri Veillette

Проблема довольно проста: Изменить порядок вашего конвейера OWIN .

public void Configuration(IAppBuilder app)
{
    ConfigureOAuth(app);
    var config = new HttpConfiguration();
    WebApiConfig.Register(config);
    app.UseWebApi(config);
}

Для конвейера OWIN порядок вашей конфигурации довольно важен. В вашем случае вы пытаетесь использовать ваш обработчик Web API перед обработчиком OAuth. Внутри него вы проверяете свой запрос, обнаруживаете безопасное действие и пытаетесь проверить его по текущему Owin.Context.User. На данный момент этот пользователь не существует, потому что он установлен из токена с OAuth Handler, который вызывается позже.

29
Andrei Tserakhau

Вы должны добавить претензию с этой схемой:

http://schemas.Microsoft.com/ws/2008/06/identity/claims/role

лучше всего использовать предопределенный набор требований:

identity.AddClaim(new Claim(ClaimTypes.Role, "User"));

Вы можете найти ClaimTypes в System.Security.Claims.

Еще одна вещь, которую вы должны учитывать, это фильтровать роли в вашем контроллере/действии:

[Authorize(Roles="User")]

Вы можете найти простое приложение-образец, размещенное самостоятельно с клиентом jquery здесь .

2
LeftyX

Похоже, версия " System.IdentityModel.Tokens.Jwt" , которая сосуществует с другими сборками Owin, неверна.

Если вы используете «Microsoft.Owin.Security.Jwt» версии 2.1.0, вам следует использовать сборку «System.IdentityModel.Tokens.Jwt» версии 3.0.2.

С консоли диспетчера пакетов попробуйте:

Update-Package System.IdentityModel.Tokens.Jwt -Version 3.0.2
0
aquaraga