- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要在 ASP.NET Core 2.0 MVC 应用程序中支持两种身份验证类型:
在ASP.NET Core 1.0版本中这非常容易。但在 2.0 版本中语法发生了变化。这是我的代码:
services.AddAuthentication(o =>
{
o.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
o.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
o.DefaultAuthenticateScheme = OpenIdConnectDefaults.AuthenticationScheme;
}).AddIdentityServerAuthentication(options =>
{
options.Authority = PlatformConfiguration.IdentityServerUri;
options.RequireHttpsMetadata = false;
options.SaveToken = true;
options.ApiSecret = "somesecret";
options.ApiName = "some_api";
})
.AddCookie()
.AddOpenIdConnect(o =>
{
o.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
o.Authority = PlatformConfiguration.IdentityServerUri;
o.RequireHttpsMetadata = false;
o.ClientId = "some_viewer";
o.UseTokenLifetime = true;
o.ResponseType = "id_token token";
o.Scope.Add("openid");
o.Scope.Add("roles");
o.Scope.Add("profile");
o.SaveTokens = true;
o.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = JwtClaimTypes.Name,
RoleClaimType = JwtClaimTypes.Role
};
});
services.AddAuthorization();
但是这样,Bearer认证就不起作用了。由于默认方案:DefaultChallengeScheme、DefaultAuthenticateScheme。
如何定义多种认证方案?
最佳答案
这是我在 ASP.NET 2.0 中使用 JWT token 对网页进行身份验证的示例
您可以找到我使用的语法,即使它没有包含您的所有需求,我希望它会对您有所帮助。
Asp Net Core
第一步是编写配置 Jwt 身份验证的方法:
// Configure authentication with JWT (Json Web Token).
public void ConfigureJwtAuthService(IServiceCollection services)
{
// Enable the use of an [Authorize(AuthenticationSchemes =
// JwtBearerDefaults.AuthenticationScheme)]
// attribute on methods and classes to protect.
services.AddAuthentication().AddJwtBearer(cfg =>
{
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.TokenValidationParameters = new TokenValidationParameters()
{
IssuerSigningKey = JwtController.SecurityKey,
ValidAudience = JwtController.Audience,
ValidIssuer = JwtController.Issuer,
// When receiving a token, check that we've signed it.
ValidateIssuerSigningKey = true,
// When receiving a token, check that it is still valid.
ValidateLifetime = true,
// This defines the maximum allowable clock skew when validating
// the lifetime. As we're creating the tokens locally and validating
// them on the same machines which should have synchronised time,
// this can be set to zero.
ClockSkew = TimeSpan.FromMinutes(0)
};
});
}
现在,在 Startup.cs 的 ConfigureServices() 方法中,我们可以调用 ConfigureJwtAuthService() 方法来配置 Jwt 身份验证。
这是完整的Startup.cs:
using System;
using Autofac;
using ExpertCodeBlogWebApp.Controllers;
using ExpertCodeBlogWebApp.Domain;
using ExpertCodeBlogWebApp.Domain.Interfaces;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.SpaServices.Webpack;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
namespace ExpertCodeBlogWebApp
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add
// services to the container.
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc();
// Configure jwt autenticazione
ConfigureJwtAuthService(services);
// Repositories
services.AddScoped<IUserRepository, UserRepository>();
// Create the Autofac container builder for dependency injection
var builder = new ContainerBuilder();
// Add any Autofac modules or registrations.
builder.RegisterModule(new AutofacModule());
// Return ServiceProvider
var serviceProvider = services.BuildServiceProvider();
return serviceProvider;
}
// Configure authentication with JWT (Json Web Token).
public void ConfigureJwtAuthService(IServiceCollection services)
{
// Enable the use of an [Authorize(AuthenticationSchemes =
// JwtBearerDefaults.AuthenticationScheme)]
// attribute on methods and classes to protect.
services.AddAuthentication().AddJwtBearer(cfg =>
{
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.TokenValidationParameters = new TokenValidationParameters()
{
IssuerSigningKey = JwtController.SecurityKey,
ValidAudience = JwtController.Audience,
ValidIssuer = JwtController.Issuer,
// When receiving a token, check that we've signed it.
ValidateIssuerSigningKey = true,
// When receiving a token, check that it is still valid.
ValidateLifetime = true,
// This defines the maximum allowable clock skew when validating
// the lifetime.
// As we're creating the tokens locally and validating them on the
// same machines which should have synchronised time, this can be
// set to zero.
ClockSkew = TimeSpan.FromMinutes(0)
};
});
}
// This method gets called by the runtime. Use this method to configure
// the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
{
HotModuleReplacement = true
});
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "Home", action = "Index" });
});
}
}
// For dependency injection.
public class AutofacModule : Module
{
// Dependency Injection with Autofact
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<UserRepository>().As<IUserRepository>()
.SingleInstance();
}
}
}
JwtController.cs
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using AutoMapper;
using ExpertCodeBlogWebApp.Domain;
using ExpertCodeBlogWebApp.Domain.Interfaces;
using ExpertCodeBlogWebApp.Domain.Models;
using ExpertCodeBlogWebApp.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
namespace ExpertCodeBlogWebApp.Controllers
{
[Route("api/[controller]")]
public class JwtController : Controller
{
#region Private Members
// JWT-related members
private TimeSpan TokenExpiration;
private SigningCredentials SigningCredentials;
// EF and Identity members, available through DI
private MyDbContext DbContext;
private IUserRepository _userRepository;
private readonly ILogger _logger;
#endregion Private Members
#region Static Members
private static readonly string PrivateKey = "my_PrivateKey";
public static readonly SymmetricSecurityKey SecurityKey =
new SymmetricSecurityKey(Encoding.ASCII.GetBytes(PrivateKey));
public static readonly string Issuer = "my_Issuer";
public static readonly string Audience = "my_Audience";
#endregion Static Members
#region Constructor
// I have used Autofac in the Startup.cs for dependency injection)
public JwtController(
MyDbContext dbContext,
IUserRepository userRepository,
ILogger<JwtController> logger)
{
_logger = logger;
_userRepository = userRepository;
// Instantiate JWT-related members
TokenExpiration = TimeSpan.FromMinutes(10);
SigningCredentials = new SigningCredentials(SecurityKey,
SecurityAlgorithms.HmacSha256);
// Instantiate through Dependency Injection with Autofact
DbContext = dbContext;
}
#endregion Constructor
#region Public Methods
// Manages the request for a new authentication or the refresh of an
// already established one
[HttpPost("token")]
public async Task<IActionResult>
Authentication([FromBody]JwtRequestViewModel jwt)
{
if (ModelState.IsValid)
{
string grantType = jwt.GrantType;
if (grantType == "password")
{
string userName = jwt.UserName;
string password = jwt.Password;
// Password check required
var user = await
_userRepository.GetUserInfoWithCheckPwd(userName, password);
// Check if user is expired (check the ExpireDate property)
if (UserExpired(user))
return BadRequest($"Account of {user.Name} expired!");
if (UserEnabled(user))
return await GenerateToken(user);
else
return BadRequest("User name or password invalid.");
}
}
else if (grantType == "refresh_token")
{
string userName = jwt.UserName;
// Refresh token (no password check required)
var user = await _userRepository.GetUserInfoByName(userName);
// Check if user is expired (check the ExpireDate property)
if (UserExpired(user))
return BadRequest($"Account of {user.Name} expired!");
string token = jwt.Token;
if (token == user.Token)
{
// Generate token and send it via a json-formatted string
return await GenerateToken(user);
}
else
{
return BadRequest("User token invalid.");
}
}
else
return BadRequest("Authentication type invalid.");
}
else
return BadRequest("Request invalid.");
}
#endregion Public Methods
#region Private Methods
private bool UserExpired(Users utente)
{
if (utente != null)
return utente.ExpireDate.CompareTo(DateTime.Now) < 0;
return true;
}
private bool UserEnabled(Users utente)
{
if (utente != null)
return utente.Enabled == true;
return false;
}
private JsonSerializerSettings DefaultJsonSettings
{
get
{
return new JsonSerializerSettings()
{
Formatting = Formatting.Indented
};
}
}
private async Task<IActionResult> GenerateToken(Users user)
{
try
{
if (user != null)
{
var handler = new JwtSecurityTokenHandler();
DateTime newTokenExpiration = DateTime.Now.Add(TokenExpiration);
ClaimsIdentity identity = new ClaimsIdentity(
new GenericIdentity(user.Name, "TokenAuth"),
new[] { new Claim("ID", user.Id.ToString())}
);
var securityToken = handler.CreateToken(new SecurityTokenDescriptor
{
Issuer = JwtController.Issuer,
Audience = JwtController.Audience,
SigningCredentials = SigningCredentials,
Subject = identity,
Expires = newTokenExpiration
});
string encodedToken = handler.WriteToken(securityToken);
// Update token data on database
await _userRepository.UpdateTokenData(user.Name, encodedToken,
newTokenExpiration);
// Build the json response
// (I use Automapper to maps an object into another object)
var jwtResponse = Mapper.Map<JwtResponseViewModel>(user);
jwtResponse.AccessToken = encodedToken;
jwtResponse.Expiration = (int)TokenExpiration.TotalSeconds;
return Ok(jwtResponse);
}
return NotFound();
}
catch(Exception e)
{
return BadRequest(e.Message);
}
}
#endregion
}
}
在我的项目中我使用 Angular。通过 Angular 调用 JwtController 方法:
login(userName: string, password: string)
{
return this.getLoginEndpoint(userName, password)
.map((response: Response) => this.processLoginResponse(response));
}
getLoginEndpoint(userName: string, password: string): Observable<Response>
{
// Body
// JwtRequest is a model class that I use to send info to the controller
let jwt = new JwtRequest();
jwt.GrantType = "password";
jwt.UserName = userName;
jwt.Password = password;
jwt.ClientId = "my_Issuer";
// Post requiest (I use getAuthHeader that attach to the header the
// authentication token, but it can also be omitted because it is ignored
// by the JwtController
return this.http.post(this.loginUrl, JSON.stringify(jwt),
this.getAuthHeader(true))
}
protected getAuthHeader(includeJsonContentType?: boolean): RequestOptions
{
// Hera I use this.authService.accessToken that is a my service where
// I have store the token received from the server
let headers = new Headers({
'Authorization': 'Bearer ' + this.authService.accessToken });
if (includeJsonContentType)
headers.append("Content-Type", "application/json");
headers.append("Accept", `application/vnd.iman.v01+json,
application/json, text/plain, */*`);
headers.append("App-Version", "01");
return new RequestOptions({ headers: headers });
}
private processLoginResponse(response: Response)
{
// process the response..
}
在您希望仅由经过身份验证的用户访问的 Controller 类(或方法)上(不是在您的 JwtController 上,因为它的方法必须由所有用户访问),您可以设置:
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
要从 Angular 调用需要身份验证的 Controller 方法,您需要使用 getAuthHeader() 方法将 token 附加到 header 中。
希望这篇文章可以帮助到您。
关于identityserver3 - asp .net core 2.0中的多种身份验证方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46691485/
我想做的是让 JTextPane 在 JPanel 中占用尽可能多的空间。对于我使用的 UpdateInfoPanel: public class UpdateInfoPanel extends JP
我在 JPanel 中有一个 JTextArea,我想将其与 JScrollPane 一起使用。我正在使用 GridBagLayout。当我运行它时,框架似乎为 JScrollPane 腾出了空间,但
我想在 xcode 中实现以下功能。 我有一个 View Controller 。在这个 UIViewController 中,我有一个 UITabBar。它们下面是一个 UIView。将 UITab
有谁知道Firebird 2.5有没有类似于SQL中“STUFF”函数的功能? 我有一个包含父用户记录的表,另一个表包含与父相关的子用户记录。我希望能够提取用户拥有的“ROLES”的逗号分隔字符串,而
我想使用 JSON 作为 mirth channel 的输入和输出,例如详细信息保存在数据库中或创建 HL7 消息。 简而言之,输入为 JSON 解析它并输出为任何格式。 最佳答案 var objec
通常我会使用 R 并执行 merge.by,但这个文件似乎太大了,部门中的任何一台计算机都无法处理它! (任何从事遗传学工作的人的附加信息)本质上,插补似乎删除了 snp ID 的 rs 数字,我只剩
我有一个以前可能被问过的问题,但我很难找到正确的描述。我希望有人能帮助我。 在下面的代码中,我设置了varprice,我想添加javascript变量accu_id以通过rails在我的数据库中查找记
我有一个简单的 SVG 文件,在 Firefox 中可以正常查看 - 它的一些包装文本使用 foreignObject 包含一些 HTML - 文本包装在 div 中:
所以我正在为学校编写一个 Ruby 程序,如果某个值是 1 或 3,则将 bool 值更改为 true,如果是 0 或 2,则更改为 false。由于我有 Java 背景,所以我认为这段代码应该有效:
我做了什么: 我在这些账户之间创建了 VPC 对等连接 互联网网关也连接到每个 VPC 还配置了路由表(以允许来自双方的流量) 情况1: 当这两个 VPC 在同一个账户中时,我成功测试了从另一个 La
我有一个名为 contacts 的表: user_id contact_id 10294 10295 10294 10293 10293 10294 102
我正在使用 Magento 中的新模板。为避免重复代码,我想为每个产品预览使用相同的子模板。 特别是我做了这样一个展示: $products = Mage::getModel('catalog/pro
“for”是否总是检查协议(protocol)中定义的每个函数中第一个参数的类型? 编辑(改写): 当协议(protocol)方法只有一个参数时,根据该单个参数的类型(直接或任意)找到实现。当协议(p
我想从我的 PHP 代码中调用 JavaScript 函数。我通过使用以下方法实现了这一点: echo ' drawChart($id); '; 这工作正常,但我想从我的 PHP 代码中获取数据,我使
这个问题已经有答案了: Event binding on dynamically created elements? (23 个回答) 已关闭 5 年前。 我有一个动态表单,我想在其中附加一些其他 h
我正在尝试找到一种解决方案,以在 componentDidMount 中的映射项上使用 setState。 我正在使用 GraphQL连同 Gatsby返回许多 data 项目,但要求在特定的 pat
我在 ScrollView 中有一个 View 。只要用户按住该 View ,我想每 80 毫秒调用一次方法。这是我已经实现的: final Runnable vibrate = new Runnab
我用 jni 开发了一个 android 应用程序。我在 GetStringUTFChars 的 dvmDecodeIndirectRef 中得到了一个 dvmabort。我只中止了一次。 为什么会这
当我到达我的 Activity 时,我调用 FragmentPagerAdapter 来处理我的不同选项卡。在我的一个选项卡中,我想显示一个 RecyclerView,但他从未出现过,有了断点,我看到
当我按下 Activity 中的按钮时,会弹出一个 DialogFragment。在对话框 fragment 中,有一个看起来像普通 ListView 的 RecyclerView。 我想要的行为是当
我是一名优秀的程序员,十分优秀!