static void Main(string[] args) { string keyDir = AppDomain.CurrentDomain.BaseDirectory; if (RSAUtils.TryGetKeyParameters(keyDir, true, out RSAParameters keyParams) == false) { Console.WriteLine("按任意键开始生产RSAKey文件。"); Console.Read(); keyParams = RSAUtils.GenerateAndSaveKey(keyDir); Console.WriteLine("RSAKey文件生存成功!"); } else { //Console.WriteLine("RSAKey文件已经存在!"); Console.WriteLine("生成jwtToken"); JwtTokenUtils jwtTokenUtils = new JwtTokenUtils(); string jwtToken = jwtTokenUtils.GenerateJwtToken("zhuqp", "", "pbirs"); Console.WriteLine(jwtToken); Console.WriteLine("验证jwtToken"); string username = jwtTokenUtils.ValidateJwtToken(jwtToken, "pbirs"); Console.WriteLine(username); Console.Read(); } }
// This method gets called by the runtime. Use this method to add services to the container. public IServiceProvider ConfigureServices(IServiceCollection services) { // 从文件读取密钥 string keyDir = PlatformServices.Default.Application.ApplicationBasePath; if (RSAUtils.TryGetKeyParameters(keyDir, true, out RSAParameters keyParams) == false) { keyParams = RSAUtils.GenerateAndSaveKey(keyDir); } JWTTokenOptions _tokenOptions = new JWTTokenOptions(); _tokenOptions.Key = new RsaSecurityKey(keyParams); _tokenOptions.Issuer = "EcpB2bIssuer"; // 签发者名称 _tokenOptions.Credentials = new SigningCredentials(_tokenOptions.Key, SecurityAlgorithms.RsaSha256Signature); // 添加到 IoC 容器 有可能报错 改为不是单例 services.AddSingleton(_tokenOptions); services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(jwtOptions => { jwtOptions.TokenValidationParameters = new TokenValidationParameters { IssuerSigningKey = _tokenOptions.Key, ValidAudience = _tokenOptions.Audience, ValidIssuer = _tokenOptions.Issuer, ValidateLifetime = true }; }); services.AddDataProtection(options => { options.ApplicationDiscriminator = "localhost"; }); services.ConfigureApplicationCookie(options => { options.Cookie.Domain = "localhost"; options.Cookie.Name = ".AspNetCore.Cookies"; }); services.AddMvc(); return (Util.AutofacIoc.AutofacHelp.AutofacProviderBuilderCore( services, ApplicationContainer, new B2b.ClientRegisterModuleIoc.GrpcClientModule() )); }
public static void AddSiteRegisterJwt(this IServiceCollection services, string Issuer, string audience) { // 从文件读取密钥 JWTTokenOptions _tokenOptions = new JWTTokenOptions(); string keyDir = PlatformServices.Default.Application.ApplicationBasePath; if (RSAUtils.TryGetKeyParameters(keyDir, false, out RSAParameters keyparams) == false) { _tokenOptions.Key = default(RsaSecurityKey); } else { _tokenOptions.Key = new RsaSecurityKey(keyparams); } _tokenOptions.Issuer = Issuer; // 设置签发者 _tokenOptions.Audience = audience; // 设置签收者,也就是这个应用服务器的名称 _tokenOptions.Credentials = new SigningCredentials(_tokenOptions.Key, SecurityAlgorithms.RsaSha256Signature); services.AddAuthorization(auth => { auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder() .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme) .RequireAuthenticatedUser() //.AddRequirements(new ValidJtiRequirement()) // 添加上面的验证要求 .Build()); }); // 注册验证要求的处理器,可通过这种方式对同一种要求添加多种验证 //services.AddSingleton<IAuthorizationHandler, ValidJtiHandler>(); services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(jwtOptions => { jwtOptions.TokenValidationParameters = new TokenValidationParameters { IssuerSigningKey = _tokenOptions.Key, ValidAudience = _tokenOptions.Audience, ValidIssuer = _tokenOptions.Issuer, ValidateLifetime = true }; }); }
/// <summary> /// 注入服务 /// </summary> /// <param name="services">IServiceCollection</param> /// <param name="Configuration">IConfiguration</param> public static void AddServiceSingleton(this IServiceCollection services, IConfiguration Configuration) { services.Configure <IdentityOption>(Configuration.GetSection("IdentityOption")); //var identityConfigurationSection = Configuration.GetSection("IdentityOption"); // 添加服务设置实例配置 var identity = Configuration.GetSection("IdentityOption"); #region 【读取配置】 var symmetricKeyAsBase64 = Configuration["IdentityOption:Secret"]; var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64); var signingKey = new SymmetricSecurityKey(keyByteArray); var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256); IdentityOption identityOption = new IdentityOption { Secret = Configuration["IdentityOption:Secret"], //密钥 Issuer = Configuration["IdentityOption:Issuer"], //发行者 Audience = Configuration["IdentityOption:Audience"], //令牌的观众 TokenType = Configuration["IdentityOption:TokenType"], //表示令牌类型,该值大小写不敏感,必选项,可以是bearer类型或mac类型。 Scope = Configuration["IdentityOption:Scope"], //表示权限范围,如果与客户端申请的范围一致,此项可省略 Subject = Configuration["IdentityOption:Subject"], //主题 ExpiresIn = Convert.ToInt32(Configuration["IdentityOption:ExpiresIn"]), //表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。 ClientId = Configuration["IdentityOption:ClientId"], //表示客户端的ID,必选项 ResponseType = Configuration["IdentityOption:ResponseType"], //表示授权类型,必选项,此处的值固定为"code" RedirectUri = Configuration["IdentityOption:RedirectUri"], State = Configuration["IdentityOption:State"], //表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。 SigningCredentials = signingCredentials }; #endregion #region 【客户端模式】【密码模式】 LicensingMode.SetResourceOwnerPasswordAndClientCredentials(services, identityOption); #endregion #region JWT JwtRegisteredClaimNames 方式 直接读取配置文件信息,初始化Token 需要验证的信息,如果不同在一台服务,则产生的Token与验证的Token的服务器验证信息与产生的信息要一致 var jwtKeyAsBase64 = Configuration["JWTTokenOption:Secret"]; var jwtKeyByteArray = Encoding.ASCII.GetBytes(jwtKeyAsBase64); var jwtSigningKey = new SymmetricSecurityKey(jwtKeyByteArray); var jwtSigningCredentials = new SigningCredentials(jwtSigningKey, SecurityAlgorithms.RsaSha256Signature); JWTTokenOption jwtOption = new JWTTokenOption { Issuer = Configuration["JWTTokenOption:Issuer"], //发行者 Audience = Configuration["JWTTokenOption:Audience"], //令牌的观众 ExpiresIn = Convert.ToInt32(Configuration["JWTTokenOption:ExpiresIn"]), //表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。 ClientId = Configuration["JWTTokenOption:ClientId"], //表示客户端的ID,必选项 SigningCredentials = jwtSigningCredentials }; // 从文件读取密钥 string keyDir = PlatformServices.Default.Application.ApplicationBasePath; if (RSAUtils.TryGetKeyParameters(keyDir, false, out RSAParameters keyParams) == false) { keyParams = RSAUtils.GenerateAndSaveKey(keyDir); } jwtOption.RsaSecurityKey = new RsaSecurityKey(keyParams); // 添加到 IoC 容器 // services.SigningCredentials(_tokenOptions); var tokenValidationParameters = new TokenValidationParameters { #region 面三个参数是必须 // 签名秘钥 ValidateIssuerSigningKey = true, IssuerSigningKey = jwtSigningKey, // 发行者(颁发机构) ValidateIssuer = true, ValidIssuer = jwtOption.Issuer, // 令牌的观众(颁发给谁) ValidateAudience = true, ValidAudience = jwtOption.Audience, #endregion // 是否验证Token有效期 ValidateLifetime = true, ClockSkew = TimeSpan.Zero //ClockSkew:允许的服务器时间偏移量,默认是5分钟,如果不设置,时间有效期间到了以后,5分钟之内还可以访问资源 /***********************************TokenValidationParameters的参数默认值***********************************/ // RequireSignedTokens = true, // SaveSigninToken = false, // ValidateActor = false, // 将下面两个参数设置为false,可以不验证Issuer和Audience,但是不建议这样做。 // ValidateAudience = true, // ValidateIssuer = true, // ValidateIssuerSigningKey = false, // 是否要求Token的Claims中必须包含Expires // RequireExpirationTime = true, // 允许的服务器时间偏移量 // ClockSkew = TimeSpan.FromSeconds(300),//TimeSpan.Zero // 是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比 // ValidateLifetime = true }; services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(o => { //不使用https //o.RequireHttpsMetadata = false; o.TokenValidationParameters = tokenValidationParameters; }); #endregion #region 【密码模式 OIDC】和用户有关,一般用于第三方登录 //services.AddAuthentication(options => //{ // options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; // options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; // options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; //}) // .AddCookie() // .AddOpenIdConnect(o => // { // o.ClientId = "oidc.hybrid"; // o.ClientSecret = "secret"; // // 若不设置Authority,就必须指定MetadataAddress // o.Authority = "https://oidc.faasx.com/"; // // 默认为Authority+".well-known/openid-configuration" // //o.MetadataAddress = "https://oidc.faasx.com/.well-known/openid-configuration"; // o.RequireHttpsMetadata = false; // // 使用混合流 // o.ResponseType = OpenIdConnectResponseType.CodeIdToken; // // 是否将Tokens保存到AuthenticationProperties中 // o.SaveTokens = true; // // 是否从UserInfoEndpoint获取Claims // o.GetClaimsFromUserInfoEndpoint = true; // // 在本示例中,使用的是IdentityServer,而它的ClaimType使用的是JwtClaimTypes。 // o.TokenValidationParameters.NameClaimType = "name"; //JwtClaimTypes.Name; // // 以下参数均有对应的默认值,通常无需设置。 // //o.CallbackPath = new PathString("/signin-oidc"); // //o.SignedOutCallbackPath = new PathString("/signout-callback-oidc"); // //o.RemoteSignOutPath = new PathString("/signout-oidc"); // //o.Scope.Add("openid"); // //o.Scope.Add("profile"); // //o.ResponseMode = OpenIdConnectResponseMode.FormPost; // /***********************************相关事件***********************************/ // // 未授权时,重定向到OIDC服务器时触发 // //o.Events.OnRedirectToIdentityProvider = context => Task.CompletedTask; // // 获取到授权码时触发 // //o.Events.OnAuthorizationCodeReceived = context => Task.CompletedTask; // // 接收到OIDC服务器返回的认证信息(包含Code, ID Token等)时触发 // //o.Events.OnMessageReceived = context => Task.CompletedTask; // // 接收到TokenEndpoint返回的信息时触发 // //o.Events.OnTokenResponseReceived = context => Task.CompletedTask; // // 验证Token时触发 // //o.Events.OnTokenValidated = context => Task.CompletedTask; // // 接收到UserInfoEndpoint返回的信息时触发 // //o.Events.OnUserInformationReceived = context => Task.CompletedTask; // // 出现异常时触发 // //o.Events.OnAuthenticationFailed = context => Task.CompletedTask; // // 退出时,重定向到OIDC服务器时触发 // //o.Events.OnRedirectToIdentityProviderForSignOut = context => Task.CompletedTask; // // OIDC服务器退出后,服务端回调时触发 // //o.Events.OnRemoteSignOut = context => Task.CompletedTask; // // OIDC服务器退出后,客户端重定向时触发 // //o.Events.OnSignedOutCallbackRedirect = context => Task.CompletedTask; //}); #endregion //注册简单的定时任务执行 //services.AddSingleton<Microsoft.Extensions.Hosting.IHostedService, MainService>(); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddDbContext <CrazyBullDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Conn"))); services.AddScoped <CrazyBullDbContext>(); services.AddScoped <ICategoryService, CategoryService>(); services.AddScoped(typeof(IRepository <>), typeof(Repository <>)); // Add framework services. services.AddMvc(); // Register the Swagger generator, defining one or more Swagger documents services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" }); //添加header过滤器 c.OperationFilter <HttpHeaderOperation>(); //Set the comments path for the swagger json and ui. var basePath = PlatformServices.Default.Application.ApplicationBasePath; var xmlPath = Path.Combine(basePath, "CrazyBull.Api.xml"); c.IncludeXmlComments(xmlPath); }); #region 发放Token // 从文件读取密钥 string keyDir = PlatformServices.Default.Application.ApplicationBasePath; if (RSAUtils.TryGetKeyParameters(keyDir, true, out RSAParameters keyParams) == false) { keyParams = RSAUtils.GenerateAndSaveKey(keyDir); } var _key = new RsaSecurityKey(keyParams); var _options = new JWTTokenOptions() { Key = _key, Audience = "TestAudience", Issuer = "TestIssuer", // 签发者名称 Credentials = new SigningCredentials(_key, SecurityAlgorithms.RsaSha256Signature) }; services.AddAuthorization(auth => { auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder() .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme) .RequireAuthenticatedUser() .Build()); }); #endregion //.net core 2.0 鉴权和1.1写法不一样,参数JwtBearerOption是一样的,之前写在Configure方法里,现在只需要在Configurez方法中写一句app.UseAuthentication() #region 鉴权Token services.AddAuthentication(options => { options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { IssuerSigningKey = _options.Key, ValidAudience = _options.Audience, // 设置接收者必须是 TestAudience ValidIssuer = _options.Issuer, // 设置签发者必须是 TestIssuer ValidateLifetime = true }; }); #endregion //services.AddMvc().AddJsonOptions(options => { options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); }); services.AddSingleton(_options); //添加允许跨域 services.AddCors(options => options.AddPolicy("AllowSameDomain", builder => builder.WithOrigins("*").WithHeaders("date"). AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin().AllowCredentials()) ); //return services.BuilderInterceptableServiceProvider(builder=>builder.SetDynamicProxyFactory()); }