2017-02-01 17 views
5

Tôi đã có ứng dụng ASP.NET Core MVC, được lưu trữ trên các trang web Azure, nơi tôi đã triển khai Phiên và Danh tính. Vấn đề của tôi là sau 30 phút, tôi bị đăng xuất. Nó không quan trọng nếu tôi đã hoạt động trong 30 phút qua hay không.Trang web ASP.NET Core hết thời gian sau 30 phút

Thực hiện một số tìm kiếm, tôi nhận thấy rằng vấn đề là công cụ SecurityStamp, found here. Tôi đã cố gắng thực hiện điều này bằng cách làm như sau:

Dưới đây là impelmentation UserManager của tôi với các công cụ an ninh tem:

public class UserManager : UserManager<Login> 
{ 
    public UserManager(
     IUserStore<Login> store, 
     IOptions<IdentityOptions> optionsAccessor, 
     IPasswordHasher<Login> passwordHasher, 
     IEnumerable<IUserValidator<Login>> userValidators, 
     IEnumerable<IPasswordValidator<Login>> passwordValidators, 
     ILookupNormalizer keyNormalizer, 
     IdentityErrorDescriber errors, 
     IServiceProvider services, 
     ILogger<UserManager<Login>> logger) 
     : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger) 
    { 
     // noop 
    } 

    public override bool SupportsUserSecurityStamp => true; 

    public override async Task<string> GetSecurityStampAsync(Login login) 
    { 
     return await Task.FromResult("MyToken"); 
    } 

    public override async Task<IdentityResult> UpdateSecurityStampAsync(Login login) 
    { 
     return await Task.FromResult(IdentityResult.Success); 
    } 
} 

Dưới đây là phương pháp ConfigureServices tôi trên Startup.cs:

public void ConfigureServices(IServiceCollection services) 
{ 
    // Add framework services. 
    services.AddApplicationInsightsTelemetry(Configuration); 

    services.AddSingleton(_ => Configuration); 

    services.AddSingleton<IUserStore<Login>, UserStore>(); 
    services.AddSingleton<IRoleStore<Role>, RoleStore>(); 

    services.AddIdentity<Login, Role>(o => 
    { 
     o.Password.RequireDigit = false; 
     o.Password.RequireLowercase = false; 
     o.Password.RequireUppercase = false; 
     o.Password.RequiredLength = 6; 
     o.Cookies.ApplicationCookie.ExpireTimeSpan = TimeSpan.FromDays(365); 
     o.Cookies.ApplicationCookie.SlidingExpiration = true; 
     o.Cookies.ApplicationCookie.AutomaticAuthenticate = true; 
    }) 
     .AddUserStore<UserStore>() 
     .AddUserManager<UserManager>() 
     .AddRoleStore<RoleStore>() 
     .AddRoleManager<RoleManager>() 
     .AddDefaultTokenProviders(); 

    services.AddScoped<SignInManager<Login>, SignInManager<Login>>(); 
    services.AddScoped<UserManager<Login>, UserManager<Login>>(); 

    services.Configure<AuthorizationOptions>(options => 
    { 
     options.AddPolicy("Admin", policy => policy.Requirements.Add(new AdminRoleRequirement(new RoleRepo(Configuration)))); 
     options.AddPolicy("SuperUser", policy => policy.Requirements.Add(new SuperUserRoleRequirement(new RoleRepo(Configuration)))); 
     options.AddPolicy("DataIntegrity", policy => policy.Requirements.Add(new DataIntegrityRoleRequirement(new RoleRepo(Configuration)))); 
    }); 

    services.Configure<FormOptions>(x => x.ValueCountLimit = 4096); 
    services.AddScoped<IPasswordHasher<Login>, PasswordHasher>(); 

    services.AddDistributedMemoryCache(); 
    services.AddSession(); 

    services.AddMvc(); 

    // repos 
    InjectRepos(services); 

    // services 
    InjectServices(services); 
} 

Và cuối cùng , đây là phương pháp Định cấu hình của tôi trên Startup.cs:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
    loggerFactory.AddDebug(); 

    app.UseApplicationInsightsRequestTelemetry(); 

    if (env.IsDevelopment()) 
    { 
     app.UseDeveloperExceptionPage(); 
     app.UseDatabaseErrorPage(); 
     app.UseBrowserLink(); 
    } 
    else 
    { 
     app.UseExceptionHandler("/home/error"); 
    } 

    app.UseStatusCodePages(); 

    app.UseStaticFiles(); 

    app.UseSession(); 
    app.UseIdentity(); 

    app.UseMiddleware(typeof (ErrorHandlingMiddleware)); 
    app.UseMiddleware(typeof (RequestLogMiddleware)); 

    app.UseMvc(routes => 
    { 
     routes.MapRoute(
      name: "default", 
      template: "{controller=Home}/{action=Index}/{id?}"); 
    }); 
} 

W mũ của sai với việc thực hiện của tôi ở đây?

CẬP NHẬT: Điều gì một giây ... Tôi nhận thấy UserManager của tôi không kế thừa từ bất kỳ giao diện nào cho công cụ đóng dấu bảo mật, đó là những gì cần thiết?

Trả lời

1

Bạn có được lưu trữ trong IIS không? Nếu vậy, có thể không có gì sai với mã của bạn, nhưng hồ bơi ứng dụng của bạn có thể được tái chế (kiểm tra cài đặt nâng cao trên hồ bơi ứng dụng). Khi điều đó xảy ra, nhị phân của bạn có được lấy ra khỏi bộ nhớ và được thay thế bằng một cái mới, PID của nó thay đổi không?

+0

Rất tiếc, mục này được lưu trữ trên Azure, vì vậy tôi không tin rằng mình có quyền kiểm soát IIS. – ganders

3

Điều này đơn giản chỉ vì bạn cần phải enable and configure Data Protection. Cookie và thiết lập phiên có vẻ chính xác. Điều gì đang xảy ra ngay bây giờ cho bạn là bất cứ khi nào ứng dụng được tái chế hoặc cân bằng tải máy chủ đến máy chủ khác hoặc triển khai mới xảy ra, v.v., nó tạo khóa bảo vệ dữ liệu mới trong bộ nhớ, vì vậy khoá phiên của người dùng không hợp lệ. Vì vậy, tất cả các bạn cần làm là thêm dòng sau vào Startup.cs:

services.AddDataProtection() 
     .PersistKeysToFileSystem(new DirectoryInfo(@"D:\writable\temp\directory\")) 
     .SetDefaultKeyLifetime(TimeSpan.FromDays(14)); 

Sử dụng các tài liệu hướng dẫn để tìm hiểu cách thiết đúng cách này và các tùy chọn khác nhau về nơi để lưu các khóa Bảo vệ dữ liệu (hệ thống tập tin, redis , đăng ký, v.v.). Bạn có thể nghĩ về khóa bảo vệ dữ liệu là thay thế khóa máy của web.config trong asp.net.

Vì bạn đã đề cập bạn đang sử dụng Azure, bạn có thể sử dụng gói này Microsoft.AspNetCore.DataProtection.AzureStorage để lưu khóa sao cho khóa vẫn tiếp tục. Vì vậy, bạn có thể use this example of how to use Azure Storage.

+0

Vì vậy, hồ bơi ứng dụng của tôi đang được tái chế sau mỗi 30 phút và được đồng bộ hóa với thời gian tôi đăng nhập lần cuối? Điều đó không hợp lý với tôi. – ganders

+0

Nó có thể không được tái chế thường xuyên, không. Nhưng tài liệu AspNetCore đề cập rằng các khóa bảo vệ dữ liệu được tạo trong bộ nhớ theo mặc định-- và là những gì bảo vệ dữ liệu cookie phiên và nhận dạng (cũng như bộ lọc hành động ValidateAntiForgeryToken) sẽ không hợp lệ cho người dùng nếu khóa bảo vệ dữ liệu này thay đổi. – truemedia

+0

Tôi vừa nhận thấy [cài đặt mặc định cho Bảo vệ dữ liệu] (https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/default-settings#data-protection-default-settings) trên Azure thực sự khá tốt khi thiết lập bạn. Bạn có thể chỉ cần thêm mã, 'services.AddDataProtection();' và bạn sẽ được thiết lập và chạy. Azure sẽ tự động duy trì các phím cho bạn. Ngoài ra, đối với bất kỳ ai sử dụng IIS, chúng cũng sẽ hoạt động tốt trên một máy đơn mà không cần tùy chọn 'PersistKeysToFileSystem', vì cài đặt mặc định được thiết lập tốt, như được hiển thị trong tài liệu. – truemedia

Các vấn đề liên quan