在 WebAPI 中使用 OAuth2.0 的 Angular 8 CRUD 失败并显示错误:"unsupported_grant_type"



我正在尝试使用 WebApi 2 设置 OAuth 登录,使用 Angular 8 CRUD 与 OAuth2.0 In WebAPI (https://www.c-sharpcorner.com/article/angular-8-crud-with-oauth2-0-in-webapi-part-2/( 文章。

我几乎已经剪切并粘贴了他的代码,但我得到:

400(错误请求(错误:"unsupported_grant_type">

当我回调我的Visual Studio 2015 IIS express实例时,http://localhost/oauth/token

我已经浏览了十几篇文章,这些文章都说要包含application/x-www-urlencoded的内容类型标头,我已经这样做了,但我仍然无法让这个血腥的事情工作!

他的用户身份验证是一项服务,如下所示:

import {HttpClient,HttpHeaders} from '@angular/common/http';    
import { ProductDTO } from '../app/ProductDTO';    
import { Observable } from 'rxjs';    
@Injectable({    
providedIn: 'root'    
})    
export class ProductService {    
ApiUrl='http://localhost:57046/';    
constructor(private httpclient: HttpClient) { }    
UserAuthentication(UserName: string,Password: string):Observable<any>{    
let credentials='username=' +UserName  + '&password=' +Password +'&grant_type=password';     
var reqHeader = new HttpHeaders({'Content-Type': 'application/x-www-urlencoded','No-Auth':'True' });    
return this.httpclient.post<any>(this.ApiUrl+'token',encodeURI(credentials),{headers:reqHeader});    
}    
}

接收 OAuth 请求的后端是:

public class UtiliAuthProvider : OAuthAuthorizationServerProvider
{
private const string IPW = "invalid_password";
private const string IPWC = "invalid_password_recaptcha";
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
string clientId;
string clientSecret;
string jwtName = context.Parameters.Get(ConfigurationManager.AppSettings["WebJWTName"]);
if (!context.TryGetBasicCredentials(out clientId, out clientSecret))
{
context.TryGetFormCredentials(out clientId, out clientSecret);
}
if (context.ClientId == null || jwtName.Equals(ConfigurationManager.AppSettings["WebJWTProg"]))
{
context.Validated(ConfigurationManager.AppSettings["AudienceId"]);
}
else
{
if (context.ClientId == null)
{
context.SetError("invalid_clientId", "client_Id is not set");
}
else
{
if (AudienceProvider.FindAudience(context.ClientId) == null)
{
context.SetError("invalid_clientId", $"Invalid client_id '{context.ClientId}'");
}
else
{
context.Validated();
}
}
}
return Task.FromResult<object>(null);
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { ConfigurationManager.AppSettings["CORSUrl"] });
ApplicationUserManager userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
UtiliUserModel user = await userManager.FindAsync(context.UserName, context.Password);
if (user == null)
{
UtiliUserModel failUser = await userManager.FindByNameAsync(context.UserName);
if (failUser == null)
{
context.SetError("user_not_found", "Please check your user name and try again.");
return;
}
await userManager.AccessFailedAsync(failUser.Id);
if (await userManager.IsLockedOutAsync(failUser.Id))
{
ContextSetErrorLockOut(context);
return;
}
int attemptsLeft = userManager.MaxFailedAccessAttemptsBeforeLockout - failUser.AccessFailedCount;
context.SetError(attemptsLeft == 1 ? IPWC : IPW, $"Incorrect password. You have {attemptsLeft} attempt{(attemptsLeft > 1 ? "s" : "")} left before account is locked out.");
return;
}
if (await userManager.IsLockedOutAsync(user.Id))
{
ContextSetErrorLockOut(context);
return;
}
if (user.AccessFailedCount > 0) await userManager.ResetAccessFailedCountAsync(user.Id);
IFormCollection formData = await context.Request.ReadFormAsync();
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, "JWT");
oAuthIdentity.AddClaim(new Claim(ConfigurationManager.AppSettings["WebJWTName"], formData[ConfigurationManager.AppSettings["WebJWTName"]]));
oAuthIdentity.AddClaim(new Claim(ConfigurationManager.AppSettings["ScopeClaim"], new UtiliportalViews(null).IsCurrentRoleAnyAdmin(context.UserName) ? ConfigurationManager.AppSettings["ScopeClaimAdmin"] : ConfigurationManager.AppSettings["ScopeClaimUser"]));
context.Validated(new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties(new Dictionary<string, string> {{ UtiliportalDbConstants.AudiencePropertyKey, context.ClientId ?? string.Empty }})));
}
private static void ContextSetErrorLockOut(OAuthGrantResourceOwnerCredentialsContext context)
{
context.SetError("locked_out", "This account has been locked.");
}
}

这个后端已经工作了多年,当前的AngularJS客户端没有任何问题。现在尝试将网站重写为 Angular 8,会导致这种胡说八道。

有人可以发布一个如何使用Visual Studio IIS Express服务器调用OAuth/WebApi 2.0登录令牌的工作示例吗?

以下代码将包含客户端 ID 和机密的 oAuth 2 密码授予类型发送到使用 OpenIddict 库生成 JWT 令牌配置的 dotnet core 3 服务器。

在 Angular 的身份验证服务中尝试此操作:

export interface JWT {
token_type: string;
access_token: string;
expires_in: number;
}
@Injectable()
export class AuthService {
private api = `${environment.serverURL}/connect/token`;
private clientID = `${environment.clientID}`;
private secret = `${environment.secret}`;
private currentTokenSubject: BehaviorSubject<JWT>;
constructor(private http: HttpClient){}
login(email: string, password: string): any {
const payload = new HttpParams()
.append('grant_type', 'password')
.append('redirect_uri', 'http://localhost:4200')
.append('client_id', this.clientID)
.append('client_secret', this.secret)
.append('scope', 'email profile roles')
.append('username', email)
.append('password', password);
return this.http.post<JWT>(this.api, payload).pipe(map(token => {
localStorage.setItem('token', JSON.stringify(token));
this.currentTokenSubject.next(token);
}));
}
}

相关内容

最新更新