Ich habe diesen Artikel befolgt , um einen OAuth-Autorisierungsserver zu implementieren. Wenn ich jedoch Postman verwende, um ein Token zu erhalten, wird in der Antwort ein Fehler angezeigt:
"error": "unsupported_grant_type"
Ich habe irgendwo gelesen, dass die Daten in Postman mit gebucht werden müssen Content-type:application/x-www-form-urlencoded
. Ich habe die erforderlichen Einstellungen in Postman vorbereitet:
und doch sind meine Überschriften so:
Hier ist mein 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 der obigen CustomJWTFormat-Klasse wird nur der Haltepunkt im Konstruktor getroffen. In der CustomOauth-Klasse wird der Haltepunkt in der GrantResourceOwnerCredentials-Methode niemals getroffen. Die anderen tun es.
Die Startup-Klasse:
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)
}
});
}
}
Muss ich Content-type:application/x-www-form-urlencoded
irgendwo anders im Web-API-Code einrichten ? Was könnte falsch sein? Bitte helfen Sie.
quelle
Antworten:
Die Antwort ist etwas spät - aber falls jemand das Problem in der Zukunft hat ...
Aus dem obigen Screenshot geht hervor, dass Sie die URL-Daten (Benutzername, Kennwort, Grant-Typ) zum Header und nicht zum Body-Element hinzufügen.
Wenn Sie auf die Registerkarte "Körper" klicken und dann das Optionsfeld "x-www-form-urlencoded" auswählen, sollte sich darunter eine Liste mit Schlüsselwerten befinden, in die Sie die Anforderungsdaten eingeben können
quelle
Wählen Sie bei Postman die Registerkarte Body aus, wählen Sie die Rohoption aus und geben Sie Folgendes ein:
quelle
p@ssword
müssten Sie das "@" durch ein "% 40" ersetzen?localhost:55828/token
(nichtlocalhost:55828/API/token
)[email protected]&password=Test123$&grant_type=password
Wenn Sie JavaScript verwenden, um eine Post-Anfrage zu stellen, können Sie Folgendes verwenden:
$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) {//...
Siehe Screenshots unten von Postman:
quelle
Wenn Sie AngularJS verwenden, müssen Sie die Body-Parameter als Zeichenfolge übergeben:
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' } }); };
quelle
Versuchen Sie, dies in Ihre Nutzlast aufzunehmen
quelle
Alte Frage, aber
angular 6
dafür muss dies getan werden, wenn Sie verwenden.HttpClient
Ich mache Token-Daten hier öffentlich verfügbar, aber es wäre gut, wenn Sie über schreibgeschützte Eigenschaften darauf zugreifen würden.import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable, of } from 'rxjs'; import { delay, tap } from 'rxjs/operators'; import { Router } from '@angular/router'; @Injectable() export class AuthService { isLoggedIn: boolean = false; url = "token"; tokenData = {}; username = ""; AccessToken = ""; constructor(private http: HttpClient, private router: Router) { } login(username: string, password: string): Observable<object> { let model = "username=" + username + "&password=" + password + "&grant_type=" + "password"; return this.http.post(this.url, model).pipe( tap( data => { console.log('Log In succesful') //console.log(response); this.isLoggedIn = true; this.tokenData = data; this.username = data["username"]; this.AccessToken = data["access_token"]; console.log(this.tokenData); return true; }, error => { console.log(error); return false; } ) ); } }
quelle
Ich habe auch diesen Fehler erhalten und der Grund war eine falsche Anruf-URL. Ich lasse diese Antwort hier, wenn jemand anderes die URLs mischt und diesen Fehler erhält. Ich habe Stunden gebraucht, um festzustellen, dass ich eine falsche URL hatte.
Fehler, den ich bekommen habe (HTTP-Code 400):
{ "error": "unsupported_grant_type", "error_description": "grant type not supported" }
Ich habe angerufen:
https://MY_INSTANCE.lightning.force.com
Während die richtige URL gewesen wäre:
https://MY_INSTANCE.cs110.my.salesforce.com
quelle
Verwenden Sie grant_type = {Ihr Passwort}
quelle