获得"错误":" unsupported_grant_type"试图通过调用通过邮差的OWIN的OAuth保护的Web API来获取一个JWT时 [英] Getting "error": "unsupported_grant_type" when trying to get a JWT by calling an OWIN OAuth secured Web Api via Postman

查看:5115
本文介绍了获得"错误":" unsupported_grant_type"试图通过调用通过邮差的OWIN的OAuth保护的Web API来获取一个JWT时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我按照<一个href=\"http://bitoftech.net/2015/02/16/implement-oauth-json-web-tokens-authentication-in-asp-net-web-api-and-identity-2/\"相对=nofollow>这篇文章实现一个OAuth授权服务器。然而,当我使用后的人得到一个道理,我在响应得到一个错误:

I have followed this article to implement an OAuth Authorization server. However when I use post man to get a token, I get an error in the response:

错误:unsupported_grant_type

"error": "unsupported_grant_type"

我读的地方,需要使用被张贴在邮差数据内容类型:应用程序/ x-WWW的形式urlen codeD 。我有$ P $在邮差ppped所需的设置:

I read somewhere that the data in Postman needs to be posted using Content-type:application/x-www-form-urlencoded. I have prepped the required settings in Postman:

可是我的标题是这样的:

and yet my headers are like this:

下面是我的code

public class CustomOAuthProvider : OAuthAuthorizationServerProvider
{
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
        return Task.FromResult<object>(null);
    }

    public override Task MatchEndpoint(OAuthMatchEndpointContext context)
    {
        if (context.OwinContext.Request.Method == "OPTIONS" && context.IsTokenEndpoint)
        {
            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Methods", new[] { "POST" });
            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "accept", "authorization", "content-type" });
            context.OwinContext.Response.StatusCode = 200;
            context.RequestCompleted();
            return Task.FromResult<object>(null);
        }
        return base.MatchEndpoint(context);       
    }

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        string allowedOrigin = "*";

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

        Models.TheUser user = new Models.TheUser();
        user.UserName = context.UserName;
        user.FirstName = "Sample first name";
        user.LastName = "Dummy Last name";

        ClaimsIdentity identity = new ClaimsIdentity("JWT");

        identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
        foreach (string claim in user.Claims)
        {
            identity.AddClaim(new Claim("Claim", claim));    
        }

        var ticket = new AuthenticationTicket(identity, null);
        context.Validated(ticket);
    }
}

public class CustomJwtFormat : ISecureDataFormat<AuthenticationTicket>
{
    private readonly string _issuer = string.Empty;

    public CustomJwtFormat(string issuer)
    {
        _issuer = issuer;
    }

    public string Protect(AuthenticationTicket data)
    {
        string audienceId = ConfigurationManager.AppSettings["AudienceId"];
        string symmetricKeyAsBase64 = ConfigurationManager.AppSettings["AudienceSecret"];
        var keyByteArray = TextEncodings.Base64Url.Decode(symmetricKeyAsBase64);
        var signingKey = new HmacSigningCredentials(keyByteArray);
        var issued = data.Properties.IssuedUtc;
        var expires = data.Properties.ExpiresUtc;
        var token = new JwtSecurityToken(_issuer, audienceId, data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime, signingKey);
        var handler = new JwtSecurityTokenHandler();
        var jwt = handler.WriteToken(token);
        return jwt;
    }

    public AuthenticationTicket Unprotect(string protectedText)
    {
        throw new NotImplementedException();
    }
}

在上面只在构造函数中的断点CustomJWTFormat类被击中。在CustomOauth类中,GrantResourceOwnerCredentials方法断点从来没有被击中。其他人做的。

In the CustomJWTFormat class above only the breakpoint in the constructor gets hit. In the CustomOauth class, the breakpoint in the GrantResourceOwnerCredentials method never gets hit. The others do.

启动类:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

        HttpConfiguration config = new HttpConfiguration();
        WebApiConfig.Register(config);

        ConfigureOAuthTokenGeneration(app);
        ConfigureOAuthTokenConsumption(app);

        app.UseWebApi(config);
    }

    private void ConfigureOAuthTokenGeneration(IAppBuilder app)
    {
        var OAuthServerOptions = new OAuthAuthorizationServerOptions()
        {
            //For Dev enviroment only (on production should be AllowInsecureHttp = false)
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/oauth/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
            Provider = new CustomOAuthProvider(),
            AccessTokenFormat = new CustomJwtFormat(ConfigurationManager.AppSettings["Issuer"])
        };

        // OAuth 2.0 Bearer Access Token Generation
        app.UseOAuthAuthorizationServer(OAuthServerOptions);
    }

    private void ConfigureOAuthTokenConsumption(IAppBuilder app)
    {
        string issuer = ConfigurationManager.AppSettings["Issuer"]; 
        string audienceId = ConfigurationManager.AppSettings["AudienceId"];
        byte[] audienceSecret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["AudienceSecret"]);

        // Api controllers with an [Authorize] attribute will be validated with JWT
        app.UseJwtBearerAuthentication(
            new JwtBearerAuthenticationOptions
            {
                AuthenticationMode = AuthenticationMode.Active,
                AllowedAudiences = new[] { audienceId },
                IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
                {
                    new SymmetricKeyIssuerSecurityTokenProvider(issuer, audienceSecret)
                }
            });
    }
}

我是否需要设置内容类型:应用程序/ x-WWW的形式urlen codeD 在Web API code别的地方?可能是什么问题?请帮助。

Do I need to set up Content-type:application/x-www-form-urlencoded somewhere else in the web api code? What could be wrong? Please help.

推荐答案

的反应是有点晚了 - 但如果任何人有这个问题在未来...

The response is a bit late - but in case anyone has the issue in the future...

从上面的截图 - 似乎你添加的URL数据(用户名,密码,grant_type)的头部,而不是身体的元素

From the screenshot above - it seems that you are adding the url data (username, password, grant_type) to the header and not to the body element.

点击体标签,然后选择X-WWW的形式urlen codeD单选按钮,应该有以下关键值列表,您可以输入请求数据

Clicking on the body tab, and then select "x-www-form-urlencoded" radio button, there should be a key-value list below that where you can enter the request data

这篇关于获得&QUOT;错误&QUOT;:&QUOT; unsupported_grant_type&QUOT;试图通过调用通过邮差的OWIN的OAuth保护的Web API来获取一个JWT时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆