Asp.net 核心 2.1 的 JWT 身份验证仅适用于本地主机
JWT Authentification with Asp.net core 2.1 works only on localhost
我向现有的 aspnet core mvc web 应用程序添加了 JWT 身份验证,以保护 api 移动应用程序。
我使用 Multi auth 和 MultiPolicies 进行授权(带有身份和 JWT 的 Cookie),我使用 postman 和移动应用程序在本地主机上对其进行了测试,它运行良好。但是当我将它部署到我的远程服务器时,我不工作。身份验证和令牌生成有效,但是当我使用 httpget 请求访问 api 时,我会重定向到 mvc 登录页面。
我的 Startup.cs 包含这个:
services.AddAuthentication().AddCookie(options =>
{
options.Cookie.HttpOnly = identityDefaultOptions.CookieHttpOnly;
options.Cookie.Expiration = TimeSpan.FromDays(identityDefaultOptions.CookieExpiration);
options.LoginPath = identityDefaultOptions.LoginPath; // If the LoginPath is not set here, ASP.NET Core will default to /Account/Login
options.LogoutPath = identityDefaultOptions.LogoutPath; // If the LogoutPath is not set here, ASP.NET Core will default to /Account/Logout
options.AccessDeniedPath = identityDefaultOptions.AccessDeniedPath; // If the AccessDeniedPath is not set here, ASP.NET Core will default to /Account/AccessDenied
options.SlidingExpiration = identityDefaultOptions.SlidingExpiration;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = tokenValidationParameters;
options.Audience = jwtAppSettingsOptions[nameof(JwtIssuerOptions.Audience)];
options.RequireHttpsMetadata = bool.Parse(jwtAppSettingsOptions[nameof(JwtIssuerOptions.RequireHttpsMetadata)]);
});
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new RequireHttpsAttribute());
config.Filters.Add(new AuthorizeFilter(policy));
}).AddJsonOptions(opt =>
opt.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver())
.AddJsonOptions(opt => opt.SerializerSettings
.ReferenceLoopHandling = ReferenceLoopHandling.Ignore).AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
// Add support for localizing strings in data annotations (e.g. validation messages) via the
// IStringLocalizer abstractions.
.AddDataAnnotationsLocalization();
services.AddAuthorization(options =>
{
options.AddPolicy("ApiUserPolicy", policy => policy.RequireClaim("JwtRole", "ID"));
});
这是使用邮递员登录本地主机的屏幕截图。
这是使用带有生产环境的邮递员登录。
这是本地主机上的请求,它有效,我得到了 json 结果。
在这里我得到了这个重定向到 mvc 登录页面。
我的问题是通过对 startup.cs 进行一些更改解决的,我 删除了 来自 的策略过滤器services.AddMVC 选项定义,我向授权定义添加了两个授权策略:
services.AddAuthentication().AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.Cookie.HttpOnly = identityDefaultOptions.CookieHttpOnly;
options.Cookie.Expiration = TimeSpan.FromDays(identityDefaultOptions.CookieExpiration);
options.LoginPath = identityDefaultOptions.LoginPath; // If the LoginPath is not set here, ASP.NET Core will default to /Account/Login
options.LogoutPath = identityDefaultOptions.LogoutPath; // If the LogoutPath is not set here, ASP.NET Core will default to /Account/Logout
options.AccessDeniedPath = identityDefaultOptions.AccessDeniedPath; // If the AccessDeniedPath is not set here, ASP.NET Core will default to /Account/AccessDenied
options.SlidingExpiration = identityDefaultOptions.SlidingExpiration;
})
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.TokenValidationParameters = tokenValidationParameters;
options.Audience = jwtAppSettingsOptions[nameof(JwtIssuerOptions.Audience)];
options.RequireHttpsMetadata = bool.Parse(jwtAppSettingsOptions[nameof(JwtIssuerOptions.RequireHttpsMetadata)]);
});
services.AddMvc(config =>
{
config.Filters.Add(new RequireHttpsAttribute());
}).AddJsonOptions(opt =>
opt.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver())
.AddJsonOptions(opt => opt.SerializerSettings
.ReferenceLoopHandling = ReferenceLoopHandling.Ignore).AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
// Add support for localizing strings in data annotations (e.g. validation messages) via the
// IStringLocalizer abstractions.
.AddDataAnnotationsLocalization();
services.AddAuthorization(options =>
{
options.AddPolicy(CookieAuthenticationDefaults.AuthenticationScheme, new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme)
.Build());
options.AddPolicy("ApiUserPolicy", new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.RequireClaim("JwtRole", "ID")
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.Build());
});
要了解更多有关策略和 authentificationSchemas 的授权,请检查此 answer
我向现有的 aspnet core mvc web 应用程序添加了 JWT 身份验证,以保护 api 移动应用程序。
我使用 Multi auth 和 MultiPolicies 进行授权(带有身份和 JWT 的 Cookie),我使用 postman 和移动应用程序在本地主机上对其进行了测试,它运行良好。但是当我将它部署到我的远程服务器时,我不工作。身份验证和令牌生成有效,但是当我使用 httpget 请求访问 api 时,我会重定向到 mvc 登录页面。 我的 Startup.cs 包含这个:
services.AddAuthentication().AddCookie(options =>
{
options.Cookie.HttpOnly = identityDefaultOptions.CookieHttpOnly;
options.Cookie.Expiration = TimeSpan.FromDays(identityDefaultOptions.CookieExpiration);
options.LoginPath = identityDefaultOptions.LoginPath; // If the LoginPath is not set here, ASP.NET Core will default to /Account/Login
options.LogoutPath = identityDefaultOptions.LogoutPath; // If the LogoutPath is not set here, ASP.NET Core will default to /Account/Logout
options.AccessDeniedPath = identityDefaultOptions.AccessDeniedPath; // If the AccessDeniedPath is not set here, ASP.NET Core will default to /Account/AccessDenied
options.SlidingExpiration = identityDefaultOptions.SlidingExpiration;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = tokenValidationParameters;
options.Audience = jwtAppSettingsOptions[nameof(JwtIssuerOptions.Audience)];
options.RequireHttpsMetadata = bool.Parse(jwtAppSettingsOptions[nameof(JwtIssuerOptions.RequireHttpsMetadata)]);
});
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new RequireHttpsAttribute());
config.Filters.Add(new AuthorizeFilter(policy));
}).AddJsonOptions(opt =>
opt.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver())
.AddJsonOptions(opt => opt.SerializerSettings
.ReferenceLoopHandling = ReferenceLoopHandling.Ignore).AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
// Add support for localizing strings in data annotations (e.g. validation messages) via the
// IStringLocalizer abstractions.
.AddDataAnnotationsLocalization();
services.AddAuthorization(options =>
{
options.AddPolicy("ApiUserPolicy", policy => policy.RequireClaim("JwtRole", "ID"));
});
我的问题是通过对 startup.cs 进行一些更改解决的,我 删除了 来自 的策略过滤器services.AddMVC 选项定义,我向授权定义添加了两个授权策略:
services.AddAuthentication().AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.Cookie.HttpOnly = identityDefaultOptions.CookieHttpOnly;
options.Cookie.Expiration = TimeSpan.FromDays(identityDefaultOptions.CookieExpiration);
options.LoginPath = identityDefaultOptions.LoginPath; // If the LoginPath is not set here, ASP.NET Core will default to /Account/Login
options.LogoutPath = identityDefaultOptions.LogoutPath; // If the LogoutPath is not set here, ASP.NET Core will default to /Account/Logout
options.AccessDeniedPath = identityDefaultOptions.AccessDeniedPath; // If the AccessDeniedPath is not set here, ASP.NET Core will default to /Account/AccessDenied
options.SlidingExpiration = identityDefaultOptions.SlidingExpiration;
})
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.TokenValidationParameters = tokenValidationParameters;
options.Audience = jwtAppSettingsOptions[nameof(JwtIssuerOptions.Audience)];
options.RequireHttpsMetadata = bool.Parse(jwtAppSettingsOptions[nameof(JwtIssuerOptions.RequireHttpsMetadata)]);
});
services.AddMvc(config =>
{
config.Filters.Add(new RequireHttpsAttribute());
}).AddJsonOptions(opt =>
opt.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver())
.AddJsonOptions(opt => opt.SerializerSettings
.ReferenceLoopHandling = ReferenceLoopHandling.Ignore).AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
// Add support for localizing strings in data annotations (e.g. validation messages) via the
// IStringLocalizer abstractions.
.AddDataAnnotationsLocalization();
services.AddAuthorization(options =>
{
options.AddPolicy(CookieAuthenticationDefaults.AuthenticationScheme, new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme)
.Build());
options.AddPolicy("ApiUserPolicy", new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.RequireClaim("JwtRole", "ID")
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.Build());
});
要了解更多有关策略和 authentificationSchemas 的授权,请检查此 answer