I am working through some MVC 6 and ASP.NET 5 samples and I am having issues finding any worthy documentation on using bearer tokens to secure API's. I am able to make such samples work with VS 2013, MVC 5 but I am unable to port these over to VS 2015 and MVC 6. Does anyone know of any good samples of implementing bearer tokens in MVC 6 in order to secure API's?
问题:
回答1:
In order to authenticate a request using bearer tokens, you can pull down the Microsoft.AspNet.Security.OAuthBearer package. Then, you can add the OAuthBearerAuthenticationMiddleware
middleware to the pipeline by using the UseOAuthBearerAuthentication
extension method.
Example:
public void Configure(IApplicationBuilder app)
{
// ...
app.UseOAuthBearerAuthentication(options =>
{
options.Audience = "Redplace-With-Real-Audience-Info";
options.Authority = "Redplace-With-Real-Authority-Info";
});
}
Also, have a look at WebApp-WebAPI-OpenIdConnect-AspNet5 sample.
回答2:
There is no middleware in Asp.Net Core, which generates bearer token. You can create your own solution or implement some community based approaches like
- OpenIdConnect
- OpenIdDict
- IdentityServer4
回答3:
I have implemented a single page application with token based authentication implementation using MVC 6, OpenId and the Aurelia front end framework. In Startup.cs, the Configure method looks like so:
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseIISPlatformHandler();
// Add a new middleware validating access tokens.
app.UseJwtBearerAuthentication(options => {
// Automatic authentication must be enabled
// for SignalR to receive the access token.
options.AutomaticAuthenticate = true;
// Automatically disable the HTTPS requirement for development scenarios.
options.RequireHttpsMetadata = !env.IsDevelopment();
// Note: the audience must correspond to the address of the SignalR server.
options.Audience = clientUri;
// Note: the authority must match the address of the identity server.
options.Authority = serverUri;
});
// Add a new middleware issuing access tokens.
app.UseOpenIdConnectServer(options => {
options.Provider = new AuthenticationProvider();
});
app.UseIISPlatformHandler(options => options.AuthenticationDescriptions.Clear());
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
The authentication provider is defined like so:
public class AuthenticationProvider : OpenIdConnectServerProvider
{
public override Task ValidateClientAuthentication(ValidateClientAuthenticationContext context)
{
if (context.ClientId == "AureliaNetAuthApp")
{
// Note: the context is marked as skipped instead of validated because the client
// is not trusted (JavaScript applications cannot keep their credentials secret).
context.Skipped();
}
else {
// If the client_id doesn't correspond to the
// intended identifier, reject the request.
context.Rejected();
}
return Task.FromResult(0);
}
public override Task GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsContext context)
{
var user = new { Id = "users-123", Email = "alex@123.com", Password = "AureliaNetAuth" };
if (context.UserName != user.Email || context.Password != user.Password)
{
context.Rejected("Invalid username or password.");
return Task.FromResult(0);
}
var identity = new ClaimsIdentity(OpenIdConnectDefaults.AuthenticationScheme);
identity.AddClaim(ClaimTypes.NameIdentifier, user.Id, "id_token token");
identity.AddClaim(ClaimTypes.Name, user.Email, "id_token token");
context.Validated(new ClaimsPrincipal(identity));
return Task.FromResult(0);
}
}
This defines a token endpoint which can be reached at the url /connect/token
.
So to request a token from the client side, here is the javascript code, taken from the AuthService
in authSvc.js:
login(username, password) {
var baseUrl = yourBaseUrl;
var data = "client_id=" + yourAppClientId
+ "&grant_type=password"
+ "&username=" + username
+ "&password=" + password
+ "&resource=" + encodeURIComponent(baseUrl);
return this.http.fetch(baseUrl + 'connect/token', {
method: 'post',
body : data
});
}
Full source can be seen here:
https://github.com/alexandre-spieser/AureliaAspNetCoreAuth
Hope this helps,
Best,
Alex