jwt を使用して、既存の AspNet Core 2.0 / angular 4 アプリを保護しようとしています。クライアント部分に angular2-jwt を使用していますが、問題なく動作します。ただし、WebApi に関しては、トークンは常に拒否されます (angular2-jwt の AuthHttp を使用してリクエストを起動したり、郵便配達員を使用したりします)。私が受け取る唯一の応答は、401 Bearer error="invalid_token" です。jwt.io chrome 拡張機能で確認しましたが、問題ないようです (署名、オーディエンス、発行者)。無効と見なされる理由については、IIS ログにも何も見つかりません。だから私の質問は、トークンの何が問題なのかについて、どうすればより多くの情報を得ることができますか? どんな助けでも大歓迎です。
参考までに、ここに私のstartup.csがあります
public class Startup
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
}
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
IConfigurationSection jwtConf = this.Configuration.GetSection("jwt");
services.Configure<Controls.JWTConf>(Configuration.GetSection("jwt"));
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters =
new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtConf.GetValue<string>("issuer"),
ValidAudience = jwtConf.GetValue<string>("audience"),
IssuerSigningKey = Security.JwtSecurityKey.Create(jwtConf.GetValue<string>("keyBase"))
};
});
services.AddMvc(
config =>
{
var policy = new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireClaim(ClaimTypes.Name)
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
}
).AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
services.AddNodeServices();
string conn = this.Configuration.GetConnectionString("optimumDB");
services.AddDbContext<TracDbContext>(options =>
options.UseSqlServer(conn));
// Register the Swagger generator, defining one or more Swagger documents
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "Angular 4.0 Universal & ASP.NET Core advanced starter-kit web API", Version = "v1" });
});
}
// 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, TracDbContext context)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseStaticFiles();
app.UseAuthentication();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
{
HotModuleReplacement = true,
HotModuleReplacementEndpoint = "/dist/__webpack_hmr"
});
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
// Enable middleware to serve swagger-ui (HTML, JS, CSS etc.), specifying the Swagger JSON endpoint.
app.MapWhen(x => !x.Request.Path.Value.StartsWith("/swagger", StringComparison.OrdinalIgnoreCase), builder =>
{
builder.UseMvc(routes =>
{
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "Home", action = "Index" });
});
});
}
else
{
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(
"Sitemap",
"sitemap.xml",
new { controller = "Home", action = "SitemapXml" });
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "Home", action = "Index" });
});
app.UseExceptionHandler("/Home/Error");
}
}
}
私のトークン生成コントローラー
[Route("api/token")]
[AllowAnonymous]
public class TokenController : Controller
{
private IOptions<JWTConf> jwt;
public TokenController(IOptions<JWTConf> jwtConf)
{
this.jwt = jwtConf;
}
[HttpPost]
public IActionResult Create([FromBody]string userCode)
{
Model.Entities.Utilisateur user = new Model.Entities.Utilisateur { ID_UTILISATEUR = 6 };
JwtToken token = new JwtTokenBuilder()
.AddSecurityKey(JwtSecurityKey.Create(this.jwt.Value.keyBase))
.AddSubject("User")
.AddIssuer(this.jwt.Value.issuer)
.AddAudience(this.jwt.Value.audience)
.AddClaim(ClaimTypes.Name,user.ID_UTILISATEUR.ToString())
.AddExpiry(1440)
.Build();
var tok = new { token = token.Value };
//return Ok(token);
return Ok(JsonConvert.SerializeObject(tok));
}
}
最後に、トークンを拒否するコントローラー:
[Produces("application/json")]
public class JobsController : BaseController
{
public JobsController(IConfiguration config, TracDbContext db) : base(config, db)
{
}
// GET: api/Jobs
[HttpGet]
[Route("api/Jobs")]
public IEnumerable<Departement> Get()
{
return new GroupedJobs(Db.GetJobs().ToList());
}
[HttpGet]
[Route("api/Jobs/{id}")]
public JOB_CLIENT Get(int id)
{
return Db.GetDetailsJob(id);
}
}