/// <summary> /// In order to ensure that the Web API only accepts tokens from tenants where it has been consented and provisioned, a token that /// has neither Roles nor Scopes claims should be rejected. To enforce that rule, add an event handler to the beginning of the /// <see cref="JwtBearerEvents.OnTokenValidated"/> handler chain that rejects tokens that don't meet the rules. /// </summary> /// <param name="events">The <see cref="JwtBearerEvents"/> object to modify.</param> /// <param name="jwtBearerScheme">The JWT bearer scheme name to be used. By default it uses "Bearer".</param> internal static void ChainOnTokenValidatedEventForClaimsValidation(JwtBearerEvents events, string jwtBearerScheme) { var tokenValidatedHandler = events.OnTokenValidated; events.OnTokenValidated = async context => { if (!context !.Principal !.Claims.Any(x => x.Type == ClaimConstants.Scope || x.Type == ClaimConstants.Scp || x.Type == ClaimConstants.Roles || x.Type == ClaimConstants.Role)) { context.Fail(string.Format(CultureInfo.InvariantCulture, IDWebErrorMessage.NeitherScopeOrRolesClaimFoundInToken, jwtBearerScheme)); } await tokenValidatedHandler(context).ConfigureAwait(false); }; }
/// <summary> /// Wraps an instance of <see cref="JwtBearerEvents" /> with a behavior /// checks for a token in the query string with a name specified in the /// <paramref name="queryStringParameterName" /> parameter. /// </summary> /// <param name="inner"> /// A base <see cref="JwtBearerEvents" /> implementation that will gain /// this additional query string inspection behavior. /// </param> /// <param name="queryStringParameterName"> /// The name of the query string parameter that will be sought from requests /// in order to extract a token. /// </param> /// <exception cref="ArgumentNullException"> /// Thrown when <paramref name="inner" /> or /// <paramref name="queryStringParameterName" /> is null. /// </exception> /// <exception cref="ArgumentException"> /// Thrown when <paramref name="queryStringParameterName" /> is an invalid name /// for a query string parameter. /// </exception> public QueryStringJwtBearerEventsWrapper(JwtBearerEvents inner, string queryStringParameterName) : base(inner) { if (queryStringParameterName == null) { throw new ArgumentNullException(nameof(queryStringParameterName)); } else if (String.IsNullOrWhiteSpace(queryStringParameterName)) { throw new ArgumentException( $"The '{nameof(queryStringParameterName)}' cannot be null or whitespace.", nameof(queryStringParameterName) ); } this.QueryStringParameterName = queryStringParameterName; }
private void AddAutheticationAndAuthorization(IServiceCollection services) { var tokenValidationParameters = new TokenValidationParameters() { ValidIssuer = Configuration["Tokens:Issuer"], ValidAudience = Configuration["Tokens:Audience"], ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"])), ValidateLifetime = true }; var logger = LoggerFactory.CreateLogger("Jwt events logger"); var tokenEvents = new JwtBearerEvents { OnAuthenticationFailed = context => { logger.LogInformation("OnAuthenticationFailed: " + context.Exception.Message); return(Task.CompletedTask); }, OnTokenValidated = context => { logger.LogInformation("OnTokenValidated: " + context.SecurityToken); return(Task.CompletedTask); } }; services.AddIdentity <SystemUser, IdentityRole>() .AddEntityFrameworkStores <ToggleContext>(); services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(o => { o.Audience = Configuration["Tokens:Audience"]; o.TokenValidationParameters = tokenValidationParameters; o.Events = tokenEvents; }); services.AddAuthorization(cfg => { cfg.AddPolicy("Administrators", p => p.RequireClaim("SuperUser", "True")); }); }
/// <summary> /// Subscribes to all the JwtBearer events, to help debugging, while /// preserving the previous handlers (which are called). /// </summary> /// <param name="events">Events to subscribe to.</param> /// <returns><see cref="JwtBearerEvents"/> for chaining.</returns> public JwtBearerEvents Subscribe(JwtBearerEvents events) { events ??= new JwtBearerEvents(); s_onAuthenticationFailed = events.OnAuthenticationFailed; events.OnAuthenticationFailed = OnAuthenticationFailedAsync; s_onMessageReceived = events.OnMessageReceived; events.OnMessageReceived = OnMessageReceivedAsync; s_onTokenValidated = events.OnTokenValidated; events.OnTokenValidated = OnTokenValidatedAsync; s_onChallenge = events.OnChallenge; events.OnChallenge = OnChallengeAsync; return(events); }
private void ConfigureAuthService(IServiceCollection services) { // prevent from mapping "sub" claim to nameidentifier. JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); var identityAuthority = Configuration.GetValue <string>("IdentityAuthority"); var audience = Configuration.GetValue <string>("IdentityAudience"); services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(options => { var events = new JwtBearerEvents(); events.OnChallenge = (context) => { return(Task.FromResult(0)); }; events.OnAuthenticationFailed = (context) => { return(Task.FromResult(0)); }; events.OnForbidden = (context) => { return(Task.FromResult(0)); }; events.OnTokenValidated = (context) => { return(Task.FromResult(0)); }; events.OnMessageReceived = (context) => { return(Task.FromResult(0)); }; options.Events = events; options.Authority = identityAuthority; options.TokenValidationParameters.ValidAudience = audience; }); //services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) // .AddMicrosoftIdentityWebApi(options => // { // Configuration.Bind("AzureAdB2C", options); // options.TokenValidationParameters.NameClaimType = "name"; // }, // options => { // Configuration.Bind("AzureAdB2C", options); // }); }
public static IServiceCollection AddTokenAuthentication( this IServiceCollection services, IConfiguration configuration, JwtBearerEvents events = null) { var secret = configuration .GetSection(nameof(ApplicationSettings)) .GetValue <string>(nameof(ApplicationSettings.Secret)); var key = Encoding.ASCII.GetBytes(secret); IdentityModelEventSource.ShowPII = true; services .AddAuthentication(authentication => { authentication.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; authentication.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(bearer => { bearer.RequireHttpsMetadata = false; bearer.SaveToken = true; bearer.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(key), ValidateIssuer = false, ValidateAudience = false }; if (events != null) { bearer.Events = events; } }); services.AddHttpContextAccessor(); services.AddScoped <ICurrentUserService, CurrentUserService>(); return(services); }
/// <summary> /// Subscribes to all the JwtBearer events, to help debugging, while /// preserving the previous handlers (which are called) /// </summary> /// <param name="events">Events to subscribe to</param> public static JwtBearerEvents Subscribe(JwtBearerEvents events) { if (events == null) { events = new JwtBearerEvents(); } onAuthenticationFailed = events.OnAuthenticationFailed; events.OnAuthenticationFailed = OnAuthenticationFailed; onMessageReceived = events.OnMessageReceived; events.OnMessageReceived = OnMessageReceived; onTokenValidated = events.OnTokenValidated; events.OnTokenValidated = OnTokenValidated; onChallenge = events.OnChallenge; events.OnChallenge = OnChallenge; return(events); }
private static JwtBearerEvents buildStackedEventHandler <T>(JwtBearerEvents events, Action <Func <T, Task> > setEvent, params Func <T, Task>[] eventContextHandler) where T : ResultContext <JwtBearerOptions> { setEvent(async(context) => { foreach (var handler in eventContextHandler) { if (handler != null) { await handler.Invoke(context); } // We want to break if result has been set. if (context.Result != null) { break; } } }); return(events); }
public void Constructor_WithCustomQueryStringParameterName_InvalidParameterName( string queryStringParameterName) { // Arrange var inner = new JwtBearerEvents(); // Act var exception = Record.Exception( () => new QueryStringJwtBearerEventsWrapper(inner, queryStringParameterName) ); // Assert Assert.IsType <ArgumentException>(exception); Assert.Equal( $"The 'queryStringParameterName' cannot be null or whitespace." + Environment.NewLine + "Parameter name: queryStringParameterName", exception.Message ); }
protected override JwtBearerEvents CreateJwtBearerEvents(JwtBearerEvents inner) { return(this.CreateQueryStringJwtBearerEvents(inner)); }
public static JwtBearerEvents WhenTokenValidated(this JwtBearerEvents events, params Func <TokenValidatedContext, Task>[] tokenValidatedContextHandler) => buildStackedEventHandler(events, eventContextHandler => events.OnTokenValidated = eventContextHandler, tokenValidatedContextHandler);
public static JwtBearerEvents WhenMessageReceived(this JwtBearerEvents events, params Func <MessageReceivedContext, Task>[] messageReceivedContextHandler) => buildStackedEventHandler(events, eventContextHandler => events.OnMessageReceived = eventContextHandler, messageReceivedContextHandler);
private static void CreateJwtBearerOptions(JwtBearerOptions o, string issuer, SymmetricSecurityKey signingKey, IHostingEnvironment environment, JwtBearerEvents events) { if (environment.IsDevelopment()) { o.RequireHttpsMetadata = false; } o.Audience = issuer; o.Authority = null; if (events != null) { o.Events = events; } o.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = issuer, ValidateAudience = true, ValidAudience = issuer, ValidateIssuerSigningKey = true, IssuerSigningKey = signingKey, RequireExpirationTime = true, ValidateLifetime = true, ClockSkew = TimeSpan.Zero, NameClaimType = ClaimTypes.NameIdentifier }; }
/// <summary> /// 权限控制核心,即必须的配置 /// </summary> /// <param name="services"></param> /// <param name="action"></param> public static void AddCorePermission(this IServiceCollection services, Action <PermissionOptions> action) { services.AddSingleton <IToken, Token>(); #region 身份验证 var permissionOption = new PermissionOptions(); action(permissionOption); //addAuthentication不放到AddPermissionCore方法里,是为了外部可自己配置 // 当未通过authenticate时(如无token或是token出错时),会返回401,当通过了authenticate但没通过authorize时,会返回403。 services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie( CookieAuthenticationDefaults.AuthenticationScheme, options => { //下面的委托方法只会在第一次cookie验证时调用,调用时会用到上面的permissionOption变量,但其实permissionOption变量是在以前已经初始化的,所以在此方法调用之前,permissionOption变量不会被释放 options.Cookie.Name = "auth"; options.AccessDeniedPath = permissionOption.AccessDeniedPath; // 当403时,返回到无授权界面 options.LoginPath = permissionOption.LoginPath; // 当401时,返回到登录界面,会自动在url后加上returnUrl=xxx options.ExpireTimeSpan = permissionOption.ExpireTimeSpan != default ? permissionOption.ExpireTimeSpan : new TimeSpan(12, 0, 0); options.ForwardDefaultSelector = context => { string authorization = context.Request.Headers["Authorization"]; //身份验证的顺序为jwt、cookie if (authorization != null && authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) { return(JwtBearerDefaults.AuthenticationScheme); } else { return(CookieAuthenticationDefaults.AuthenticationScheme); } }; var cookieAuthenticationEvents = new CookieAuthenticationEvents { OnSignedIn = context => { return(Task.CompletedTask); }, OnSigningOut = context => { return(Task.CompletedTask); } }; options.Events = cookieAuthenticationEvents; }) .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => { // jwt可用对称和非对称算法进行验签 SecurityKey key; if (permissionOption.IsAsymmetric) { key = new RsaSecurityKey(RSAHelper.GetRSAParametersFromFromPublicPem(permissionOption.RsaPublicKey)); } else { key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(permissionOption.SymmetricSecurityKey)); } options.TokenValidationParameters = new TokenValidationParameters() { NameClaimType = PermissionConstant.userIdClaim, RoleClaimType = PermissionConstant.roleIdsClaim, ValidIssuer = permissionOption.Issuer, ValidAudience = permissionOption.Audience, IssuerSigningKey = key, ValidateIssuer = false, ValidateAudience = false }; var jwtBearerEvents = new JwtBearerEvents { OnMessageReceived = context => { return(Task.CompletedTask); }, OnTokenValidated = context => { return(Task.CompletedTask); }, OnAuthenticationFailed = context => { return(Task.CompletedTask); } }; options.Events = jwtBearerEvents; }); #endregion #region 授权 //权限控制只要在配置IServiceCollection,不需要额外配置app管道 //权限控制参考:https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-2.2 //handler和requirement有几种关系:1 handler对多requirement(此时handler实现IAuthorizationHandler);1对1(实现AuthorizationHandler<PermissionRequirement>),和多对1 //所有的handler都要注入到services,用services.AddSingleton<IAuthorizationHandler, xxxHandler>(),而哪个requirement用哪个handler,低层会自动匹配。最后将requirement对到policy里即可 services.AddAuthorization(options => { // 增加鉴权策略,并告知这个策略要判断用户是否获得了PermissionRequirement这个Requirement options.AddPolicy(PermissionConstant.PermissionAuthorizePolicy, policyBuilder => { policyBuilder.AddRequirements(new PermissionRequirement()); }); //options.AddPolicy(PermissionConstant.OnlyAuthenticationPolicy, policyBuilder => // { // policyBuilder.AddRequirements(new OnlyAuthenticationRequirement()); // }); }); services.AddScoped <IAuthorizationHandler, PermissionRequirementHandler>(); services.AddMemoryCache(); services.TryAddScoped <IApplicationContext, ApplicationContext>(); services.AddHttpContextAccessor(); services.Configure(action); #endregion }
public static JwtBearerOptions WithEventsProcessor(this JwtBearerOptions options, JwtBearerEvents eventsProcessor) { if (options == null) { throw new ArgumentNullException(nameof(options)); } if (eventsProcessor == null) { throw new ArgumentNullException(nameof(eventsProcessor)); } options.Events = eventsProcessor; return(options); }
internal void ConfigureJwtBearer(JwtBearerOptions jwtOptions) { jwtOptions.Authority = Authority; jwtOptions.RequireHttpsMetadata = RequireHttpsMetadata; jwtOptions.BackchannelTimeout = BackChannelTimeouts; jwtOptions.RefreshOnIssuerKeyNotFound = true; jwtOptions.SaveToken = SaveToken; jwtOptions.Events = new JwtBearerEvents { OnMessageReceived = e => { e.Token = InternalTokenRetriever(e.Request); return(JwtBearerEvents.MessageReceived(e)); }, OnTokenValidated = e => JwtBearerEvents.TokenValidated(e), OnAuthenticationFailed = e => JwtBearerEvents.AuthenticationFailed(e), OnChallenge = e => JwtBearerEvents.Challenge(e) }; if (DiscoveryDocumentRefreshInterval.HasValue) { var parsedUrl = DiscoveryClient.ParseUrl(Authority); var httpClient = new HttpClient(JwtBackChannelHandler ?? new HttpClientHandler()) { Timeout = BackChannelTimeouts, MaxResponseContentBufferSize = 1024 * 1024 * 10 // 10 MB }; var manager = new ConfigurationManager <OpenIdConnectConfiguration>( parsedUrl.Url, new OpenIdConnectConfigurationRetriever(), new HttpDocumentRetriever(httpClient) { RequireHttps = RequireHttpsMetadata }) { AutomaticRefreshInterval = DiscoveryDocumentRefreshInterval.Value }; jwtOptions.ConfigurationManager = manager; } if (JwtBackChannelHandler != null) { jwtOptions.BackchannelHttpHandler = JwtBackChannelHandler; } // if API name is set, do a strict audience check for if (!string.IsNullOrWhiteSpace(ApiName) && !LegacyAudienceValidation) { jwtOptions.Audience = ApiName; } else { // no audience validation, rely on scope checks only jwtOptions.TokenValidationParameters.ValidateAudience = false; } jwtOptions.TokenValidationParameters.NameClaimType = NameClaimType; jwtOptions.TokenValidationParameters.RoleClaimType = RoleClaimType; if (TokenDecryptionKey != null) { jwtOptions.TokenValidationParameters.TokenDecryptionKey = TokenDecryptionKey; } else if (!string.IsNullOrWhiteSpace(CertificateThumbprint)) { var certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine); certStore.Open(OpenFlags.ReadOnly); var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, CertificateThumbprint, true); if (certCollection.Count == 0) { throw new Exception("CertificateNotFound"); } var certificate = certCollection[0]; jwtOptions.TokenValidationParameters.TokenDecryptionKey = new X509SecurityKey(certificate); } jwtOptions.TokenValidationParameters.RequireSignedTokens = RequireSignedTokens; jwtOptions.TokenValidationParameters.ValidateIssuer = ValidateIssuer; if (JwtValidationClockSkew.HasValue) { jwtOptions.TokenValidationParameters.ClockSkew = JwtValidationClockSkew.Value; } if (InboundJwtClaimTypeMap != null) { var handler = new JwtSecurityTokenHandler { InboundClaimTypeMap = InboundJwtClaimTypeMap }; jwtOptions.SecurityTokenValidators.Clear(); jwtOptions.SecurityTokenValidators.Add(handler); } }
/// <summary> /// /// </summary> /// <param name="services"></param> /// <param name="name"></param> /// <param name="configuration"></param> /// <param name="events"></param> public static void AddAzureAdAuthentication(this IServiceCollection services, IConfiguration configuration, JwtBearerEvents events = null, string sectionName = "AzureAdAuth") { var azureAdAuth = new AzureAdAuth(); configuration.Bind(sectionName, azureAdAuth); services.AddAuthentication(sharedoptions => { sharedoptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.Authority = azureAdAuth.Authority; options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters { ValidAudiences = azureAdAuth.ValidAudiences, ValidIssuers = azureAdAuth.ValidIssuers }; if (events != null) { options.Events = events; } }); services.AddScoped <ITokenService, TokenService>(); }
public static void AddJwtBearerAuthentication(this IServiceCollection serviceCollection, IConfiguration configuration, Action <JwtBearerOptions> configureOptions = null, JwtBearerEvents bearerEvents = null) { configuration.GetSection("TokenConfig").Bind(_tokenConfig); var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(_tokenConfig.TokenSigningKey)); if (configureOptions == null) { configureOptions = options => { options.TokenValidationParameters = new TokenValidationParameters { ValidAudience = "*", ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuers = _tokenConfig.TokenIssuers, IssuerSigningKeys = new[] { signingKey } }; if (bearerEvents != null) { options.Events = bearerEvents; } else { options.Events = new JwtBearerEvents { OnMessageReceived = OnMessageReceived, OnTokenValidated = TokenValidated } }; }; } serviceCollection.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(configureOptions); }
//oauth 2 public void ConfigureJwtAuthService(IServiceCollection services) { var audienceConfig = Configuration.GetSection("Audience"); var symmetricKeyAsBase64 = audienceConfig["Secret"]; var signingKey = JwtSecurityKey.Create(symmetricKeyAsBase64); var tokenValidationParameters = new TokenValidationParameters { // The signing key must match! ValidateIssuerSigningKey = true, IssuerSigningKey = signingKey, // Validate the JWT Issuer (iss) claim ValidateIssuer = true, ValidIssuer = audienceConfig["Iss"], // Validate the JWT Audience (aud) claim ValidateAudience = true, ValidAudience = audienceConfig["Aud"], // Validate the token expiry ValidateLifetime = true, ClockSkew = TimeSpan.Zero, RequireExpirationTime = true, }; var jwtBearerEvents = new JwtBearerEvents { OnAuthenticationFailed = context => { var err = ""; if (context.Exception.GetType() == typeof(SecurityTokenValidationException)) { err = "invalid token"; } else if (context.Exception.GetType() == typeof(SecurityTokenInvalidIssuerException)) { err = "invalid issuer"; } else if (context.Exception.GetType() == typeof(SecurityTokenExpiredException)) { err = "token expired"; } var resp = new { error = err, status = 401 }; context.Response.WriteAsync(JsonConvert.SerializeObject(resp, Formatting.Indented)); return(Task.FromResult <object>(0)); //return Task.CompletedTask; }, OnTokenValidated = context => { return(Task.CompletedTask); }, OnMessageReceived = context => { var value = context.Request.Headers["Authorization"].ToString(); if (!string.IsNullOrEmpty(value) && value.ToLower().Contains("bearer")) { value = value.Trim().Substring(6).Trim(); } if (!string.IsNullOrEmpty(value)) { context.Token = value; } return(Task.CompletedTask); }, OnChallenge = context => { return(Task.CompletedTask); } }; services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.RequireHttpsMetadata = false; options.TokenValidationParameters = tokenValidationParameters; options.Events = jwtBearerEvents; }); }
public static void ConfigureJwt(this IServiceCollection services, IConfiguration configurationRoot, Func <JwtIssuerOptions, JwtSigningKey> signingKey, JwtBearerEvents jwtBearerEvents = null) { var jwtAppSettingOptions = configurationRoot.GetSection(nameof(JwtIssuerOptions)).Get <JwtIssuerOptions>(); var issuerSigningKey = signingKey(jwtAppSettingOptions); services.AddSingleton(issuerSigningKey); var tokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = jwtAppSettingOptions.Issuer, ValidateAudience = true, ValidAudience = jwtAppSettingOptions.Audience, ValidateIssuerSigningKey = true, IssuerSigningKey = issuerSigningKey, RequireExpirationTime = true, ValidateLifetime = true, ClockSkew = TimeSpan.Zero }; services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = tokenValidationParameters; options.Events = jwtBearerEvents ?? new JwtBearerEvents(); }); }
private static void AddAuthenticate(IServiceCollection services) { var authenticationBuilder = services.AddAuthentication(o => { o.DefaultAuthenticateScheme = jwtBearerScheme; o.DefaultChallengeScheme = jwtBearerScheme; }); authenticationBuilder.AddJwtBearer(options => { // Forward any requests to cookie scheme that not start with /api to that scheme options.ForwardDefaultSelector = ctx => ctx.Request.Path.StartsWithSegments("/api") ? null : cookieScheme; //todo: use configurations var jwtSetting = JwtSetting.Instance; options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = jwtSetting.Issuer, ValidAudience = jwtSetting.Issuer, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSetting.Key)) }; var jwtBearerEvents = new JwtBearerEvents(); options.Events = jwtBearerEvents; //测试用 => 模拟发来的Authorization: "Bearer Token" jwtBearerEvents.OnMessageReceived = context => { if (string.IsNullOrWhiteSpace(MockClientRequest.Instance.Token)) { return(Task.CompletedTask); } //模拟客户端发来的Bearer Token var theToken = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last(); if (theToken == null) { context.Request.Headers["Authorization"] = "Bearer " + MockClientRequest.Instance.Token; } context.Token = MockClientRequest.Instance.Token; return(Task.CompletedTask); }; }); authenticationBuilder.AddCookie(cookieScheme, options => { // Forward any requests that start with /api to that scheme options.ForwardDefaultSelector = ctx => ctx.Request.Path.StartsWithSegments("/api") ? jwtBearerScheme : null; //todo: use configurations var cookieSetting = CookieSetting.Instance; options.ExpireTimeSpan = cookieSetting.ExpireTimeSpan; options.LoginPath = cookieSetting.LoginPath; options.LogoutPath = cookieSetting.LogoutPath; options.AccessDeniedPath = cookieSetting.AccessDeniedPath; }); }
private QueryStringJwtBearerEventsWrapper CreateQueryStringJwtBearerEvents( JwtBearerEvents inner) { return(new QueryStringJwtBearerEventsWrapper(inner)); }
public void WithEventsProcessorShouldValidateInput(JwtBearerOptions options, JwtBearerEvents eventsProcessor) { Assert.Throws <ArgumentNullException>(() => options.WithEventsProcessor(eventsProcessor)); }
/// <summary> /// 使用 JWT 认证。 /// </summary> /// <param name="app">项目构建器。</param> /// <param name="events">认证配置。</param> /// <returns></returns> public static IApplicationBuilder UseJwtBearer(this IApplicationBuilder app, JwtBearerEvents events) { if (events is null) { throw new ArgumentNullException(nameof(events)); } return(app.Use(next => { return context => { var receivedContext = new MessageReceivedContext(context); events.MessageReceived(receivedContext); if (string.IsNullOrEmpty(receivedContext.Token)) { #if NET40 next.Invoke(context); return; #else return next.Invoke(context); #endif } var tokenValidateContext = new TokenValidateContext(receivedContext); events.TokenValidate(tokenValidateContext); if (tokenValidateContext.UserData is null || tokenValidateContext.UserData.Count == 0) { #if NET40 next.Invoke(context); return; #else return next.Invoke(context); #endif } var tokenValidatedContext = new TokenValidatedContext(tokenValidateContext); events.TokenValidated(tokenValidatedContext); if (tokenValidatedContext.User?.Identity?.IsAuthenticated ?? false) { context.User = tokenValidatedContext.User; #if NET40 Thread.CurrentPrincipal = tokenValidatedContext.User; #endif } #if NET40 next.Invoke(context); return; #else return next.Invoke(context); #endif }; })); }
public static void ConfigureJwt(this IServiceCollection services, IConfiguration configurationRoot, Func <JwtIssuerOptions, JwtSigningKey> signingKey, JwtBearerEvents jwtBearerEvents = null) { var jwtAppSettingOptions = configurationRoot.GetSection(nameof(JwtIssuerOptions)).Get <JwtIssuerOptions>(); var issuerSigningKey = signingKey(jwtAppSettingOptions); services.AddSingleton(issuerSigningKey); var tokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = jwtAppSettingOptions.Issuer, ValidateAudience = true, ValidAudience = jwtAppSettingOptions.Audience, ValidateIssuerSigningKey = true, IssuerSigningKey = issuerSigningKey, RequireExpirationTime = true, ValidateLifetime = true, ClockSkew = TimeSpan.Zero }; services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.RequireHttpsMetadata = false; options.TokenValidationParameters = tokenValidationParameters; options.Events = new JwtBearerEvents { OnMessageReceived = context => { var task = Task.Run(() => { if (context.Request.Query.TryGetValue("securityToken", out var securityToken)) { context.Token = securityToken.FirstOrDefault(); } }); return(task); } }; }); }
//oauth 2 public void ConfigureJwtAuthService(IServiceCollection services) { var audienceConfig = Configuration.GetSection("Audience"); var symmetricKeyAsBase64 = audienceConfig["Secret"]; var signingKey = JwtSecurityKey.Create(symmetricKeyAsBase64); var tokenValidationParameters = new TokenValidationParameters { // The signing key must match! ValidateIssuerSigningKey = true, IssuerSigningKey = signingKey, // Validate the JWT Issuer (iss) claim ValidateIssuer = true, ValidIssuer = audienceConfig["Iss"], // Validate the JWT Audience (aud) claim ValidateAudience = true, ValidAudience = audienceConfig["Aud"], // Validate the token expiry ValidateLifetime = true, ClockSkew = TimeSpan.Zero, RequireExpirationTime = true }; var jwtBearerEvents = new JwtBearerEvents { OnAuthenticationFailed = context => { return(Task.CompletedTask); }, OnTokenValidated = context => { return(Task.CompletedTask); }, OnMessageReceived = context => { var value = context.Request.Headers["Authorization"].ToString(); if (!string.IsNullOrEmpty(value) && value.ToLower().Contains("bearer")) { value = value.Trim().Substring(6).Trim(); } if (!string.IsNullOrEmpty(value)) { context.Token = value; } return(Task.CompletedTask); }, OnChallenge = context => { return(Task.CompletedTask); } }; services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.RequireHttpsMetadata = false; options.TokenValidationParameters = tokenValidationParameters; options.Events = jwtBearerEvents; }); }
protected abstract JwtBearerEvents CreateJwtBearerEvents(JwtBearerEvents inner);
/// <summary> /// Adds a JwtBearerOptions and JwtTokenFactory instance to the IServiceCollection /// </summary> /// <param name="serviceCollection"></param> /// <param name="issuer">The Issuer field for the JWTs</param> /// <param name="secretKey">The secret key to be used to sign and validate JWTs. Should be big and kept secret</param> /// <param name="environment"></param> /// <param name="events">Optionally, you can provide an events object so you can handle JWT related events</param> public static void AddJwtServices(this IServiceCollection serviceCollection, string issuer, string secretKey, IHostingEnvironment environment, JwtBearerEvents events = null) { var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey)); var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256); serviceCollection.Add(ServiceDescriptor.Singleton(new JwtTokenFactory(issuer, signingCredentials))); serviceCollection.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(o => CreateJwtBearerOptions(o, issuer, signingKey, environment, events)); }
internal void ConfigureJwtBearer(JwtBearerOptions jwtOptions) { jwtOptions.Authority = Authority; jwtOptions.RequireHttpsMetadata = RequireHttpsMetadata; jwtOptions.BackchannelTimeout = BackChannelTimeouts; jwtOptions.RefreshOnIssuerKeyNotFound = true; jwtOptions.SaveToken = SaveToken; jwtOptions.Events = new JwtBearerEvents { OnMessageReceived = e => { e.Token = InternalTokenRetriever(e.Request); return(JwtBearerEvents.MessageReceived(e)); }, OnTokenValidated = e => JwtBearerEvents.TokenValidated(e), OnAuthenticationFailed = e => JwtBearerEvents.AuthenticationFailed(e), OnChallenge = e => JwtBearerEvents.Challenge(e) }; if (DiscoveryDocumentRefreshInterval.HasValue) { var parsedUrl = DiscoveryEndpoint.ParseUrl(Authority); var httpClient = new HttpClient(JwtBackChannelHandler ?? new HttpClientHandler()) { Timeout = BackChannelTimeouts, MaxResponseContentBufferSize = 1024 * 1024 * 10 // 10 MB }; var manager = new ConfigurationManager <OpenIdConnectConfiguration>( parsedUrl.Url, new OpenIdConnectConfigurationRetriever(), new HttpDocumentRetriever(httpClient) { RequireHttps = RequireHttpsMetadata }) { AutomaticRefreshInterval = DiscoveryDocumentRefreshInterval.Value }; jwtOptions.ConfigurationManager = manager; } if (JwtBackChannelHandler != null) { jwtOptions.BackchannelHttpHandler = JwtBackChannelHandler; } // if API name is set, do a strict audience check for if (!string.IsNullOrWhiteSpace(ApiName) && !LegacyAudienceValidation) { jwtOptions.Audience = ApiName; } else { // no audience validation, rely on scope checks only jwtOptions.TokenValidationParameters.ValidateAudience = false; } jwtOptions.TokenValidationParameters.NameClaimType = NameClaimType; jwtOptions.TokenValidationParameters.RoleClaimType = RoleClaimType; if (JwtValidationClockSkew.HasValue) { jwtOptions.TokenValidationParameters.ClockSkew = JwtValidationClockSkew.Value; } if (InboundJwtClaimTypeMap != null) { var handler = new JwtSecurityTokenHandler { InboundClaimTypeMap = InboundJwtClaimTypeMap }; jwtOptions.SecurityTokenValidators.Clear(); jwtOptions.SecurityTokenValidators.Add(handler); } }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddIdentity <IdentityUser, IdentityRole>().AddEntityFrameworkStores <ConduitDbContext>().AddDefaultTokenProviders(); services.Configure <IdentityOptions>(options => { options.User.RequireUniqueEmail = true; }); JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); TokenValidationParameters tokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = Configuration["Jwt:Issuer"], ValidAudience = Configuration["Jwt:Issuer"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"])) }; JwtBearerEvents events = new JwtBearerEvents() { OnMessageReceived = context => { string auth = context.Request.Headers["Authorization"]; if (auth?.StartsWith("Token ", StringComparison.OrdinalIgnoreCase) ?? false) { context.Request.Headers["Authorization"] = "Bearer " + auth.Substring("Token ".Length).Trim(); } return(Task.CompletedTask); } }; services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.TokenValidationParameters = tokenValidationParameters; options.Events = events; options.IncludeErrorDetails = true; }) .AddJwtBearer("Token", options => { options.TokenValidationParameters = tokenValidationParameters; options.Events = events; options.IncludeErrorDetails = true; }); services.AddDbContext <ConduitDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("ConduitDB"))); services.AddMvc(); services.AddAuthorization(options => { options.AddPolicy("ValidUsername", policy => policy.Requirements.Add(new ValidUsernameRequirement())); }); services.AddScoped <IAuthorizationHandler, ValidJWTAuthorizationHandler>(); //Custom services services.AddScoped <IArticleService, ArticleService>(); services.AddScoped <ICommentService, CommentService>(); services.AddScoped <IProfileService, ProfileService>(); services.AddScoped <IUserService, UserService>(); //Custom repositories services.AddScoped <IArticleRepository, ArticleRepository>(); services.AddScoped <IArticleTagsRepository, ArticleTagsRepository>(); services.AddScoped <ICommentRepository, CommentRepository>(); services.AddScoped <IFavoriteArticleRepository, FavoriteArticleRepository>(); services.AddScoped <ITagsRepository, TagsRepository>(); services.AddScoped <IUserIsFollowingRepository, UserIsFollowingRepository>(); services.AddScoped <IUserPersonalizationRepository, UserPersonalizationRepository>(); }