private void ErrorIfAlreadyAuthenticated(CookieApplyRedirectContext context)
 {
     if (context.Request.User.Identity.IsAuthenticated)
     {
         context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
     }
 }
예제 #2
0
 private static void OnApplyRedirect(CookieApplyRedirectContext context)
 {
     if (context.Request.User.Identity.IsAuthenticated)
     {
         context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
     }
     else
     {
         context.Response.Redirect(context.RedirectUri);
     }
 }
        private void ApplyRedirect(CookieApplyRedirectContext context)
        {
            if (!IsAjaxRequest(context.Request))
            {
                var redirectUri = context.RedirectUri;
                var uri = new Uri(redirectUri);

                UrlHelper _url = new UrlHelper(HttpContext.Current.Request.RequestContext);
                string actionUri = string.Format("{0}{1}", _url.RouteUrl("AccountLogin"), uri.Query);
                context.Response.Redirect(actionUri);
            }
        }
예제 #4
0
        private static void ApplyRedirect(CookieApplyRedirectContext context, Func<IStorefrontUrlBuilder> urlBuilderFactory)
        {
            Uri absoluteUri;
            if (Uri.TryCreate(context.RedirectUri, UriKind.Absolute, out absoluteUri))
            {
                var path = PathString.FromUriComponent(absoluteUri);
                if (path == context.OwinContext.Request.PathBase + context.Options.LoginPath)
                {
                    var urlBuilder = urlBuilderFactory();
                    context.RedirectUri = urlBuilder.ToAppAbsolute(context.Options.LoginPath.ToString()) + new QueryString(context.Options.ReturnUrlParameter, context.Request.Uri.AbsoluteUri);
                }
            }

            context.Response.Redirect(context.RedirectUri);
        }
예제 #5
0
        private static void ApplyRedirect(CookieApplyRedirectContext context)
        {
            Uri absoluteUri;
            if (Uri.TryCreate(context.RedirectUri, UriKind.Absolute, out absoluteUri))
            {
                var path = PathString.FromUriComponent(absoluteUri);
                if (path == context.OwinContext.Request.PathBase + context.Options.LoginPath)
                    context.RedirectUri = "http://accounts.domain.com/login" +
                        new QueryString(
                            context.Options.ReturnUrlParameter,
                            context.Request.Uri.AbsoluteUri);
            }

            context.Response.Redirect(context.RedirectUri);
        }
예제 #6
0
        /// <summary>
        /// Method for managing all the re-directs that occurs on the website.
        /// </summary>
        /// <param name="context"></param>
        private static void ApplyRedirect(CookieApplyRedirectContext context)
        {
            string backendPath = Paths.ProtectedRootPath.TrimEnd('/');

            // We use the method for transferring the user to the backend login pages if she tries to go
            // to the Edit views without being navigated.
            if (context.Request.Uri.AbsolutePath.StartsWith(backendPath) && !context.Request.User.Identity.IsAuthenticated)
            {
                context.RedirectUri = VirtualPathUtility.ToAbsolute("~/BackendLogin") +
                        new QueryString(
                            context.Options.ReturnUrlParameter,
                            context.Request.Uri.AbsoluteUri);
            }

            context.Response.Redirect(context.RedirectUri);
        }
        public void UpdateRedirectUrlToAdminLoginPageIfNecessary(CookieApplyRedirectContext context)
        {
            if (UserWasAccessingInternalArea(context))
            {
                string standardLoginPathString = VirtualPathUtility.ToAbsolute(context.Options.LoginPath.Value);
                string adminLoginPathString = VirtualPathUtility.ToAbsolute(AdminLoginPath);

                Uri currentUri = new Uri(context.RedirectUri);
                
                UriBuilder uriBuilder = new UriBuilder(currentUri);
                
                if (string.Equals(uriBuilder.Path, standardLoginPathString, StringComparison.OrdinalIgnoreCase))
                {
                    uriBuilder.Path = adminLoginPathString;
                }

                context.RedirectUri = uriBuilder.Uri.ToString();
            }
        }
예제 #8
0
 public override void ApplyRedirect(CookieApplyRedirectContext context)
 {
     base.ApplyRedirect(context);
 }
예제 #9
0
        public void Configuration(IAppBuilder app)
        {
            // MVC
            GlobalFilters.Filters.Add(new HandleErrorAttribute());
            RouteTable.Routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
                );

            app.UseErrorPage();

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
                LoginPath          = CookieAuthenticationDefaults.LoginPath,
                LogoutPath         = CookieAuthenticationDefaults.LogoutPath,
                ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter,
                Provider           = new CookieAuthenticationProvider
                {
                    OnResponseSignOut = (context) =>
                    {
                        // Single Sign-Out
                        var casUrl                = new Uri(ConfigurationManager.AppSettings["Authentication:CAS:CasServerUrlBase"]);
                        var serviceUrl            = context.Request.Uri.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped);
                        var redirectUri           = new UriBuilder(casUrl);
                        redirectUri.Path         += "/logout";
                        redirectUri.Query         = $"service={Uri.EscapeDataString(serviceUrl)}";
                        var logoutRedirectContext = new CookieApplyRedirectContext(
                            context.OwinContext,
                            context.Options,
                            redirectUri.Uri.AbsoluteUri
                            );
                        context.Options.Provider.ApplyRedirect(logoutRedirectContext);
                    }
                }
            });

            app.UseCasAuthentication(new CasAuthenticationOptions
            {
                CasServerUrlBase = ConfigurationManager.AppSettings["Authentication:CAS:CasServerUrlBase"],
                Provider         = new CasAuthenticationProvider
                {
                    OnCreatingTicket = (context) =>
                    {
                        // first_name, family_name, display_name, email, verified_email
                        var assertion = (context.Identity as CasIdentity)?.Assertion;
                        if (assertion == null)
                        {
                            return(Task.FromResult(0));
                        }
                        var email = assertion.Attributes["email"].FirstOrDefault();
                        if (!string.IsNullOrEmpty(email))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.Email, email));
                        }
                        var displayName = assertion.Attributes["display_name"].FirstOrDefault();
                        if (!string.IsNullOrEmpty(displayName))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.Name, displayName));
                        }
                        return(Task.FromResult(0));
                    }
                }
            });

            app.UseOAuthAuthentication((options) => {
                options.ClientId                = ConfigurationManager.AppSettings["Authentication:OAuth:ClientId"];
                options.ClientSecret            = ConfigurationManager.AppSettings["Authentication:OAuth:ClientSecret"];
                options.CallbackPath            = new PathString("/sign-oauth");
                options.AuthorizationEndpoint   = ConfigurationManager.AppSettings["Authentication:OAuth:AuthorizationEndpoint"];
                options.TokenEndpoint           = ConfigurationManager.AppSettings["Authentication:OAuth:TokenEndpoint"];
                options.SaveTokensAsClaims      = true;
                options.UserInformationEndpoint = ConfigurationManager.AppSettings["Authentication:OAuth:UserInformationEndpoint"];
                options.Events = new OAuthEvents
                {
                    OnCreatingTicket = async(context) =>
                    {
                        var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
                        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
                        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                        var response = await context.Backchannel.SendAsync(request, context.Request.CallCancelled);
                        response.EnsureSuccessStatusCode();

                        var user       = JObject.Parse(await response.Content.ReadAsStringAsync());
                        var identifier = user.Value <string>("id");
                        if (!string.IsNullOrEmpty(identifier))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, identifier));
                        }
                        var attributes = user.Value <JObject>("attributes");
                        if (attributes == null)
                        {
                            return;
                        }
                        var email = attributes.Value <string>("email");
                        if (!string.IsNullOrEmpty(email))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.Email, email));
                        }
                        var displayName = attributes.Value <string>("display_name");
                        if (!string.IsNullOrEmpty(displayName))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.Name, displayName));
                        }
                    }
                };
            });
        }
예제 #10
0
 private static void ApplyRedirect(CookieApplyRedirectContext context)
 {
     UrlHelper _url = new UrlHelper(HttpContext.Current.Request.RequestContext);
     String actionUri = _url.Action("Login", "Account", new { Culture = Abstractions.CultureHelper.CurrentCulture.Name });
     context.Response.Redirect(actionUri);
 }
예제 #11
0
 /// <summary>
 /// Implements the interface method by invoking the related delegate method
 /// </summary>
 /// <param name="context">Contains information about the event</param>
 public virtual void ApplyRedirect(CookieApplyRedirectContext context)
 {
     OnApplyRedirect.Invoke(context);
 }
예제 #12
0
        public void Configuration(IAppBuilder app)
        {
            var env     = Environment.GetEnvironmentVariable("ENVIRONMENT") ?? "Production";
            var builder = new ConfigurationBuilder()
                          .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                          .AddJsonFile($"appsettings.{env}.json", optional: true, reloadOnChange: true);
            var configuration = builder.Build();

            // MVC
            GlobalFilters.Filters.Add(new HandleErrorAttribute());
            RouteTable.Routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
                );

            app.UseErrorPage();

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                LoginPath  = CookieAuthenticationDefaults.LoginPath,
                LogoutPath = CookieAuthenticationDefaults.LogoutPath,
                Provider   = new CookieAuthenticationProvider
                {
                    OnResponseSignOut = context =>
                    {
                        // Single Sign-Out
                        var casUrl                = new Uri(configuration["Authentication:CAS:ServerUrlBase"]);
                        var serviceUrl            = context.Request.Uri.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped);
                        var redirectUri           = new UriBuilder(casUrl);
                        redirectUri.Path         += "/logout";
                        redirectUri.Query         = $"service={Uri.EscapeDataString(serviceUrl)}";
                        var logoutRedirectContext = new CookieApplyRedirectContext(
                            context.OwinContext,
                            context.Options,
                            redirectUri.Uri.AbsoluteUri
                            );
                        context.Options.Provider.ApplyRedirect(logoutRedirectContext);
                    }
                }
            });

            app.UseCasAuthentication(options =>
            {
                options.CasServerUrlBase = configuration["Authentication:CAS:ServerUrlBase"];
                var protocolVersion      = configuration.GetValue("Authentication:CAS:ProtocolVersion", 3);
                if (protocolVersion != 3)
                {
                    switch (protocolVersion)
                    {
                    case 1:
                        options.ServiceTicketValidator = new Cas10ServiceTicketValidator(options);
                        break;

                    case 2:
                        options.ServiceTicketValidator = new Cas20ServiceTicketValidator(options);
                        break;
                    }
                }
                options.Provider = new CasAuthenticationProvider
                {
                    OnCreatingTicket = context =>
                    {
                        // add claims from CasIdentity.Assertion ?
                        var assertion = (context.Identity as CasIdentity)?.Assertion;
                        if (assertion == null)
                        {
                            return(Task.CompletedTask);
                        }
                        context.Identity.AddClaim(new Claim(context.Identity.NameClaimType, assertion.PrincipalName));
                        if (assertion.Attributes.TryGetValue("email", out var email))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.Email, email));
                        }
                        if (assertion.Attributes.TryGetValue("display_name", out var displayName))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.GivenName, displayName));
                        }
                        return(Task.CompletedTask);
                    }
                };
            });

            app.UseOAuthAuthentication(options =>
            {
                options.ClientId                = configuration["Authentication:OAuth:ClientId"];
                options.ClientSecret            = configuration["Authentication:OAuth:ClientSecret"];
                options.CallbackPath            = new PathString("/sign-oauth");
                options.AuthorizationEndpoint   = configuration["Authentication:OAuth:AuthorizationEndpoint"];
                options.TokenEndpoint           = configuration["Authentication:OAuth:TokenEndpoint"];
                options.SaveTokensAsClaims      = true;
                options.UserInformationEndpoint = configuration["Authentication:OAuth:UserInformationEndpoint"];
                options.Events = new OAuthEvents
                {
                    OnCreatingTicket = async context =>
                    {
                        var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
                        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
                        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                        var response = await context.Backchannel.SendAsync(request, context.Request.CallCancelled);
                        response.EnsureSuccessStatusCode();

                        var user       = JObject.Parse(await response.Content.ReadAsStringAsync());
                        var identifier = user.Value <string>("id");
                        if (!string.IsNullOrEmpty(identifier))
                        {
                            context.Identity.AddClaim(new Claim(context.Identity.NameClaimType, identifier));
                        }
                        var attributes = user.Value <JObject>("attributes");
                        if (attributes == null)
                        {
                            return;
                        }
                        var email = attributes.Value <string>("email");
                        if (!string.IsNullOrEmpty(email))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.Email, email));
                        }
                        var displayName = attributes.Value <string>("display_name");
                        if (!string.IsNullOrEmpty(displayName))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.GivenName, displayName));
                        }
                    }
                };
            });
        }
예제 #13
0
        public void Configuration(IAppBuilder app)
        {
            var env     = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development";
            var builder = new ConfigurationBuilder()
                          .AddJsonFile($"appsettings.json", optional: true, reloadOnChange: true)
                          .AddJsonFile($"appsettings.{env}.json", optional: true, reloadOnChange: true);
            var configuration = builder.Build();

            app.UseErrorPage();

            var sessionStore = new AuthenticationSessionStoreWrapper(new RuntimeCacheServiceTicketStore());

            app.UseCasSingleSignOut(sessionStore);

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                LoginPath    = new PathString("/login"),
                LogoutPath   = new PathString("/logout"),
                SessionStore = sessionStore,
                Provider     = new CookieAuthenticationProvider
                {
                    OnResponseSignOut = context =>
                    {
                        // Single Sign-Out
                        var casUrl                = new Uri(configuration["Authentication:CAS:ServerUrlBase"]);
                        var serviceUrl            = context.Request.Uri.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped);
                        var redirectUri           = new UriBuilder(casUrl);
                        redirectUri.Path         += "/logout";
                        redirectUri.Query         = $"service={Uri.EscapeDataString(serviceUrl)}";
                        var logoutRedirectContext = new CookieApplyRedirectContext(
                            context.OwinContext,
                            context.Options,
                            redirectUri.Uri.AbsoluteUri
                            );
                        context.Options.Provider.ApplyRedirect(logoutRedirectContext);
                    }
                }
            });

            app.UseCasAuthentication(options =>
            {
                options.CasServerUrlBase = configuration["Authentication:CAS:ServerUrlBase"];
                options.ServiceUrlBase   = configuration.GetValue <Uri>("Authentication:CAS:ServiceUrlBase");
                options.UseAuthenticationSessionStore = true;
                var protocolVersion = configuration.GetValue("Authentication:CAS:ProtocolVersion", 3);
                if (protocolVersion != 3)
                {
                    switch (protocolVersion)
                    {
                    case 1:
                        options.ServiceTicketValidator = new Cas10ServiceTicketValidator(options);
                        break;

                    case 2:
                        options.ServiceTicketValidator = new Cas20ServiceTicketValidator(options);
                        break;
                    }
                }
                options.Provider = new CasAuthenticationProvider
                {
                    OnCreatingTicket = context =>
                    {
                        // add claims from CasIdentity.Assertion ?
                        var assertion = (context.Identity as CasIdentity)?.Assertion;
                        if (assertion == null)
                        {
                            return(Task.CompletedTask);
                        }
                        context.Identity.AddClaim(new Claim(context.Identity.NameClaimType, assertion.PrincipalName));
                        if (assertion.Attributes.TryGetValue("email", out var email))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.Email, email));
                        }
                        if (assertion.Attributes.TryGetValue("display_name", out var displayName))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.GivenName, displayName));
                        }
                        return(Task.CompletedTask);
                    }
                };
            });

            app.UseOAuthAuthentication(options =>
            {
                options.ClientId                = configuration["Authentication:OAuth:ClientId"];
                options.ClientSecret            = configuration["Authentication:OAuth:ClientSecret"];
                options.CallbackPath            = new PathString("/sign-oauth");
                options.AuthorizationEndpoint   = configuration["Authentication:OAuth:AuthorizationEndpoint"];
                options.TokenEndpoint           = configuration["Authentication:OAuth:TokenEndpoint"];
                options.SaveTokensAsClaims      = true;
                options.UserInformationEndpoint = configuration["Authentication:OAuth:UserInformationEndpoint"];
                options.Events = new OAuthEvents
                {
                    OnCreatingTicket = async context =>
                    {
                        var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
                        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
                        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                        var response = await context.Backchannel.SendAsync(request, context.Request.CallCancelled);
                        response.EnsureSuccessStatusCode();

                        var user       = JObject.Parse(await response.Content.ReadAsStringAsync());
                        var identifier = user.Value <string>("id");
                        if (!string.IsNullOrEmpty(identifier))
                        {
                            context.Identity.AddClaim(new Claim(context.Identity.NameClaimType, identifier));
                        }
                        var attributes = user.Value <JObject>("attributes");
                        if (attributes == null)
                        {
                            return;
                        }
                        var email = attributes.Value <string>("email");
                        if (!string.IsNullOrEmpty(email))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.Email, email));
                        }
                        var displayName = attributes.Value <string>("display_name");
                        if (!string.IsNullOrEmpty(displayName))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.GivenName, displayName));
                        }
                    }
                };
            });

            // Choose an authentication type
            app.Map("/login", branch =>
            {
                branch.Run(async context =>
                {
                    var scheme = context.Request.Query["authscheme"];
                    if (!string.IsNullOrEmpty(scheme))
                    {
                        // By default the client will be redirect back to the URL that issued the challenge (/login?authscheme=foo),
                        // send them to the home page instead (/).
                        context.Authentication.Challenge(new AuthenticationProperties {
                            RedirectUri = "/"
                        }, scheme);
                        return;
                    }

                    context.Response.ContentType = "text/html";
                    await context.Response.WriteAsync(@"<!DOCTYPE html><html><head><meta charset=""utf-8""></head><body>");
                    await context.Response.WriteAsync("<p>Choose an authentication scheme:</p>");
                    foreach (var type in context.Authentication.GetAuthenticationTypes())
                    {
                        if (string.IsNullOrEmpty(type.Caption))
                        {
                            continue;
                        }
                        await context.Response.WriteAsync($"<a href=\"?authscheme={type.AuthenticationType}\">{type.Caption ?? type.AuthenticationType}</a><br>");
                    }
                    await context.Response.WriteAsync("</body></html>");
                });
            });

            // Sign-out to remove the user cookie.
            app.Map("/logout", branch =>
            {
                branch.Run(context =>
                {
                    context.Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType);
                    context.Response.Redirect("/");
                    return(Task.CompletedTask);
                });
            });

            app.Run(async context =>
            {
                // CookieAuthenticationOptions.AutomaticAuthenticate = true (default) causes User to be set
                var user = context.Authentication.User;

                // This is what [Authorize] calls
                // var user = await context.Authentication.AuthenticateAsync(AuthenticationManager.AutomaticScheme);

                // Deny anonymous request beyond this point.
                if (user == null || !user.Identities.Any(identity => identity.IsAuthenticated))
                {
                    // This is what [Authorize] calls
                    // The cookie middleware will intercept this 401 and redirect to /login
                    context.Authentication.Challenge();

                    return;
                }

                // Display user information
                context.Response.ContentType = "text/html";
                await context.Response.WriteAsync(@"<!DOCTYPE html><html><head><meta charset=""utf-8""></head><body>");
                await context.Response.WriteAsync($"<h1>Hello {user.Identity.Name ?? "anonymous"}</h1>");
                await context.Response.WriteAsync("<ul>");
                foreach (var claim in user.Claims)
                {
                    await context.Response.WriteAsync($"<li>{claim.Type}: {claim.Value}</li>");
                }
                await context.Response.WriteAsync("</ul>");
                await context.Response.WriteAsync("<a href=\"/logout\">Logout</a><br>");
                await context.Response.WriteAsync("</body></html>");
            });
        }
 public void ApplyRedirect(CookieApplyRedirectContext context)
 {
     context.Response.Redirect(context.RedirectUri);
 }
예제 #15
0
        public void Configuration(IAppBuilder app)
        {
            var env = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? "Production";

            _configuration = new ConfigurationBuilder()
                             .AddJsonFile("appsettings.json")
                             .AddJsonFile($"appsettings.{env}.json", optional: true, reloadOnChange: true)
                             .AddEnvironmentVariables()
                             .Build();

            var services = new ServiceCollection();

            ConfigureServices(services);
            _resolver = services.BuildServiceProvider();

            // MVC
            GlobalFilters.Filters.Add(new AuthorizeAttribute());
            GlobalFilters.Filters.Add(new HandleErrorAttribute());
            RouteTable.Routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
                );
            AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;

            // configure nlog.config per environment
            var configFile = new FileInfo(Path.Combine(AppContext.BaseDirectory, $"NLog.{env}.config"));

            LogManager.LoadConfiguration(configFile.Exists ? configFile.Name : "NLog.config");
            app.UseNLog();

            app.UseCasSingleSignOut(_resolver.GetRequiredService <IAuthenticationSessionStore>());

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                LoginPath  = CookieAuthenticationDefaults.LoginPath,
                LogoutPath = CookieAuthenticationDefaults.LogoutPath,
                // https://github.com/aspnet/AspNetKatana/wiki/System.Web-response-cookie-integration-issues
                CookieManager = new SystemWebCookieManager(),
                SessionStore  = _resolver.GetRequiredService <IAuthenticationSessionStore>(),
                Provider      = new CookieAuthenticationProvider
                {
                    OnResponseSignOut = context =>
                    {
                        // Single Sign-Out
                        var casUrl                = new Uri(_configuration["Authentication:CAS:ServerUrlBase"]);
                        var urlHelper             = new UrlHelper(HttpContext.Current.Request.RequestContext);
                        var serviceUrl            = urlHelper.Action("Index", "Home", null, HttpContext.Current.Request.Url.Scheme);
                        var redirectUri           = new UriBuilder(casUrl);
                        redirectUri.Path         += "/logout";
                        redirectUri.Query         = $"service={Uri.EscapeDataString(serviceUrl)}";
                        var logoutRedirectContext = new CookieApplyRedirectContext
                                                    (
                            context.OwinContext,
                            context.Options,
                            redirectUri.Uri.AbsoluteUri
                                                    );
                        context.Options.Provider.ApplyRedirect(logoutRedirectContext);
                    }
                }
            });

            app.UseCasAuthentication(options =>
            {
                options.CasServerUrlBase = _configuration["Authentication:CAS:ServerUrlBase"];
                options.ServiceUrlBase   = _configuration.GetValue <Uri>("Authentication:CAS:ServiceUrlBase");
                // required for CasSingleSignOutMiddleware
                options.UseAuthenticationSessionStore = true;
                var protocolVersion = _configuration.GetValue("Authentication:CAS:ProtocolVersion", 3);
                if (protocolVersion != 3)
                {
                    switch (protocolVersion)
                    {
                    case 1:
                        options.ServiceTicketValidator = new Cas10ServiceTicketValidator(options);
                        break;

                    case 2:
                        options.ServiceTicketValidator = new Cas20ServiceTicketValidator(options);
                        break;
                    }
                }
                options.Provider = new CasAuthenticationProvider
                {
                    OnCreatingTicket = context =>
                    {
                        var assertion = (context.Identity as CasIdentity)?.Assertion;
                        if (assertion == null)
                        {
                            return(Task.CompletedTask);
                        }
                        // Map claims from assertion
                        context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, assertion.PrincipalName));
                        if (assertion.Attributes.TryGetValue("display_name", out var displayName))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.Name, displayName));
                        }
                        if (assertion.Attributes.TryGetValue("email", out var email))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.Email, email));
                        }
                        return(Task.CompletedTask);
                    },
                    OnRemoteFailure = context =>
                    {
                        var failure = context.Failure;
                        _logger.Error(failure, failure.Message);
                        context.Response.Redirect("/Account/ExternalLoginFailure");
                        context.HandleResponse();
                        return(Task.CompletedTask);
                    }
                };
            });

            app.UseOAuthAuthentication(options =>
            {
                options.ClientId                = _configuration["Authentication:OAuth:ClientId"];
                options.ClientSecret            = _configuration["Authentication:OAuth:ClientSecret"];
                options.AuthorizationEndpoint   = _configuration["Authentication:OAuth:AuthorizationEndpoint"];
                options.TokenEndpoint           = _configuration["Authentication:OAuth:TokenEndpoint"];
                options.UserInformationEndpoint = _configuration["Authentication:OAuth:UserInformationEndpoint"];
                options.Events = new OAuthEvents
                {
                    OnCreatingTicket = async context =>
                    {
                        // Get the OAuth user
                        using var request             = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
                        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
                        using var response            = await context.Backchannel.SendAsync(request, context.Request.CallCancelled).ConfigureAwait(false);

                        if (!response.IsSuccessStatusCode || response.Content?.Headers?.ContentType?.MediaType.StartsWith("application/json") != true)
                        {
                            var responseText = response.Content == null
                                ? string.Empty
                                : await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                            _logger.Error($"An error occurred when retrieving OAuth user information ({response.StatusCode}). {responseText}");
                            return;
                        }

                        using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
                        using var json   = await JsonDocument.ParseAsync(stream).ConfigureAwait(false);
                        var user         = json.RootElement;
                        if (user.TryGetProperty("id", out var id))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id.GetString()));
                        }
                        if (user.TryGetProperty("attributes", out var attributes))
                        {
                            if (attributes.TryGetProperty("display_name", out var displayName))
                            {
                                context.Identity.AddClaim(new Claim(ClaimTypes.Name, displayName.GetString()));
                            }
                            if (attributes.TryGetProperty("email", out var email))
                            {
                                context.Identity.AddClaim(new Claim(ClaimTypes.Email, email.GetString()));
                            }
                        }
                    },
                    OnRemoteFailure = context =>
                    {
                        var failure = context.Failure;
                        _logger.Error(failure, failure.Message);
                        context.Response.Redirect("/Account/ExternalLoginFailure");
                        context.HandleResponse();
                        return(Task.CompletedTask);
                    }
                };
            });
        }
        /// <summary>
        /// Parse the request URI to determine whether the user was trying to access the internal area.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public bool UserWasAccessingInternalArea(CookieApplyRedirectContext context)
        {
            HttpRequest request = new HttpRequest(null, context.Request.Uri.OriginalString, context.Request.Uri.Query);
            HttpResponse response = new HttpResponse(new StringWriter());
            HttpContext httpContext = new HttpContext(request, response);

            var routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));

            string area = routeData.DataTokens["area"] as string;

            bool userWasAccessingInternalArea = string.Equals(area, AdminAreaName, StringComparison.OrdinalIgnoreCase);
            
            return userWasAccessingInternalArea;
        }
 public void ApplyRedirect(CookieApplyRedirectContext context)
 {
     context.Response.Redirect(context.RedirectUri);
 }
예제 #18
0
        /// <summary>
        /// Applies grants to the response
        /// </summary>
        /// <returns></returns>
        protected override async Task ApplyResponseGrantAsync()
        {
            AuthenticationResponseGrant signin = Helper.LookupSignIn(Options.AuthenticationType);
            bool shouldSignin = signin != null;
            AuthenticationResponseRevoke signout = Helper.LookupSignOut(Options.AuthenticationType, Options.AuthenticationMode);
            bool shouldSignout = signout != null;

            if (!(shouldSignin || shouldSignout || _shouldRenew))
            {
                return;
            }

            AuthenticationTicket model = await AuthenticateAsync();

            try
            {
                var cookieOptions = new CookieOptions
                {
                    Domain   = Options.CookieDomain,
                    HttpOnly = Options.CookieHttpOnly,
                    Path     = Options.CookiePath ?? "/",
                };
                if (Options.CookieSecure == CookieSecureOption.SameAsRequest)
                {
                    cookieOptions.Secure = Request.IsSecure;
                }
                else
                {
                    cookieOptions.Secure = Options.CookieSecure == CookieSecureOption.Always;
                }

                if (shouldSignin)
                {
                    var signInContext = new CookieResponseSignInContext(
                        Context,
                        Options,
                        Options.AuthenticationType,
                        signin.Identity,
                        signin.Properties,
                        cookieOptions);

                    DateTimeOffset issuedUtc;
                    if (signInContext.Properties.IssuedUtc.HasValue)
                    {
                        issuedUtc = signInContext.Properties.IssuedUtc.Value;
                    }
                    else
                    {
                        issuedUtc = Options.SystemClock.UtcNow;
                        signInContext.Properties.IssuedUtc = issuedUtc;
                    }

                    if (!signInContext.Properties.ExpiresUtc.HasValue)
                    {
                        signInContext.Properties.ExpiresUtc = issuedUtc.Add(Options.ExpireTimeSpan);
                    }

                    Options.Provider.ResponseSignIn(signInContext);

                    if (signInContext.Properties.IsPersistent)
                    {
                        DateTimeOffset expiresUtc = signInContext.Properties.ExpiresUtc ?? issuedUtc.Add(Options.ExpireTimeSpan);
                        signInContext.CookieOptions.Expires = expiresUtc.ToUniversalTime().DateTime;
                    }

                    model = new AuthenticationTicket(signInContext.Identity, signInContext.Properties);
                    if (Options.SessionStore != null)
                    {
                        if (_sessionKey != null)
                        {
                            await Options.SessionStore.RemoveAsync(_sessionKey);
                        }
                        _sessionKey = await Options.SessionStore.StoreAsync(model);

                        ClaimsIdentity identity = new ClaimsIdentity(
                            new[] { new Claim(SessionIdClaim, _sessionKey) },
                            Options.AuthenticationType);
                        model = new AuthenticationTicket(identity, null);
                    }

                    string cookieValue = Options.TicketDataFormat.Protect(model);

                    Options.CookieManager.AppendResponseCookie(
                        Context,
                        Options.CookieName,
                        cookieValue,
                        signInContext.CookieOptions);

                    var signedInContext = new CookieResponseSignedInContext(
                        Context,
                        Options,
                        Options.AuthenticationType,
                        signInContext.Identity,
                        signInContext.Properties);

                    Options.Provider.ResponseSignedIn(signedInContext);
                }
                else if (shouldSignout)
                {
                    if (Options.SessionStore != null && _sessionKey != null)
                    {
                        await Options.SessionStore.RemoveAsync(_sessionKey);
                    }

                    var context = new CookieResponseSignOutContext(
                        Context,
                        Options,
                        cookieOptions);

                    Options.Provider.ResponseSignOut(context);

                    Options.CookieManager.DeleteCookie(
                        Context,
                        Options.CookieName,
                        context.CookieOptions);
                }
                else if (_shouldRenew && model.Identity != null)
                {
                    model.Properties.IssuedUtc  = _renewIssuedUtc;
                    model.Properties.ExpiresUtc = _renewExpiresUtc;

                    if (Options.SessionStore != null && _sessionKey != null)
                    {
                        await Options.SessionStore.RenewAsync(_sessionKey, model);

                        ClaimsIdentity identity = new ClaimsIdentity(
                            new[] { new Claim(SessionIdClaim, _sessionKey) },
                            Options.AuthenticationType);
                        model = new AuthenticationTicket(identity, null);
                    }

                    string cookieValue = Options.TicketDataFormat.Protect(model);

                    if (model.Properties.IsPersistent)
                    {
                        cookieOptions.Expires = _renewExpiresUtc.ToUniversalTime().DateTime;
                    }

                    Options.CookieManager.AppendResponseCookie(
                        Context,
                        Options.CookieName,
                        cookieValue,
                        cookieOptions);
                }

                Response.Headers.Set(
                    HeaderNameCacheControl,
                    HeaderValueNoCache);

                Response.Headers.Set(
                    HeaderNamePragma,
                    HeaderValueNoCache);

                Response.Headers.Set(
                    HeaderNameExpires,
                    HeaderValueMinusOne);

                bool shouldLoginRedirect  = shouldSignin && Options.LoginPath.HasValue && Request.Path == Options.LoginPath;
                bool shouldLogoutRedirect = shouldSignout && Options.LogoutPath.HasValue && Request.Path == Options.LogoutPath;

                if ((shouldLoginRedirect || shouldLogoutRedirect) && Response.StatusCode == 200)
                {
                    IReadableStringCollection query = Request.Query;
                    string redirectUri = query.Get(Options.ReturnUrlParameter);
                    if (!string.IsNullOrWhiteSpace(redirectUri) &&
                        IsHostRelative(redirectUri))
                    {
                        var redirectContext = new CookieApplyRedirectContext(Context, Options, redirectUri);
                        Options.Provider.ApplyRedirect(redirectContext);
                    }
                }
            }
            catch (Exception exception)
            {
                CookieExceptionContext exceptionContext = new CookieExceptionContext(Context, Options,
                                                                                     CookieExceptionContext.ExceptionLocation.ApplyResponseGrant, exception, model);
                Options.Provider.Exception(exceptionContext);
                if (exceptionContext.Rethrow)
                {
                    throw;
                }
            }
        }
예제 #19
0
 private static bool IsApiRequest(CookieApplyRedirectContext context)
 {
     return(context.Request.Path.StartsWithSegments(new PathString("/api")));
 }
        /// <summary>
        /// If a user times out before attempting an action, the "ReturnUrl" query string
        /// parameter included in the sign-in page URL may need to be rewritten.
        /// This can be used to prevent the user being redirected with a GET to a POST-only action
        /// after they sign back in.
        /// </summary>
        public void ApplyReturnUrlMapping(CookieApplyRedirectContext context)
        {
            Uri currentUri = new Uri(context.RedirectUri);
            var queryStringParameters = HttpUtility.ParseQueryString(currentUri.Query);

            string returnUrl = queryStringParameters["ReturnUrl"];

            if (returnUrlMapping.IsMapped(returnUrl))
            {
                returnUrl = returnUrlMapping.ApplyMap(returnUrl);

                if (returnUrl != null)
                {
                    queryStringParameters["ReturnUrl"] = returnUrl;
                }
                else
                {
                    queryStringParameters.Remove("ReturnUrl");
                }

                UriBuilder uriBuilder = new UriBuilder(currentUri);
                uriBuilder.Query = queryStringParameters.ToString();
                context.RedirectUri = uriBuilder.Uri.ToString();
            }
        }
        public void Configuration(IAppBuilder app)
        {
            app.UseErrorPage();

            var sessionStore = new AuthenticationSessionStoreWrapper(new RuntimeCacheServiceTicketStore());

            app.UseCasSingleSignOut(sessionStore);

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                LoginPath    = new PathString("/login"),
                LogoutPath   = new PathString("/logout"),
                SessionStore = sessionStore,
                Provider     = new CookieAuthenticationProvider
                {
                    OnResponseSignOut = (context) =>
                    {
                        // Single Sign-Out
                        var casUrl                = new Uri(ConfigurationManager.AppSettings["Authentication:CAS:CasServerUrlBase"]);
                        var serviceUrl            = context.Request.Uri.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped);
                        var redirectUri           = new UriBuilder(casUrl);
                        redirectUri.Path         += "/logout";
                        redirectUri.Query         = $"service={Uri.EscapeDataString(serviceUrl)}";
                        var logoutRedirectContext = new CookieApplyRedirectContext(
                            context.OwinContext,
                            context.Options,
                            redirectUri.Uri.AbsoluteUri
                            );
                        context.Options.Provider.ApplyRedirect(logoutRedirectContext);
                    }
                }
            });

            app.UseCasAuthentication(new CasAuthenticationOptions
            {
                CasServerUrlBase = ConfigurationManager.AppSettings["Authentication:CAS:CasServerUrlBase"],
                UseAuthenticationSessionStore = true,
                Provider = new CasAuthenticationProvider
                {
                    OnCreatingTicket = (context) =>
                    {
                        // first_name, family_name, display_name, email, verified_email
                        var assertion = (context.Identity as CasIdentity)?.Assertion;
                        if (assertion == null)
                        {
                            return(Task.FromResult(0));
                        }
                        var email = assertion.Attributes["email"].FirstOrDefault();
                        if (!string.IsNullOrEmpty(email))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.Email, email));
                        }
                        var displayName = assertion.Attributes["display_name"].FirstOrDefault();
                        if (!string.IsNullOrEmpty(displayName))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.Name, displayName));
                        }
                        return(Task.FromResult(0));
                    }
                }
            });

            app.UseOAuthAuthentication((options) => {
                options.ClientId                = ConfigurationManager.AppSettings["Authentication:OAuth:ClientId"];
                options.ClientSecret            = ConfigurationManager.AppSettings["Authentication:OAuth:ClientSecret"];
                options.CallbackPath            = new PathString("/sign-oauth");
                options.AuthorizationEndpoint   = ConfigurationManager.AppSettings["Authentication:OAuth:AuthorizationEndpoint"];
                options.TokenEndpoint           = ConfigurationManager.AppSettings["Authentication:OAuth:TokenEndpoint"];
                options.SaveTokensAsClaims      = true;
                options.UserInformationEndpoint = ConfigurationManager.AppSettings["Authentication:OAuth:UserInformationEndpoint"];
                options.Events = new OAuthEvents
                {
                    OnCreatingTicket = async(context) =>
                    {
                        var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
                        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
                        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                        var response = await context.Backchannel.SendAsync(request, context.Request.CallCancelled);
                        response.EnsureSuccessStatusCode();

                        var user       = JObject.Parse(await response.Content.ReadAsStringAsync());
                        var identifier = user.Value <string>("id");
                        if (!string.IsNullOrEmpty(identifier))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, identifier));
                        }
                        var attributes = user.Value <JObject>("attributes");
                        if (attributes == null)
                        {
                            return;
                        }
                        var email = attributes.Value <string>("email");
                        if (!string.IsNullOrEmpty(email))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.Email, email));
                        }
                        var displayName = attributes.Value <string>("display_name");
                        if (!string.IsNullOrEmpty(displayName))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.Name, displayName));
                        }
                    }
                };
            });

            // Choose an authentication type
            app.Map("/login", branch =>
            {
                branch.Run(async context =>
                {
                    var authType = context.Request.Query["authscheme"];
                    if (!string.IsNullOrEmpty(authType))
                    {
                        // By default the client will be redirect back to the URL that issued the challenge (/login?authtype=foo),
                        // send them to the home page instead (/).
                        context.Authentication.Challenge(new AuthenticationProperties()
                        {
                            RedirectUri = "/"
                        }, authType);
                        return;
                    }

                    context.Response.ContentType = "text/html";
                    await context.Response.WriteAsync("<html><body>");
                    await context.Response.WriteAsync("<p>Choose an authentication scheme:</p>");
                    foreach (var type in context.Authentication.GetAuthenticationTypes())
                    {
                        if (string.IsNullOrEmpty(type.Caption))
                        {
                            continue;
                        }
                        await context.Response.WriteAsync($"<a href=\"?authscheme={type.AuthenticationType}\">{type.Caption}</a><br>");
                    }
                    await context.Response.WriteAsync("</body></html>");
                });
            });

            // Sign-out to remove the user cookie.
            app.Map("/logout", branch =>
            {
                branch.Run(context =>
                {
                    context.Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType);
                    context.Response.Redirect("/");
                    return(Task.FromResult(0));
                });
            });

            app.Run(async context =>
            {
                // CookieAuthenticationOptions.AutomaticAuthenticate = true (default) causes User to be set
                var user = context.Authentication.User;

                // This is what [Authorize] calls
                // var user = await context.Authentication.AuthenticateAsync(AuthenticationManager.AutomaticScheme);

                // Deny anonymous request beyond this point.
                if (user == null || !user.Identities.Any(identity => identity.IsAuthenticated))
                {
                    // This is what [Authorize] calls
                    // The cookie middleware will intercept this 401 and redirect to /login
                    context.Authentication.Challenge();

                    return;
                }

                // Display user information
                context.Response.ContentType = "text/html";
                await context.Response.WriteAsync("<html><body>");
                await context.Response.WriteAsync($"<h1>Hello {user.Identity.Name ?? "anonymous"}</h1>");
                await context.Response.WriteAsync("<ul>");
                foreach (var claim in user.Claims)
                {
                    await context.Response.WriteAsync($"<li>{claim.Type}: {claim.Value}</li>");
                }
                await context.Response.WriteAsync("</ul>");
                await context.Response.WriteAsync("<a href=\"/logout\">Logout</a><br>");
                await context.Response.WriteAsync("</body></html>");
            });
        }
 public void ApplyRedirect(CookieApplyRedirectContext context)
 {
     OnApplyingRedirect.Invoke(context);
     _cookieAuthenticationProvider.ApplyRedirect(context);
     OnRedirectApplied.Invoke(context);
 }