在 ASP.NET 5 中获取访问令牌 [英] Getting an access token in ASP.NET 5
问题描述
我的 ASP.NET 5 (MVC 6 + beta7) Web 应用程序 (MVC + WebAPI) 需要从 WebAPI 登录调用中获取 access_token.
My ASP.NET 5 (MVC 6 + beta7) web application (MVC + WebAPI) is required to get back an access_token from WebAPI login calls.
到目前为止,通过谷歌搜索,我为 startup.cs 创建了以下代码:
So far, from googling, I have created the following code for startup.cs:
app.UseOAuthBearerAuthentication(options => {
options.AutomaticAuthentication = true;
options.Audience = "http://localhost:62100/";
options.Authority = "http://localhost:62100/";
});
我的客户端是:
var login = function ()
{
var url = "http://localhost:62100/";
var data = $("#userData").serialize();
data = data + "&grant_type=password";
$.post(url, data)
.success(saveAccessToken)
.always(showResponse);
return false;
};
是否需要使用UseOpenIdConnectServer
?如果是这样,我如何使用 SigningCredentials
来获取令牌(例如 MVC5 ApplicationOAuthProvider)?
Is it required to use UseOpenIdConnectServer
? If so, how do I use SigningCredentials
so that I get a token (e.g. MVC5 ApplicationOAuthProvider)?
请注意,我的站点是简单的演示 HTTP 站点,我不需要任何 SSL.
Please note that my site is simple demo HTTP site and I do not need any SSL.
推荐答案
是否需要使用UseOpenIdConnectServer?
Is it required to use UseOpenIdConnectServer?
使用 AspNet.Security.OpenIdConnect.Server
不是必需的".您当然可以自由选择另一台服务器(如 IdentityServer)或自定义解决方案.作为 aspnet-contrib 背后的主要开发人员,我并不是很客观,所以我一定会建议使用 app.UseOpenIdConnectServer()
.
Using AspNet.Security.OpenIdConnect.Server
is not "required". You're - of course - free to opt for another server (like IdentityServer) or for a custom solution.
Being the main developer behind aspnet-contrib, I'm not really objective, so I'll necessarily suggest going with app.UseOpenIdConnectServer()
.
如果是这样,我如何使用 SigningCredentials 来获取令牌(例如 MVC5 ApplicationOAuthProvider)?
If so, how do I use SigningCredentials so that I get a token (e.g. MVC5 ApplicationOAuthProvider)?
在实施密码和使用默认令牌类型时,注册签名密钥/证书不是强制性的.
When implementing the password and using the default token type, registering a signing key/certificate is not mandatory.
您可以通过以下方式开始:
Here's how you can get started:
ASP.NET Core 1.x:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication();
}
public void Configure(IApplicationBuilder app)
{
// Add a new middleware validating the encrypted
// access tokens issued by the OIDC server.
app.UseOAuthValidation();
// Add a new middleware issuing tokens.
app.UseOpenIdConnectServer(options =>
{
options.TokenEndpointPath = "/connect/token";
// Override OnValidateTokenRequest to skip client authentication.
options.Provider.OnValidateTokenRequest = context =>
{
// Reject the token requests that don't use
// grant_type=password or grant_type=refresh_token.
if (!context.Request.IsPasswordGrantType() &&
!context.Request.IsRefreshTokenGrantType())
{
context.Reject(
error: OpenIdConnectConstants.Errors.UnsupportedGrantType,
description: "Only grant_type=password and refresh_token " +
"requests are accepted by this server.");
return Task.FromResult(0);
}
// Since there's only one application and since it's a public client
// (i.e a client that cannot keep its credentials private),
// call Skip() to inform the server the request should be
// accepted without enforcing client authentication.
context.Skip();
return Task.FromResult(0);
};
// Override OnHandleTokenRequest to support
// grant_type=password token requests.
options.Provider.OnHandleTokenRequest = context =>
{
// Only handle grant_type=password token requests and let the
// OpenID Connect server middleware handle the other grant types.
if (context.Request.IsPasswordGrantType())
{
// Do your credentials validation here.
// Note: you can call Reject() with a message
// to indicate that authentication failed.
var identity = new ClaimsIdentity(context.Options.AuthenticationScheme);
identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "[unique id]");
// By default, claims are not serialized
// in the access and identity tokens.
// Use the overload taking a "destinations"
// parameter to make sure your claims
// are correctly inserted in the appropriate tokens.
identity.AddClaim("urn:customclaim", "value",
OpenIdConnectConstants.Destinations.AccessToken,
OpenIdConnectConstants.Destinations.IdentityToken);
var ticket = new AuthenticationTicket(
new ClaimsPrincipal(identity),
new AuthenticationProperties(),
context.Options.AuthenticationScheme);
// Call SetScopes with the list of scopes you want to grant
// (specify offline_access to issue a refresh token).
ticket.SetScopes("profile", "offline_access");
context.Validate(ticket);
}
return Task.FromResult(0);
};
});
}
}
.csproj
<ItemGroup>
<PackageReference Include="AspNet.Security.OpenIdConnect.Server" Version="1.0.2" />
</ItemGroup>
ASP.NET Core 2.x:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication()
// Add a new middleware validating the encrypted
// access tokens issued by the OIDC server.
.AddOAuthValidation()
// Add a new middleware issuing tokens.
.AddOpenIdConnectServer(options =>
{
options.TokenEndpointPath = "/connect/token";
// Override OnValidateTokenRequest to skip client authentication.
options.Provider.OnValidateTokenRequest = context =>
{
// Reject the token requests that don't use
// grant_type=password or grant_type=refresh_token.
if (!context.Request.IsPasswordGrantType() &&
!context.Request.IsRefreshTokenGrantType())
{
context.Reject(
error: OpenIdConnectConstants.Errors.UnsupportedGrantType,
description: "Only grant_type=password and refresh_token " +
"requests are accepted by this server.");
return Task.CompletedTask;
}
// Since there's only one application and since it's a public client
// (i.e a client that cannot keep its credentials private),
// call Skip() to inform the server the request should be
// accepted without enforcing client authentication.
context.Skip();
return Task.CompletedTask;
};
// Override OnHandleTokenRequest to support
// grant_type=password token requests.
options.Provider.OnHandleTokenRequest = context =>
{
// Only handle grant_type=password token requests and let the
// OpenID Connect server middleware handle the other grant types.
if (context.Request.IsPasswordGrantType())
{
// Do your credentials validation here.
// Note: you can call Reject() with a message
// to indicate that authentication failed.
var identity = new ClaimsIdentity(context.Scheme.Name);
identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "[unique id]");
// By default, claims are not serialized
// in the access and identity tokens.
// Use the overload taking a "destinations"
// parameter to make sure your claims
// are correctly inserted in the appropriate tokens.
identity.AddClaim("urn:customclaim", "value",
OpenIdConnectConstants.Destinations.AccessToken,
OpenIdConnectConstants.Destinations.IdentityToken);
var ticket = new AuthenticationTicket(
new ClaimsPrincipal(identity),
new AuthenticationProperties(),
context.Scheme.Name);
// Call SetScopes with the list of scopes you want to grant
// (specify offline_access to issue a refresh token).
ticket.SetScopes("profile", "offline_access");
context.Validate(ticket);
}
return Task.CompletedTask;
};
});
}
}
.csproj
<ItemGroup>
<PackageReference Include="AspNet.Security.OpenIdConnect.Server" Version="2.0.0-*" />
</ItemGroup>
您还可以阅读这篇博文,其中解释了如何实现资源所有者密码授予:http://kevinchalet.com/2016/07/13/creating-your-own-openid-connect-server-with-asos-implementing-the-resource-owner-password-credentials-grant/
You can also read this blog post, that explains how to implement the resource owner password grant: http://kevinchalet.com/2016/07/13/creating-your-own-openid-connect-server-with-asos-implementing-the-resource-owner-password-credentials-grant/
这篇关于在 ASP.NET 5 中获取访问令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!