Exemplo n.º 1
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            var connectionString = Configuration.GetConnectionString("DefaultConnection");

            services.AddSingleton(x => new AnonymousServiceFactory(connectionString));
            services.AddHostedService <TimedHostedService>();

            services.Configure <IISServerOptions>(options =>
            {
                options.AutomaticAuthentication = true;
            });

            var tokenOptions = new JwtAuthenticationHelper.Types.TokenOptions();

            Configuration.GetSection("TokenOptions").Bind(tokenOptions);

            var authUrlOptions = new AuthUrlOptions();

            Configuration.GetSection("AuthUrlOptions").Bind(authUrlOptions);

            services.AddJwtAuthenticationWithProtectedCookie(tokenOptions, authUrlOptions: authUrlOptions);
            services.AddAuthorization();


            services.AddScoped(x => new ServiceFactory(connectionString));

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }
        public static IServiceCollection AddJwtAuthenticationWithProtectedCookie(this IServiceCollection services, IConfiguration configuration,
                                                                                 string applicationDiscriminator = null, AuthUrlOptions authUrlOptions = null)
        {
            var tokenOptions = new TokenOptions(
                configuration["Token:Audience"],
                configuration["Token:Issuer"],
                configuration["Token:SigningKey"],
                configuration["Token:ExpiryInMinutes"]);

            var serviceProvider    = services.BuildServiceProvider();
            var hostingEnvironment = serviceProvider.GetService <IHostEnvironment>();

            // The JwtAuthTicketFormat representing the cookie needs an IDataProtector and
            // IDataSerializer to correctly encrypt/decrypt and serialize/deserialize the payload
            // respectively. This requirement is enforced by ISecureDataFormat interface in ASP.NET
            // Core. Read more about ASP.NET Core Data Protection API here:
            // https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/
            // NB: This is only required if you're using JWT with Cookie based authentication, for
            //     cookieless auth (such as with a Web API) the data protection and serialization
            //     dependencies won't be needed. You simply need to set the validation params and add
            //     the token generator dependencies and use the right authentication extension below.

            var applicationName = $"{applicationDiscriminator ?? hostingEnvironment.ApplicationName}";

            services.AddDataProtection(options => options.ApplicationDiscriminator = applicationName)
            .SetApplicationName(applicationName);

            services.AddScoped <IDataSerializer <AuthenticationTicket>, TicketSerializer>();
            services.AddScoped <IJwtTokenAccessor, JwtTokenAccessor>(tokenAccessor => new JwtTokenAccessor(tokenOptions));

            serviceProvider = services.BuildServiceProvider();
            var dataProtector  = serviceProvider.GetDataProtector(new[] { $"{applicationName}-Auth1" });
            var dataSerializer = serviceProvider.GetService <IDataSerializer <AuthenticationTicket> >();

            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultSignInScheme       = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme    = CookieAuthenticationDefaults.AuthenticationScheme;
            })
            .AddCookie(CookieConstants.TwoFactorRememberMeScheme, options =>
            {
                options.Cookie.Name = CookieConstants.TwoFactorRememberMeScheme;
            })
            .AddCookie(CookieConstants.TwoFactorUserIdScheme, options =>
            {
                options.Cookie.Name    = CookieConstants.TwoFactorUserIdScheme;
                options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
            })
            .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
            {
                options.Cookie.Name = CookieConstants.ApplicationScheme;
                // cookie expiration should be set the same as the token expiry (the default is 5
                // mins). The token generator doesn't provide auto-refresh of an expired token so the
                // user will be logged out the next time they try to access a secured endpoint. They
                // will simply have to re-login and acquire a new token and by extension a new cookie.
                // Perhaps in the future I can add some kind of hooks in the token generator that can
                // let the referencing application know that the token has expired and the developer
                // can then request a new token without the user having to re-login.
                options.ExpireTimeSpan = TimeSpan.FromMinutes(tokenOptions.TokenExpiryInMinutes);

                // Specify the TicketDataFormat to use to validate/create the ASP.NET authentication
                // ticket. Its important that the same validation parameters are passed to this class
                // so that the token validation works correctly. The framework will call the
                // appropriate methods in JwtAuthTicketFormat based on whether the cookie is being
                // sent out or coming in from a previously authenticated user. Please bear in mind
                // that if the incoming token is invalid (may be it was tampered or spoofed) the
                // Unprotect() method in JwtAuthTicketFormat will simply return null and the
                // authentication will fail.
                options.TicketDataFormat = new JwtAuthTicketFormat(
                    tokenOptions.ToTokenValidationParams(),
                    dataSerializer,
                    dataProtector);

                options.LoginPath          = GetPath(authUrlOptions?.LoginPath, "/Account/Login");
                options.LogoutPath         = GetPath(authUrlOptions?.LogoutPath, "/Account/Logout");
                options.AccessDeniedPath   = GetPath(authUrlOptions?.AccessDeniedPath, "/Account/AccessDenied");
                options.ReturnUrlParameter = authUrlOptions?.ReturnUrlParameter ?? "returnUrl";
            });

            return(services);
        }