ASP.NET 5 OAuthBearerAuthentication: The following authentication scheme was not accepted: Media

Updated:

Pinpoint helped me get this prototype from the launch pad - I was very close, except:

{ "projects": [ "src", "test" ], "sdk": { "version": "1.0.0-beta6" } } 
  • I updated the links in project.json:
 { "webroot": "wwwroot", "version": "1.0.0-*", "dependencies": { "Microsoft.AspNet.Mvc": "6.0.0-beta6", "Microsoft.AspNet.Server.IIS": "1.0.0-beta6", "Microsoft.AspNet.Server.WebListener": "1.0.0-beta6", "Microsoft.AspNet.StaticFiles": "1.0.0-beta6", "System.IdentityModel.Tokens": "5.0.0-beta6-207211625", "Serilog.Framework.Logging": "1.0.0-beta-43", "Microsoft.AspNet.Authentication.OAuthBearer": "1.0.0-beta6" }, "commands": { "web": "Microsoft.AspNet.Hosting --config hosting.ini" }, "frameworks": { "dnx451": { } }, "exclude": [ "wwwroot", "node_modules", "bower_components" ], "publishExclude": [ "node_modules", "bower_components", "**.xproj", "**.user", "**.vspscc" ] } 
  • The order of the middleware at startup. UseOAuthBearerAuthentication should appear before UseMvc. The Configure method in Startup.cs now looks like this:
 public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseOAuthBearerAuthentication(); app.UseMvc(); } 



I work with ASP.NET 5 and try to implement an extremely simple proof of the concept of generating and consuming JWT tokens. Here I read articles, here and here , but this one most closely matches my needs.

To this end, I read the article very carefully, re-read it, learned all the comments, and then stood by a simple example. Now I can create a JWT token, but when I try to call my controller action, which was decorated with the authorize [Authorize ("Bearer")] attribute, I get the following message:

The following authentication scheme was not accepted: Media

Since I have not seen a high-precision A-to-Z example on how to do this, consider the following steps to reproduce:

  • Create a new web API project in Visual Studio 2015 (I use Enterprise) by selecting "New Project ... Web ... ASP.NET Web Application" and then the "Web API" option under "ASP.NET 5 Preview Templates "
  • Using beta 5 of the SDK, global.json looks like this:
 { "projects": [ "src", "test" ], "sdk": { "version": "1.0.0-beta5", "runtime": "clr", "architecture": "x86" } } 
  • When entering the dependencies required for JWT tokens, project.json looks like this:
 { "webroot": "wwwroot", "version": "1.0.0-*", "dependencies": { "Microsoft.AspNet.Mvc": "6.0.0-beta6", "Microsoft.AspNet.Server.IIS": "1.0.0-beta6", "Microsoft.AspNet.Server.WebListener": "1.0.0-beta6", "System.IdentityModel.Tokens": "5.0.0-beta5-206011020", "Microsoft.AspNet.Authentication.OAuthBearer": "1.0.0-beta5" }, "commands": { "web": "Microsoft.AspNet.Hosting --config hosting.ini" }, "frameworks": { "dnx451": { } }, "exclude": [ "wwwroot", "node_modules", "bower_components" ], "publishExclude": [ "node_modules", "bower_components", "**.xproj", "**.user", "**.vspscc" ] } 
  • Startup.cs (this is an example not intended for production)
 public class Startup { const string _TokenIssuer = "contoso.com" ; const string _TokenAudience = "contoso.com/resources" ; RsaSecurityKey _key = null ; SigningCredentials _signingCredentials = null ; public Startup(IHostingEnvironment env) { GenerateRsaKeys(); } public void ConfigureServices(IServiceCollection services) { services.AddInstance(_signingCredentials); services.ConfigureOAuthBearerAuthentication ( options => { options.AutomaticAuthentication = true; options.TokenValidationParameters.IssuerSigningKey = _key ; options.TokenValidationParameters.ValidAudience = _TokenAudience; options.TokenValidationParameters.ValidIssuer = _TokenIssuer ; } ); services.ConfigureAuthorization ( options => { options. AddPolicy ( "Bearer", new AuthorizationPolicyBuilder(). AddAuthenticationSchemes(OAuthBearerAuthenticationDefaults.AuthenticationScheme). RequireAuthenticatedUser(). Build() ); } ); services.AddMvc(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env,ILoggerFactory loggerfactory) { app.UseMvc(); app.UseOAuthBearerAuthentication(); } void GenerateRsaKeys() { using(RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048)) { _key = new RsaSecurityKey(rsa.ExportParameters(true)); _signingCredentials = new SigningCredentials ( _key , SecurityAlgorithms.RsaSha256Signature , SecurityAlgorithms.Sha256Digest , "secret" ); rsa.PersistKeyInCsp = false; } } } 
  • Some models:

Credentials.cs

 public class Credentials { public string user { set;get;} public string password { set;get;} } 

JwtToken.cs

 public class JwtToken { public string access_token { set; get; } public string token_type { set; get; } } 
  • Token controller for receiving a token (this is an example not intended for production), TokenController.cs:
 [ Route("[controller]") ] public class TokenController : Controller { private readonly OAuthBearerAuthenticationOptions _bearerOptions ; private readonly SigningCredentials _signingCredentials ; public TokenController ( IOptions<OAuthBearerAuthenticationOptions> bearerOptions , SigningCredentials signingCredentials ) { _bearerOptions = bearerOptions.Options ; _signingCredentials = signingCredentials ; } // POST: /token [HttpPost()] public JwtToken Token([FromBody] Credentials credentials) { // Pretend to validate credentials... JwtSecurityTokenHandler handler = _bearerOptions . SecurityTokenValidators . OfType<JwtSecurityTokenHandler>() . First(); JwtSecurityToken securityToken = handler . CreateToken ( issuer : _bearerOptions.TokenValidationParameters.ValidIssuer , audience : _bearerOptions.TokenValidationParameters.ValidAudience, signingCredentials : _signingCredentials , subject : new ClaimsIdentity ( new Claim [] { new Claim(ClaimTypes.Name,"somebody"), new Claim(ClaimTypes.Role,"admin" ), new Claim(ClaimTypes.Role,"teacher" ), } ) , expires : DateTime.Today.AddDays(1) ); string token = handler.WriteToken(securityToken); return new JwtToken() { access_token = token , token_type = "bearer" }; } } 
  • The value controller demonstrating the passage of the token, ValuesController.cs:
 [Route("api/[controller]")] public class ValuesController : Controller { // GET: api/values [Authorize("Bearer")] [HttpGet] public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } // GET api/values/5 [HttpGet("{id}")] public string Get(int id) { return "value"; } } 
  • Run a copy of postman (or your favorite REST client), run the sample application in Visual Studio and make a POST request, similar to http: // localhost: 22553 / token / with JSON body:
 { "user" : "user", "password" : "secret" } 

The application responds with a token:

 { "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6bnVsbH0.eyJ1bmlxdWVfbmFtZSI6InNvbWVib2R5Iiwicm9sZSI6WyJhZG1pbiIsInRlYWNoZXIiXSwiaXNzIjoiY29udG9zby5jb20iLCJhdWQiOiJjb250b3NvLmNvbS9yZXNvdXJjZXMiLCJleHAiOjE0Mzk1MzU2MDB9.anRgL10XFG_bKDDxY3D2xQSfhPRLGMjUTreQNsP1jDA6eRKwXHf3jtpCwm_saoWyUDFFA2TMI9e_LbP6F5l7vtozCluziE_GQkPkspUSWuWIpQJLPRTTPPZHGKmPmK4MLEl1zPPrggJWbvF9RBw3mMQ0KoMfjSL0vUQ8kZ7VXAel8dnYJccd-CFdnB6aDe79x2E9Se2iLxdhr--R_qgvfz1Fa6tR1dstqLQ-UjYqPWY4SOgBjM3abtjfLLVEzeQMVyezX7Cx9ObMXAGbGvQL6GB_T5RlfAoXWME4jM8Bzhd-07wwd732bBws4OXivj1sSz-qawNTnXmnuccLRtI1uA", "token_type": "bearer" } - R_qgvfz1Fa6tR1dstqLQ-UjYqPWY4SOgBjM3abtjfLLVEzeQMVyezX7Cx9ObMXAGbGvQL6GB_T5RlfAoXWME4jM8Bzhd-07wwd732bBws4OXivj1sSz-qawNTnXmnuccLRtI1uA", { "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6bnVsbH0.eyJ1bmlxdWVfbmFtZSI6InNvbWVib2R5Iiwicm9sZSI6WyJhZG1pbiIsInRlYWNoZXIiXSwiaXNzIjoiY29udG9zby5jb20iLCJhdWQiOiJjb250b3NvLmNvbS9yZXNvdXJjZXMiLCJleHAiOjE0Mzk1MzU2MDB9.anRgL10XFG_bKDDxY3D2xQSfhPRLGMjUTreQNsP1jDA6eRKwXHf3jtpCwm_saoWyUDFFA2TMI9e_LbP6F5l7vtozCluziE_GQkPkspUSWuWIpQJLPRTTPPZHGKmPmK4MLEl1zPPrggJWbvF9RBw3mMQ0KoMfjSL0vUQ8kZ7VXAel8dnYJccd-CFdnB6aDe79x2E9Se2iLxdhr--R_qgvfz1Fa6tR1dstqLQ-UjYqPWY4SOgBjM3abtjfLLVEzeQMVyezX7Cx9ObMXAGbGvQL6GB_T5RlfAoXWME4jM8Bzhd-07wwd732bBws4OXivj1sSz-qawNTnXmnuccLRtI1uA", "token_type": "bearer" } 
  • Copy the token from the previous POST, then in the postman make a GET request similar to http: // localhost: 22553 / api / values, trying to add an authorization header with the value "bearer YOURTOKEN" (for example, bearer eyJ0eXAiOiJKV1QiLCJ ...)

  • Please note that the application responds to an error:

System.InvalidOperationException The following authentication scheme was not accepted: Bearer

The stack trace is as follows:

 at Microsoft.AspNet.Http.Authentication.Internal.DefaultAuthenticationManager.< AuthenticateAsync> d__9.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at Microsoft.AspNet.Http.Authentication.AuthenticationManager.< AuthenticateAsync> d__2.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter< TResult> .GetResult() at Microsoft.AspNet.Mvc.AuthorizeFilter.< OnAuthorizationAsync> d__5.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at Microsoft.AspNet.Mvc.Core.FilterActionInvoker.< InvokeAuthorizationFilterAsync> d__43.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at Microsoft.AspNet.Mvc.Core.FilterActionInvoker.< InvokeAllAuthorizationFiltersAsync> d__42.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at Microsoft.AspNet.Mvc.Core.FilterActionInvoker.< InvokeAsync> d__40.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at Microsoft.AspNet.Mvc.MvcRouteHandler.< InvokeActionAsync> d__4.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at Microsoft.AspNet.Mvc.MvcRouteHandler.< RouteAsync> d__3.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at Microsoft.AspNet.Mvc.Routing.InnerAttributeRoute.< RouteAsync> d__10.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at Microsoft.AspNet.Routing.RouteCollection.< RouteAsync> d__9.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at Microsoft.AspNet.Builder.RouterMiddleware.< Invoke> d__4.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at Microsoft.AspNet.Hosting.Internal.RequestServicesContainerMiddleware.< Invoke> d__3.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at Microsoft.AspNet.Hosting.Internal.HostingEngine.< > c__DisplayClass29_0.< < Start> b__0> d.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at Microsoft.AspNet.Loader.IIS.RuntimeHttpApplication.< ProcessRequestAsyncImpl> d__10.MoveNext() --- exception rethrown --- at Microsoft.AspNet.Loader.IIS.RuntimeHttpApplication.< ProcessRequestAsyncImpl> d__10.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at Microsoft.AspNet.Loader.IIS.HttpApplicationBase.< InvokeProcessRequestAsyncImpl> d__9.MoveNext() 

Note that adding logging adds little to no additional understanding, as the following logs show:

 2015-08-13 13:32:35.969 -07:00 [Information] Request successfully matched the route with name 'null' and template '"api/Values"'. Exception thrown: 'System.InvalidOperationException' in Microsoft.AspNet.Http.dll 2015-08-13 13:32:36.247 -07:00 [Error] An error occurred while handling the request. 2015-08-13 13:32:36.247 -07:00 System.InvalidOperationException: The following authentication scheme was not accepted: Bearer 

I hope someone can figure out where the breakdown in this example occurs.

+10
asp.net-core-mvc jwt
Aug 13 '15 at 20:42
source share
1 answer

You must register the OAuth2 bearer authentication middleware before MVC, or your users will be unauthenticated upon reaching MVC:

 public class Startup { public void Configure(IApplicationBuilder app) { app.UseJwtBearerAuthentication(new JwtBearerOptions { // Your JWT bearer options. }); app.UseMvc(); } } 
+6
Aug 13 '15 at 21:23
source share



All Articles