我正在使用IdentityServer4处理ASP.NET核心API中的身份验证和授权。我在客户端使用angular4。
我知道我可以使用tokenype = access_token
来使用令牌端点(http://myapidomain/connect/token)来获取ResourceOwnerPassword
。这意味着我在登录界面中提供username
和password
进行身份验证。
我的问题是:我们是否需要实施API Account/Login
了?我认为IdentityServer4已经通过cookie身份验证中间件自动处理登录。
如果我们需要实现API Account/Login
。实现这一目标的最佳做法是什么。
我在某处读到的是用于登录
await HttpContext.Authentication.SignInAsync(identityUser.Id, identityUser.UserName);
这用于注销
await HttpContext.Authentication.SignOutAsync
我的第二个问题是:
当我从access_token
获得connect/token
时。我尝试通过访问http://myapidomain/connect/userinfo获取userinfo。但我总是得到405错误代码。
我缺少什么
authFormHeaders() {
const header = new Headers();
header.append('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');
header.append('Accept', 'application/json');
header.append('Authorization', 'Bearer ' + this.oidcSecurityCommon.getAccessToken());
return header;
}
getUserInfo() {
let self = this;
let options = new RequestOptions({
method: RequestMethod.Get,
headers: this.authService.authFormHeaders()
});
return self.http.get(this.authWellKnownEndpoints.userinfoEndpoint, options)
.map((res: Response) => {
return res.json();
})
.catch(self.appService.handleError);
}
在我的API服务器端:
CorsPolicyBuilder corsBuilder = new CorsPolicyBuilder()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowAnyOrigin()
.AllowCredentials();
services.AddCors(opts =>
{
opts.AddPolicy("AllowAllOrigins", corsBuilder.Build());
});
var url = optionsAccessor.Value.SystemConfig.Authority;
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
Authority = url,
RequireHttpsMetadata = false,
ApiName = "netpower.qms.saas.api"/*,
AllowedScopes = { IdentityServerConstants.StandardScopes.OpenId }*/
});
app.UseCors("AllowAllOrigins");
答案 0 :(得分:2)
对于Angular客户端,您应该使用grantype Implicit而不是ResourceOwnerPassword。资源所有者密码凭据授予类型适用于资源所有者与客户端具有信任关系的情况,例如设备操作系统或高权限应用程序。 授权服务器在启用此授权类型时应特别小心,并且仅在其他流不可行时才允许(来自OAuth Spec)
资源所有者密码授予类型允许请求令牌 代表用户通过向令牌发送用户的名称和密码 端点。这就是所谓的“非交互式”身份验证 一般不推荐。某些遗产可能有原因 或者第一方集成方案,其中此授权类型很有用, 但一般的建议是使用像 用户身份验证的隐式或混合。
对于使用Implicit的实现,您可以参考this并使用ResourceOwnerpassword,请参阅this。
资源类型的流程如下
+----------+
| Resource |
| Owner |
| |
+----------+
v
| Resource Owner
(A) Password Credentials
|
v
+---------+ +---------------+
| |>--(B)---- Resource Owner ------->| |
| | Password Credentials | Authorization |
| Client | | Server |
| |<--(C)---- Access Token ---------<| |
| | (w/ Optional Refresh Token) | |
+---------+ +---------------+
对于具有Angular和Identity Server 4的ResourceOwnerPassword类型,您可以参考this GitHub repo,其中还包含客户端和服务器端的一些示例代码
步骤如下
资源所有者为客户提供其用户名和 密码
客户端从授权请求访问令牌 服务器的令牌端点,包括收到的凭据 来自资源所有者。在提出请求时,客户端 使用授权服务器进行身份验证。
授权服务器对客户端进行身份验证并进行验证 资源所有者凭据,如果有效,则发出访问权限 令牌。
我们是否需要实施API帐户/登录?
不,您不必实现。如您所知,这是在授权服务器中完成的。您将向Identity Server 4身份验证服务器发送用户名和密码,并将为您提供Bearer令牌。您的中间件(app.UseIdentityServerAuthentication
)将验证您的申请请求。
我尝试通过访问http://myapidomain/connect/userinfo获取userinfo。但我总是得到405错误代码。我缺少什么
您可以查看身份服务器日志以找出遗漏的内容。我捕获了一个示例请求,它将如下所示
POST http://myapidomain/connect/token HTTP/1.1
Host: myapidomain
Proxy-Connection: keep-alive
Content-Length: 142
Pragma: no-cache
Cache-Control: no-cache
Accept: application/json, text/plain, */*
Origin: http://angularspawebapi.azurewebsites.net
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.110 Safari/537.36
Content-Type: application/x-www-form-urlencoded
client_id=AngularSPA&grant_type=password&username=admin%40gmail.com&password=Admin01*&scope=WebAPI%20offline_access%20openid%20profile%20roles
GET http://myapidomain/connect/userinfo HTTP/1.1
Host: myapidomain
Proxy-Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.110 Safari/537.36
Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjhDRTQ1ODAwQTAwNkExNkZGMzEwOTExMDVCRjNDNTY2MzgzNEUxQkEiLCJ0eXAiOiJKV1QiLCJ4NXQiOiJqT1JZQUtBR29XX3pFSkVRV19QRlpqZzA0Ym8ifQ.eyJuYmYiOjE1MDAwOTk4NjIsImV4cCI6MTUwMDEwMDc2MiwiaXNzIjoiaHR0cDovL2FuZ3VsYXJzcGF3ZWJhcGkuYXp1cmV3ZWJzaXRlcy5uZXQiLCJhdWQiOlsiaHR0cDovL2FuZ3VsYXJzcGF3ZWJhcGkuYXp1cmV3ZWJzaXRlcy5uZXQvcmVzb3VyY2VzIiwiV2ViQVBJIl0sImNsaWVudF9pZCI6IkFuZ3VsYXJTUEEiLCJzdWIiOiI5Y2I1ZGViNS1iZWRmLTRkMWItOThkNS05ZTFjYTgwNzVhYjAiLCJhdXRoX3RpbWUiOjE1MDAwOTk4NjEsImlkcCI6ImxvY2FsIiwicm9sZSI6ImFkbWluaXN0cmF0b3IiLCJzY29wZSI6WyJvcGVuaWQiLCJwcm9maWxlIiwicm9sZXMiLCJXZWJBUEkiLCJvZmZsaW5lX2FjY2VzcyJdLCJhbXIiOlsicHdkIl19.CZAGtK5hvwgkMvX9NQ-8zTFr8Cv3SRVhM-u1WdqdLwI-qbdknfhhVFFHFpPzEWEJnKhsi3aE_BOb_UtRiDBWNHzlXAGmKSjtd70HOlT3dR9Sj_v09Ld15On3HihgfeDwOzIt10ZYwwjRr1tRCf6Ro41FQ2UrzBYcSFe47md7DSlxPXbjnQAHdu8gHMITFF8Nqx0V9OEw21fofRdBalOpvxf1IBhsJwWLyL4bLFYya8jNispK4MnN_tdaS8kxIMZ8iC_IUlhY4XEj5pkDBA9r8ad_Vn5WavO3Lmr4Tew4uBhlFhbE-Qr6EpErAEBVHVtJYs70XXGJJ7QQLoFNmO5M9w
content-type: text/plain