获取“错误":“unsupported_grant_type"尝试通过 Postman 调用 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

查看:61
本文介绍了获取“错误":“unsupported_grant_type"尝试通过 Postman 调用 OWIN OAuth 安全 Web Api 来获取 JWT 时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已关注 本文 实现一个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"

我在某处读到 Postman 中的数据需要使用 Content-type:application/x-www-form-urlencoded 发布.我已经在 Postman 中准备了所需的设置:

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:

这是我的代码

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)
                }
            });
    }
}

我是否需要在 web api 代码的其他地方设置 Content-type:application/x-www-form-urlencoded?可能有什么问题?请帮忙.

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.

点击body选项卡,然后选择x-www-form-urlencoded"单选按钮,下面应该有一个键值列表,您可以在其中输入请求数据

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

这篇关于获取“错误":“unsupported_grant_type"尝试通过 Postman 调用 OWIN OAuth 安全 Web Api 来获取 JWT 时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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