// This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { var serviceTicketStore = new DistributedCacheServiceTicketStore(); var ticketStore = new TicketStoreWrapper(serviceTicketStore); services.AddSingleton <IServiceTicketStore>(serviceTicketStore); services.AddSingleton <ITicketStore>(ticketStore); services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.LoginPath = "/login"; options.LogoutPath = "/logout"; options.SessionStore = ticketStore; options.Events = new CookieAuthenticationEvents { OnSigningOut = context => { // Single Sign-Out var casUrl = new Uri(Configuration["Authentication:CAS:ServerUrlBase"]); var serviceUrl = new Uri(context.Request.GetEncodedUrl()) .GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped); var redirectUri = UriHelper.BuildAbsolute( casUrl.Scheme, new HostString(casUrl.Host, casUrl.Port), casUrl.LocalPath, "/logout", QueryString.Create("service", serviceUrl)); var logoutRedirectContext = new RedirectContext <CookieAuthenticationOptions>( context.HttpContext, context.Scheme, context.Options, context.Properties, redirectUri ); context.Response.StatusCode = 204; //Prevent RedirectToReturnUrl context.Options.Events.RedirectToLogout(logoutRedirectContext); return(Task.CompletedTask); } }; }) .AddCAS(options => { options.CallbackPath = "/signin-cas"; options.CasServerUrlBase = Configuration["Authentication:CAS:ServerUrlBase"]; // required for CasSingleSignOutMiddleware options.SaveTokens = 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.Events = new CasEvents { OnCreatingTicket = context => { // add claims from CasIdentity.Assertion ? var assertion = context.Assertion; if (assertion == null) { return(Task.CompletedTask); } if (!(context.Principal.Identity is ClaimsIdentity identity)) { return(Task.CompletedTask); } identity.AddClaim(new Claim(identity.NameClaimType, assertion.PrincipalName)); if (assertion.Attributes.TryGetValue("email", out var email)) { identity.AddClaim(new Claim(ClaimTypes.Email, email)); } if (assertion.Attributes.TryGetValue("display_name", out var displayName)) { identity.AddClaim(new Claim(ClaimTypes.GivenName, displayName)); } return(Task.CompletedTask); } }; }) .AddOAuth("OAuth", options => { options.CallbackPath = "/signin-oauth"; 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.SaveTokens = 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.HttpContext.RequestAborted); 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 name = attributes.Value <string>("display_name"); if (!string.IsNullOrEmpty(name)) { context.Identity.AddClaim(new Claim(ClaimTypes.GivenName, name)); } } }; }); }
// This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddAuthentication(options => options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme); services.AddDataProtection(); var servierTicketStore = new DistributedCacheServiceTicketStore(); var ticketStore = new TicketStoreWrapper(servierTicketStore); services.AddSingleton <IServiceTicketStore>(servierTicketStore); services.AddSingleton <ITicketStore>(ticketStore); services.Configure <CookieAuthenticationOptions>(options => { options.AutomaticAuthenticate = true; options.AutomaticChallenge = true; options.LoginPath = new PathString("/login"); options.LogoutPath = new PathString("/logout"); options.SessionStore = ticketStore; options.Events = new CookieAuthenticationEvents { OnSigningOut = (context) => { // Single Sign-Out var casUrl = new Uri(Configuration["Authentication:CAS:CasServerUrlBase"]); var serviceUrl = new Uri(context.Request.GetEncodedUrl()).GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped); var redirectUri = UriHelper.BuildAbsolute(casUrl.Scheme, new HostString(casUrl.Host, casUrl.Port), casUrl.LocalPath, "/logout", QueryString.Create("service", serviceUrl)); var logoutRedirectContext = new CookieRedirectContext( context.HttpContext, context.Options, redirectUri, context.Properties ); context.Response.StatusCode = 204; //Prevent RedirectToReturnUrl context.Options.Events.RedirectToLogout(logoutRedirectContext); return(Task.FromResult(0)); } }; }); services.Configure <CasAuthenticationOptions>(options => { options.CasServerUrlBase = Configuration["Authentication:CAS:CasServerUrlBase"]; options.UseTicketStore = true; options.Events = new CasEvents { OnCreatingTicket = (context) => { // first_name, family_name, display_name, email, verified_email var assertion = (context.Principal as ICasPrincipal)?.Assertion; if (assertion == null || !assertion.Attributes.Any()) { return(Task.FromResult(0)); } var identity = context.Principal.Identity as ClaimsIdentity; if (identity == null) { return(Task.FromResult(0)); } var email = assertion.Attributes["email"]?.FirstOrDefault(); if (!string.IsNullOrEmpty(email)) { identity.AddClaim(new Claim(ClaimTypes.Email, email)); } var name = assertion.Attributes["display_name"]?.FirstOrDefault(); if (!string.IsNullOrEmpty(name)) { identity.AddClaim(new Claim(ClaimTypes.Name, name)); } return(Task.FromResult(0)); } }; }); services.Configure <OAuthOptions>(options => { options.AuthenticationScheme = "OAuth"; options.DisplayName = "OAuth"; 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.SaveTokens = 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.HttpContext.RequestAborted); 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 name = attributes.Value <string>("display_name"); if (!string.IsNullOrEmpty(name)) { context.Identity.AddClaim(new Claim(ClaimTypes.Name, name)); } } }; }); }