Получение "ошибки": "unsupported_grant_type" при попытке получить JWT путем вызова OWuth OAuth Secure Web Api через почтмана
Я выполнил эту статью для реализации сервера авторизации OAuth. Однако, когда я использую post man для получения токена, я получаю сообщение об ошибке:
"error": "unsupported_grant_type"
Я где-то читал, что данные в Postman должны быть опубликованы с помощью Content-type:application/x-www-form-urlencoded
. Я подготовил необходимые настройки в Postman:
![enter image description here]()
и все же мои заголовки таковы:
![enter image description here]()
Вот мой код
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 никогда не попадает. Другие делают.
Класс запуска:
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)
}
});
}
}
Нужно ли настраивать Content-type:application/x-www-form-urlencoded
где-то еще в веб-коде api? Что может быть неправильным? Пожалуйста, помогите.
Ответы
Ответ 1
Ответ немного запоздалый - но в случае, если у кого-то проблема в будущем...
На скриншоте выше - кажется, что вы добавляете данные url (имя пользователя, пароль, grant_type) в заголовок, а не в элемент body.
Нажав на вкладку body, а затем выберите переключатель "x-www-form-urlencoded", должен быть список ключевых значений ниже, где вы можете ввести данные запроса
Ответ 2
В Postman выберите вкладку "Тело" и выберите опцию raw и введите следующее:
grant_type=password&username=yourusername&password=yourpassword
Ответ 3
- Обратите внимание на URL-адрес:
localhost:55828/token
(не localhost:55828/API/token
)
- Обратите внимание на данные запроса. Его не в формате json, его просто данные без двойных кавычек.
[email protected]&password=Test123$&grant_type=password
- Обратите внимание на тип содержимого. Content-Type: 'application/x-www-form-urlencoded' (не Content-Type: 'application/json')
-
Когда вы используете JavaScript для создания почтового запроса, вы можете использовать следующее:
$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) {//...
Посмотрите скриншоты из Postman:
![Postman Request]()
![Заголовок сообщения почтальона]()
Ответ 4
попытайтесь добавить это в свою полезную нагрузку
grant_type=password&username=pippo&password=pluto
Ответ 5
Используйте grant_type = {Ваш пароль} ![введите описание изображения здесь]()