Getting "error": "unsupported_grant_type" when trying to get a JWT by calling an OWIN OAuth secured Web Api via Postman
Solution 1
The response is a bit late - but in case anyone has the issue in the future...
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.
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
Solution 2
With Postman, select Body tab and choose the raw option and type the following:
grant_type=password&username=yourusername&password=yourpassword
Solution 3
- Note the URL:
localhost:55828/token
(notlocalhost:55828/API/token
) - Note the request data. Its not in json format, its just plain data without double quotes.
[email protected]&password=Test123$&grant_type=password
- Note the content type. Content-Type: 'application/x-www-form-urlencoded' (not Content-Type: 'application/json')
-
When you use JavaScript to make post request, you may use following:
$http.post("localhost:55828/token", "userName=" + encodeURIComponent(email) + "&password=" + encodeURIComponent(password) + "&grant_type=password", {headers: { 'Content-Type': 'application/x-www-form-urlencoded' }} ).success(function (data) {//...
See screenshots below from Postman:
Solution 4
If you are using AngularJS you need to pass the body params as string:
factory.getToken = function(person_username) {
console.log('Getting DI Token');
var url = diUrl + "/token";
return $http({
method: 'POST',
url: url,
data: 'grant_type=password&[email protected]&password=mypass',
responseType:'json',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
});
};
Solution 5
try to add this in your payload
grant_type=password&username=pippo&password=pluto
Related videos on Youtube
user20358
Updated on July 05, 2022Comments
-
user20358 almost 2 years
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:
"error": "unsupported_grant_type"
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:
Here is my 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(); } }
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.
The Startup class:
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) } }); } }
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.-
Neo almost 7 yearsI do not want to pass username password rather , I want to verify using exernal providers like twitter consumer key and consumer secret , how can I do that?
-
The Senator almost 7 yearsThanks for this, although your question and ultimate answer weren't actually what I was looking for, an inline snippet seems to have solved it for me. I was struggling with the OPTIONS auth token point being protected by the client id/secret. You saved me!
-
Paramvir Singh Karwal about 5 yearsMake sure that your authorization code has not expired. I was using postman for testing my code. The request contained old authorization code.
-
-
Parshwa Shah over 7 yearsHow can i make same the request from angular service call?
-
sadhana almost 7 yearsI am sending the same request as described above, still getting invalid_grant. Please suggest a solution.
-
greg over 6 yearsfor body's that include special characters like
p@ssword
would you need to replace the "@" with a "%40"? -
OverMars over 6 yearsGreat answer! Steps helped.
-
Peter about 6 years@GregDegruy Looks like only password must be url-encoded. username can contain '@' but I had to replace an & in my password with %26
-
Jonathan Applebaum over 5 yearsalso relevant to angular 2, i have tried to pass the data variable as an object and i got an error, passing the data as a string solved it.
-
Alielson Piffer over 5 yearsI did the same mistake. By selecting "x-www-form-urlencoded" in current version of Postman, the key "Content-Type" will be automatically added in Headers tab. Others parameters should be added in Body tab.
-
Bambam Deo about 5 yearsWhy it isn't working with form-data of body in place of x-www-form-urlencoded?
-
user230910 almost 5 yearsPlease explain how this answers the question as posted?
-
Rishabh Rusia over 2 yearsPostman automatically selects header for Content type based on body selected. We cannot change it to application/x-www-form-urlencoded when entering text content