using System; using System.Security.Claims; using Microsoft.AspNet.Authentication; using Microsoft.AspNet.Authentication.OAuth; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.OptionsModel; using Microsoft.Extensions.WebEncoders; using OAuth.AspNet.AuthServer; using Yavsc.Auth; using Yavsc.Models; namespace Yavsc { public partial class Startup { private void ConfigureOAuthServices(IServiceCollection services) { services.Configure(options => options.SignInScheme = Constants.ExternalAuthenticationSheme); services.Add(ServiceDescriptor.Singleton(typeof(IOptions), typeof(OptionsManager))); // used by the YavscGoogleOAuth middelware (TODO drop it) services.AddTransient(); /* Obsolete: var keyParamsFileInfo = new FileInfo(Configuration["DataProtection:RSAParamFile"]); var keyParams = (keyParamsFileInfo.Exists) ? RSAKeyUtils.GetKeyParameters(keyParamsFileInfo.Name) : RSAKeyUtils.GenerateKeyAndSave(keyParamsFileInfo.Name); key = new RsaSecurityKey(keyParams); services.Configure( to => { to.Audience = Configuration["Site:Audience"]; to.Issuer = Configuration["Site:Authority"]; to.SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.RsaSha256Signature); } ); */ services.AddAuthentication(options => { options.SignInScheme = Constants.ApplicationAuthenticationSheme; }); var protector = new MonoDataProtectionProvider(Configuration["Site:Title"]);; services.AddInstance( protector ); services.AddIdentity( option => { option.User.AllowedUserNameCharacters += " "; option.User.RequireUniqueEmail = true; option.Cookies.ApplicationCookie.DataProtectionProvider = protector; option.Cookies.ApplicationCookie.LoginPath = new PathString(Constants.LoginPath.Substring(1)); option.Cookies.ApplicationCookie.AccessDeniedPath = new PathString(Constants.AccessDeniedPath.Substring(1)); option.Cookies.ApplicationCookie.AutomaticAuthenticate = true; option.Cookies.ApplicationCookie.AuthenticationScheme = Constants.ApplicationAuthenticationSheme; option.Cookies.ApplicationCookieAuthenticationScheme = Constants.ApplicationAuthenticationSheme; option.Cookies.TwoFactorRememberMeCookie.ExpireTimeSpan = TimeSpan.FromDays(30); option.Cookies.TwoFactorRememberMeCookie.DataProtectionProvider = protector; option.Cookies.ExternalCookieAuthenticationScheme = Constants.ExternalAuthenticationSheme; option.Cookies.ExternalCookie.AutomaticAuthenticate = true; option.Cookies.ExternalCookie.AuthenticationScheme = Constants.ExternalAuthenticationSheme; option.Cookies.ExternalCookie.DataProtectionProvider = protector; } ).AddEntityFrameworkStores() .AddTokenProvider>(Constants.EMailFactor) .AddTokenProvider(Constants.DefaultFactor) ; } private void ConfigureOAuthApp(IApplicationBuilder app) { app.UseIdentity(); // External authentication shared cookie: app.UseCookieAuthentication(options => { options.AuthenticationScheme = Constants.ExternalAuthenticationSheme; options.AutomaticAuthenticate = true; options.ExpireTimeSpan = TimeSpan.FromMinutes(5); options.LoginPath = new PathString(Constants.LoginPath.Substring(1)); options.AccessDeniedPath = new PathString(Constants.AccessDeniedPath.Substring(1)); }); var gvents = new OAuthEvents(); var googleOptions = new YavscGoogleOptions { ClientId = Configuration["Authentication:Google:ClientId"], ClientSecret = Configuration["Authentication:Google:ClientSecret"], AccessType = "offline", SaveTokensAsClaims = true, UserInformationEndpoint = "https://www.googleapis.com/plus/v1/people/me", Events = new OAuthEvents { OnCreatingTicket = async context => { using (var serviceScope = app.ApplicationServices.GetRequiredService() .CreateScope()) { var gcontext = context as GoogleOAuthCreatingTicketContext; context.Identity.AddClaim(new Claim(YavscClaimTypes.GoogleUserId, gcontext.GoogleUserId)); var service = serviceScope.ServiceProvider.GetService(); await service.StoreTokenAsync(gcontext.GoogleUserId, context.TokenResponse); } } } }; googleOptions.Scope.Add("https://www.googleapis.com/auth/calendar"); app.UseMiddleware(googleOptions); // Facebook app.UseFacebookAuthentication(options => { options.AppId = Configuration["Authentication:Facebook:AppId"]; options.AppSecret = Configuration["Authentication:Facebook:AppSecret"]; options.Scope.Add("email"); options.UserInformationEndpoint = "https://graph.facebook.com/v2.5/me?fields=id,name,email,first_name,last_name"; }); /* Generic OAuth (here GitHub): options.Notifications = new OAuthAuthenticationNotifications { OnGetUserInformationAsync = async context => { // Get the GitHub user HttpRequestMessage userRequest = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint); userRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken); userRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); HttpResponseMessage userResponse = await context.Backchannel.SendAsync(userRequest, context.HttpContext.RequestAborted); userResponse.EnsureSuccessStatusCode(); var text = await userResponse.Content.ReadAsStringAsync(); JObject user = JObject.Parse(text); var identity = new ClaimsIdentity( context.Options.AuthenticationType, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); JToken value; var id = user.TryGetValue("id", out value) ? value.ToString() : null; if (!string.IsNullOrEmpty(id)) { identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id, ClaimValueTypes.String, context.Options.AuthenticationType)); } var userName = user.TryGetValue("login", out value) ? value.ToString() : null; if (!string.IsNullOrEmpty(userName)) { identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, userName, ClaimValueTypes.String, context.Options.AuthenticationType)); } var name = user.TryGetValue("name", out value) ? value.ToString() : null; if (!string.IsNullOrEmpty(name)) { identity.AddClaim(new Claim("urn:github:name", name, ClaimValueTypes.String, context.Options.AuthenticationType)); } var link = user.TryGetValue("url", out value) ? value.ToString() : null; if (!string.IsNullOrEmpty(link)) { identity.AddClaim(new Claim("urn:github:url", link, ClaimValueTypes.String, context.Options.AuthenticationType)); } context.Identity = identity; } }; */ /* app.UseOAuthAuthorizationServer( options => { options.AuthorizeEndpointPath = new PathString(Constants.AuthorizePath.Substring(1)); options.TokenEndpointPath = new PathString(Constants.TokenPath.Substring(1)); options.ApplicationCanDisplayErrors = true; options.AllowInsecureHttp = true; options.AuthenticationScheme = Constants.ApplicationAuthenticationSheme; options.Provider = new OAuthAuthorizationServerProvider { OnValidateClientRedirectUri = ValidateClientRedirectUri, OnValidateClientAuthentication = ValidateClientAuthentication, OnGrantResourceOwnerCredentials = GrantResourceOwnerCredentials, OnGrantClientCredentials = GrantClientCredetails }; options.AuthorizationCodeProvider = new AuthenticationTokenProvider { OnCreate = CreateAuthenticationCode, OnReceive = ReceiveAuthenticationCode, }; options.RefreshTokenProvider = new AuthenticationTokenProvider { OnCreate = CreateRefreshToken, OnReceive = ReceiveRefreshToken, }; options.AutomaticAuthenticate = true; options.AutomaticChallenge = true; } );*/ } } }