aspnet / Security

[Archived] Middleware for security and authorization of web apps. Project moved to https://github.com/aspnet/AspNetCore
Apache License 2.0
1.27k stars 599 forks source link

aspnetcore 2.0 override cookie auth defaults #1344

Closed AerisG222 closed 7 years ago

AerisG222 commented 7 years ago

I am upgrading an application to aspnetcore2 (using the ci-dev feed), and am not able to override cookie auth defaults like I had been able to in the past. I've tried following the auth 2.0 announcement (https://github.com/aspnet/announcements/issues/262), and ended up with the following in Configure:

.UseAuthentication()

and the following in ConfigureServices:

.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(opts =>
                    {
                        opts.AccessDeniedPath = "/account/access-denied";
                        opts.ExpireTimeSpan = TimeSpan.FromMinutes(2);
                        opts.LoginPath = "/about";
                        opts.LogoutPath = "/account/logout";
                    })

However, if I access a restricted resource before logging in, I end up on /Account/Login (not the /about page). Originally, I was seeing that the expiration was not being honored, but the loginpath is a bit easier to test.

.Net CLI:

.NET Command Line Tools (2.0.0-preview3-006890)

Product Information: Version: 2.0.0-preview3-006890 Commit SHA-1 hash: be54917dc4

Runtime Environment: OS Name: fedora OS Version: 26 OS Platform: Linux RID: fedora.26-x64 Base Path: /opt/dotnet/sdk/2.0.0-preview3-006890/

Microsoft .NET Core Shared Framework Host

Version : 2.0.0 Build : e8b8861ac7faf042c87a5c2f9f2d04c98b69f28d

HaoK commented 7 years ago

Are you using identity? What's the entire ConfigureServices?

AerisG222 commented 7 years ago

Yes, I am using Identity (POCO/Custom - not EF). Here is ConfigureServices (have commented out the external auths to try and make sure that was not playing into this):

public void ConfigureServices(IServiceCollection services)
        {
            services
                .Configure<ContactConfig>(_config.GetSection("ContactUs"))
                .Configure<EmailConfig>(_config.GetSection("Email"))
                .Configure<EnvironmentConfig>(_config.GetSection("Environment"))
                .Configure<GoogleCaptchaConfig>(_config.GetSection("GoogleRecaptcha"))
                .Configure<IdentityOptions>(opts =>
                    {
                        opts.Password.RequireDigit = false;
                        opts.Password.RequireLowercase = false;
                        opts.Password.RequireNonAlphanumeric = false;
                        opts.Password.RequireUppercase = false;
                        opts.Password.RequiredLength = 4;
                    })
                .AddLogging()
                .AddMawDataRepositories(_config["Environment:DbConnectionString"])
                .AddMawServices()
                .AddSingleton<IFileProvider>(x => new PhysicalFileProvider(_config["Environment:AssetsPath"]))
                .AddSingleton<IImageCropper, ImageCropper>()
                .AddSingleton<IPhotoZipper, PhotoZipper>()
                .AddScoped<ICaptchaService, GoogleCaptchaService>()
                .AddScoped<IEmailService, EmailService>()
                .AddScoped<ILoginService, LoginService>()
                .AddScoped<IUserStore<MawUser>, MawUserStore>()
                .AddScoped<IRoleStore<MawRole>, MawRoleStore>()
                .AddAntiforgery(opts => opts.HeaderName = "X-XSRF-TOKEN")
                .AddIdentity<MawUser, MawRole>()
                    .Services
                .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(opts =>
                    {
                        opts.AccessDeniedPath = "/account/access-denied";
                        opts.ExpireTimeSpan = TimeSpan.FromMinutes(2);
                        opts.LoginPath = "/about";
                        opts.LogoutPath = "/account/logout";
                    })
                /* 
                .AddGitHubAuthentication(opts =>
                    {
                        opts.ClientId = _config["GitHub:ClientId"];
                        opts.ClientSecret = _config["GitHub:ClientSecret"];
                        opts.SaveTokens = true;
                        opts.Scope.Add("user:email");
                    })

                .AddGoogle(opts => 
                    {
                        opts.ClientId = _config["GooglePlus:ClientId"];
                        opts.ClientSecret = _config["GooglePlus:ClientSecret"];
                        opts.SaveTokens = true;
                    })
                .AddMicrosoftAccount(opts =>
                    {
                        opts.ClientId = _config["Microsoft:ApplicationId"];
                        opts.ClientSecret = _config["Microsoft:Secret"];
                        opts.SaveTokens = true;
                    })
                .AddTwitter(opts =>
                    {
                        opts.ConsumerKey = _config["Twitter:ConsumerKey"];
                        opts.ConsumerSecret = _config["Twitter:ConsumerSecret"];
                        opts.RetrieveUserDetails = true;
                        opts.SaveTokens = true;
                    })
                */
                .Services
                .AddAuthorization(opts =>
                    {
                        opts.AddPolicy(MawConstants.POLICY_VIEW_PHOTOS, new AuthorizationPolicyBuilder().RequireRole(MawConstants.ROLE_FRIEND, MawConstants.ROLE_ADMIN).Build());
                        opts.AddPolicy(MawConstants.POLICY_VIEW_VIDEOS, new AuthorizationPolicyBuilder().RequireRole(MawConstants.ROLE_FRIEND, MawConstants.ROLE_ADMIN).Build());
                        opts.AddPolicy(MawConstants.POLICY_ADMIN_SITE, new AuthorizationPolicyBuilder().RequireRole(MawConstants.ROLE_ADMIN).Build());
                    })
                .AddMvc();
        }
HaoK commented 7 years ago

If you are using identity, that's already calling AddAuth and adding its own cookies, so you need to configure the application cookie via: services.ConfigureApplicationCookie()

AerisG222 commented 7 years ago

OK, let me try that. Assuming that is the case, perhaps additional commentary for Announcement 262 could save someone some time...

HaoK commented 7 years ago

Good idea, added a small section:

Configuring Identity / application cookies

The cookie options that used to be configured via:

   services.AddIdentity(options => options.Cookies...)
now are configured via:

   services.Configure[Application/External]Cookie()
AerisG222 commented 7 years ago

That worked perfectly! Thank you very much!

ppenan commented 6 years ago

I did the same, but in the second API (micro service) which was redirected from the authentication web project, I got Access Denied because the second API could not find the cookie which I created in the authentication web project. This problem occurs only in Windows(I assume the IIS Express is the problem) because in Mac the problem never occurred(I can consume the service normally).