├── .gitignore ├── IdentityServerExternalAuth.sln ├── IdentityServerExternalAuth ├── Configuration │ └── Config.cs ├── Controllers │ └── HomeController.cs ├── Data │ └── DatabaseContext.cs ├── Entities │ ├── ApplicationUser.cs │ └── Provider.cs ├── ExtensionGrant │ └── ExternalAuthenticationGrant.cs ├── Extensions │ └── ServiceCollectionExtensions.cs ├── Helpers │ ├── ProviderDataSource.cs │ ├── ProviderType.cs │ └── QueryBuilder.cs ├── IdentityServerExternalAuth.csproj ├── Interfaces │ ├── IExternalAuthProvider.cs │ ├── IFacebookAuthProvider.cs │ ├── IGitHubAuthProvider.cs │ ├── IGoogleAuthProvider.cs │ ├── ILinkedInAuthProvider.cs │ ├── ITwitterAuthProvider.cs │ └── Processors │ │ ├── IEmailUserProcessor.cs │ │ └── INonEmailUserProcessor.cs ├── Migrations │ ├── 20170918174616_init.Designer.cs │ ├── 20170918174616_init.cs │ ├── 20170918180510_init_users.Designer.cs │ ├── 20170918180510_init_users.cs │ ├── 20170919161256_external_user_table.Designer.cs │ ├── 20170919161256_external_user_table.cs │ ├── 20171017064323_remove_externaluser_table.Designer.cs │ ├── 20171017064323_remove_externaluser_table.cs │ └── DatabaseContextModelSnapshot.cs ├── Processors │ ├── EmailUserProcessor.cs │ └── NonEmailUserProcessor.cs ├── Program.cs ├── Properties │ └── launchSettings.json ├── Providers │ ├── FacebookAuthProvider.cs │ ├── GitHubAuthProvider.cs │ ├── GoogleAuthProvider.cs │ ├── LinkedInAuthProvider.cs │ └── TwitterAuthProvider.cs ├── Repositories │ ├── Interfaces │ │ └── IProviderRepository.cs │ └── ProviderRepository.cs ├── Startup.cs ├── Views │ ├── Home │ │ └── Index.cshtml │ ├── Shared │ │ └── _Layout.cshtml │ └── _ViewStart.cshtml ├── appsettings.json ├── obj │ └── Debug │ │ └── netcoreapp2.0 │ │ ├── IdentityServerExternalAuth.AssemblyInfo.cs │ │ ├── IdentityServerExternalAuth.dll │ │ └── IdentityServerExternalAuth.pdb └── tempkey.rsa ├── README.md ├── Sample ├── Api │ ├── Api.csproj │ ├── Controllers │ │ └── ValuesController.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ └── obj │ │ ├── Debug │ │ └── netcoreapp2.0 │ │ │ └── Api.AssemblyInfo.cs │ │ └── project.assets.json ├── Client │ └── Client │ │ ├── Client.csproj │ │ ├── Controllers │ │ └── ExternalAuthController.cs │ │ ├── Models │ │ └── ExternalUserViewModel.cs │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── Startup.cs │ │ └── obj │ │ └── Debug │ │ └── netcoreapp2.0 │ │ └── Client.csproj.FileListAbsolute.txt └── Google │ └── 01-JavaScriptClient │ └── JavaScriptClient │ ├── JavaScriptClient.csproj │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── Startup.cs │ ├── obj │ └── Debug │ │ └── netcoreapp2.0 │ │ ├── JavaScriptClient.AssemblyInfo.cs │ │ ├── JavaScriptClient.csproj.FileListAbsolute.txt │ │ └── JavaScriptClient.dll │ └── wwwroot │ └── index.html └── screenshots ├── id1.PNG └── id2.PNG /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # Intellij 36 | *.iml 37 | 38 | # Keystore files 39 | *.jks 40 | 41 | # ========================= 42 | # Operating System Files 43 | # ========================= 44 | 45 | # OSX 46 | # ========================= 47 | 48 | .DS_Store 49 | .AppleDouble 50 | .LSOverride 51 | 52 | # Thumbnails 53 | ._* 54 | 55 | # Files that might appear in the root of a volume 56 | .DocumentRevisions-V100 57 | .fseventsd 58 | .Spotlight-V100 59 | .TemporaryItems 60 | .Trashes 61 | .VolumeIcon.icns 62 | 63 | # Directories potentially created on remote AFP share 64 | .AppleDB 65 | .AppleDesktop 66 | Network Trash Folder 67 | Temporary Items 68 | .apdisk 69 | 70 | # Windows 71 | # ========================= 72 | 73 | # Windows image file caches 74 | Thumbs.db 75 | ehthumbs.db 76 | 77 | # Folder config file 78 | Desktop.ini 79 | 80 | # Recycle Bin used on file shares 81 | $RECYCLE.BIN/ 82 | 83 | # Windows Installer files 84 | *.cab 85 | *.msi 86 | *.msm 87 | *.msp 88 | 89 | # Windows shortcuts 90 | *.lnk 91 | *.cache 92 | .vs/config/applicationhost.config 93 | *.suo 94 | .vs/IdentityServerExternalAuth/v15/sqlite3/storage.ide 95 | *.targets 96 | *.props 97 | Sample/Google/01-JavaScriptClient/JavaScriptClient/obj/project.assets.json 98 | Sample/Client/Client/obj/project.assets.json 99 | *.pdb 100 | IdentityServerExternalAuth/obj/Debug/netcoreapp2.0/IdentityServerExternalAuth.dll 101 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26730.12 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IdentityServerExternalAuth", "IdentityServerExternalAuth\IdentityServerExternalAuth.csproj", "{915C519B-8BA0-47CC-924B-33A7C509B605}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Api", "Sample\Api\Api.csproj", "{8484BC00-3DDF-4CB4-9D4B-66762FB530B4}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sample", "Sample", "{A9B88D8B-A516-45F1-9603-59A0C97C1B14}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client", "Sample\Client\Client\Client.csproj", "{9676C3D3-2B66-41BD-BEA0-C3511C17C3D8}" 13 | EndProject 14 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Google", "Google", "{BA4D1A85-656B-4680-BCF5-37E036CFCCA6}" 15 | EndProject 16 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "01-JavaScriptClient", "01-JavaScriptClient", "{405084AA-F076-4A3C-B6AF-B484CAC3BCFF}" 17 | EndProject 18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JavaScriptClient", "Sample\Google\01-JavaScriptClient\JavaScriptClient\JavaScriptClient.csproj", "{A3E80249-1A15-4F6D-984A-E85A53187448}" 19 | EndProject 20 | Global 21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 | Debug|Any CPU = Debug|Any CPU 23 | Release|Any CPU = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 26 | {915C519B-8BA0-47CC-924B-33A7C509B605}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {915C519B-8BA0-47CC-924B-33A7C509B605}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {915C519B-8BA0-47CC-924B-33A7C509B605}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {915C519B-8BA0-47CC-924B-33A7C509B605}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {8484BC00-3DDF-4CB4-9D4B-66762FB530B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {8484BC00-3DDF-4CB4-9D4B-66762FB530B4}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {8484BC00-3DDF-4CB4-9D4B-66762FB530B4}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {8484BC00-3DDF-4CB4-9D4B-66762FB530B4}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {9676C3D3-2B66-41BD-BEA0-C3511C17C3D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {9676C3D3-2B66-41BD-BEA0-C3511C17C3D8}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {9676C3D3-2B66-41BD-BEA0-C3511C17C3D8}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {9676C3D3-2B66-41BD-BEA0-C3511C17C3D8}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {A3E80249-1A15-4F6D-984A-E85A53187448}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {A3E80249-1A15-4F6D-984A-E85A53187448}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {A3E80249-1A15-4F6D-984A-E85A53187448}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {A3E80249-1A15-4F6D-984A-E85A53187448}.Release|Any CPU.Build.0 = Release|Any CPU 42 | EndGlobalSection 43 | GlobalSection(SolutionProperties) = preSolution 44 | HideSolutionNode = FALSE 45 | EndGlobalSection 46 | GlobalSection(NestedProjects) = preSolution 47 | {8484BC00-3DDF-4CB4-9D4B-66762FB530B4} = {A9B88D8B-A516-45F1-9603-59A0C97C1B14} 48 | {9676C3D3-2B66-41BD-BEA0-C3511C17C3D8} = {A9B88D8B-A516-45F1-9603-59A0C97C1B14} 49 | {BA4D1A85-656B-4680-BCF5-37E036CFCCA6} = {A9B88D8B-A516-45F1-9603-59A0C97C1B14} 50 | {405084AA-F076-4A3C-B6AF-B484CAC3BCFF} = {BA4D1A85-656B-4680-BCF5-37E036CFCCA6} 51 | {A3E80249-1A15-4F6D-984A-E85A53187448} = {405084AA-F076-4A3C-B6AF-B484CAC3BCFF} 52 | EndGlobalSection 53 | GlobalSection(ExtensibilityGlobals) = postSolution 54 | SolutionGuid = {FD254A9B-5467-497F-B5B3-C35D032239B5} 55 | EndGlobalSection 56 | EndGlobal 57 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Configuration/Config.cs: -------------------------------------------------------------------------------- 1 | using IdentityModel; 2 | using IdentityServer4.Models; 3 | using IdentityServer4.Test; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Security.Claims; 8 | using System.Threading.Tasks; 9 | using static IdentityServer4.IdentityServerConstants; 10 | 11 | namespace IdentityServerExternalAuth.Configuration 12 | { 13 | public class Config 14 | { 15 | // scopes define the resources in your systems 16 | 17 | public static IEnumerable GetIdentityResources() 18 | { 19 | return new List 20 | { 21 | new IdentityResources.OpenId(), 22 | new IdentityResources.Profile(), 23 | new IdentityResources.Email() 24 | }; 25 | } 26 | 27 | public static IEnumerable GetApiResources() 28 | { 29 | return new List 30 | { 31 | new ApiResource("Test.WebApi","Test WebApi") 32 | }; 33 | } 34 | 35 | // clients want to access resources (aka scopes) 36 | public static IEnumerable GetClients() 37 | { 38 | // client credentials client 39 | return new List 40 | { 41 | new Client 42 | { 43 | ClientId = "Test.Client", 44 | ClientName = "LDSCore", 45 | AllowedGrantTypes = new[] {GrantType.ResourceOwnerPassword,"external"}, 46 | ClientSecrets = 47 | { 48 | new Secret("secret".Sha256()) 49 | }, 50 | AllowedScopes = { 51 | "Test.WebApi", 52 | StandardScopes.Email, 53 | StandardScopes.OpenId, 54 | StandardScopes.Profile 55 | }, 56 | AccessTokenType = AccessTokenType.Jwt, 57 | AlwaysIncludeUserClaimsInIdToken = true, 58 | AccessTokenLifetime = 86400, 59 | AllowOfflineAccess = true, 60 | IdentityTokenLifetime = 86400, 61 | AlwaysSendClientClaims = true, 62 | Enabled = true, 63 | } 64 | }; 65 | } 66 | 67 | public static List GetUsers() 68 | { 69 | return new List 70 | { 71 | new TestUser 72 | { 73 | SubjectId = "1", 74 | Username = "alice", 75 | Password = "password", 76 | Claims = new List 77 | { 78 | new Claim(ClaimTypes.Role, "Admin"), 79 | new Claim(JwtClaimTypes.Name, "jwtName") 80 | } 81 | }, 82 | new TestUser 83 | { 84 | SubjectId = "2", 85 | Username = "bob", 86 | Password = "password" 87 | } 88 | }; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using IdentityServerExternalAuth.Repositories.Interfaces; 2 | using Microsoft.AspNetCore.Mvc; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace IdentityServerExternalAuth.Controllers 9 | { 10 | public class HomeController:Controller 11 | { 12 | private readonly IProviderRepository _providersRepository; 13 | 14 | public HomeController(IProviderRepository providersRepository) 15 | { 16 | _providersRepository = providersRepository ?? throw new ArgumentNullException(nameof(providersRepository)); 17 | } 18 | public IActionResult Index() 19 | { 20 | ViewBag.Providers = _providersRepository.Get(); 21 | return View(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Data/DatabaseContext.cs: -------------------------------------------------------------------------------- 1 | using IdentityServerExternalAuth.Entities; 2 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace IdentityServerExternalAuth.Data 10 | { 11 | public class DatabaseContext:IdentityDbContext 12 | { 13 | public DatabaseContext(DbContextOptions options) 14 | : base(options) 15 | { 16 | 17 | 18 | } 19 | 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Entities/ApplicationUser.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Identity; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace IdentityServerExternalAuth.Entities 8 | { 9 | public class ApplicationUser:IdentityUser 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Entities/Provider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace IdentityServerExternalAuth.Entities 7 | { 8 | public class Provider 9 | { 10 | public int ProviderId { get; set; } 11 | public string Name { get; set; } 12 | public string UserInfoEndPoint { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/ExtensionGrant/ExternalAuthenticationGrant.cs: -------------------------------------------------------------------------------- 1 | using IdentityServer4.Models; 2 | using IdentityServer4.Validation; 3 | using IdentityServerExternalAuth.Entities; 4 | using IdentityServerExternalAuth.Helpers; 5 | using IdentityServerExternalAuth.Interfaces; 6 | using IdentityServerExternalAuth.Interfaces.Processors; 7 | using IdentityServerExternalAuth.Repositories.Interfaces; 8 | using Microsoft.AspNetCore.Identity; 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Linq; 12 | using System.Threading.Tasks; 13 | 14 | namespace IdentityServerExternalAuth.ExtensionGrant 15 | { 16 | public class ExternalAuthenticationGrant : IExtensionGrantValidator where TUser : IdentityUser, new() 17 | { 18 | private readonly UserManager _userManager; 19 | private readonly IProviderRepository _providerRepository; 20 | private readonly IFacebookAuthProvider _facebookAuthProvider; 21 | private readonly IGoogleAuthProvider _googleAuthProvider; 22 | private readonly ITwitterAuthProvider _twitterAuthProvider; 23 | private readonly ILinkedInAuthProvider _linkedAuthProvider; 24 | private readonly IGitHubAuthProvider _githubAuthProvider; 25 | private readonly INonEmailUserProcessor _nonEmailUserProcessor; 26 | private readonly IEmailUserProcessor _emailUserProcessor; 27 | public ExternalAuthenticationGrant( 28 | UserManager userManager, 29 | IProviderRepository providerRepository, 30 | IFacebookAuthProvider facebookAuthProvider, 31 | IGoogleAuthProvider googleAuthProvider, 32 | ITwitterAuthProvider twitterAuthProvider, 33 | ILinkedInAuthProvider linkeInAuthProvider, 34 | IGitHubAuthProvider githubAuthProvider, 35 | INonEmailUserProcessor nonEmailUserProcessor, 36 | IEmailUserProcessor emailUserProcessor 37 | ) 38 | { 39 | _userManager = userManager ?? throw new ArgumentNullException(nameof(userManager)); 40 | _providerRepository = providerRepository?? throw new ArgumentNullException(nameof(providerRepository)); 41 | _facebookAuthProvider = facebookAuthProvider ?? throw new ArgumentNullException(nameof(facebookAuthProvider)); 42 | _googleAuthProvider = googleAuthProvider ?? throw new ArgumentNullException(nameof(googleAuthProvider)); 43 | _twitterAuthProvider = twitterAuthProvider ?? throw new ArgumentNullException(nameof(twitterAuthProvider)); 44 | _linkedAuthProvider = linkeInAuthProvider ?? throw new ArgumentNullException(nameof(linkeInAuthProvider)); 45 | _githubAuthProvider = githubAuthProvider ?? throw new ArgumentNullException(nameof(githubAuthProvider)); 46 | _nonEmailUserProcessor = nonEmailUserProcessor ?? throw new ArgumentNullException(nameof(nonEmailUserProcessor)); 47 | _emailUserProcessor = emailUserProcessor ?? throw new ArgumentNullException(nameof(nonEmailUserProcessor)); 48 | 49 | _providers = new Dictionary 50 | { 51 | {ProviderType.Facebook, _facebookAuthProvider}, 52 | {ProviderType.Google, _googleAuthProvider}, 53 | {ProviderType.Twitter, _twitterAuthProvider}, 54 | {ProviderType.LinkedIn, _linkedAuthProvider} 55 | }; 56 | } 57 | 58 | 59 | private Dictionary _providers; 60 | 61 | public string GrantType => "external"; 62 | 63 | 64 | 65 | public async Task ValidateAsync(ExtensionGrantValidationContext context) 66 | { 67 | var provider = context.Request.Raw.Get("provider"); 68 | if (string.IsNullOrWhiteSpace(provider)) 69 | { 70 | context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, "invalid provider"); 71 | return; 72 | } 73 | 74 | 75 | var token = context.Request.Raw.Get("external_token"); 76 | if(string.IsNullOrWhiteSpace(token)) 77 | { 78 | context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, "invalid external token"); 79 | return; 80 | } 81 | 82 | var requestEmail = context.Request.Raw.Get("email"); 83 | 84 | var providerType=(ProviderType)Enum.Parse(typeof(ProviderType), provider,true); 85 | 86 | if (!Enum.IsDefined(typeof(ProviderType), providerType)) 87 | { 88 | context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, "invalid provider"); 89 | return; 90 | } 91 | 92 | var userInfo = _providers[providerType].GetUserInfo(token); 93 | 94 | if(userInfo == null) 95 | { 96 | context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, "couldn't retrieve user info from specified provider, please make sure that access token is not expired."); 97 | return; 98 | } 99 | 100 | var externalId = userInfo.Value("id"); 101 | if (!string.IsNullOrWhiteSpace(externalId)) 102 | { 103 | 104 | var user = await _userManager.FindByLoginAsync(provider, externalId); 105 | if(null != user) 106 | { 107 | user = await _userManager.FindByIdAsync(user.Id); 108 | var userClaims = await _userManager.GetClaimsAsync(user); 109 | context.Result = new GrantValidationResult(user.Id, provider, userClaims, provider, null); 110 | return; 111 | } 112 | } 113 | 114 | if (string.IsNullOrWhiteSpace(requestEmail)) 115 | { 116 | context.Result = await _nonEmailUserProcessor.ProcessAsync(userInfo, provider); 117 | return; 118 | } 119 | 120 | context.Result = await _emailUserProcessor.ProcessAsync(userInfo, requestEmail, provider); 121 | return; 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Extensions/ServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using IdentityServer4.Validation; 2 | using IdentityServerExternalAuth.Configuration; 3 | using IdentityServerExternalAuth.Data; 4 | using IdentityServerExternalAuth.Entities; 5 | using IdentityServerExternalAuth.ExtensionGrant; 6 | using IdentityServerExternalAuth.Interfaces; 7 | using IdentityServerExternalAuth.Interfaces.Processors; 8 | using IdentityServerExternalAuth.Processors; 9 | using IdentityServerExternalAuth.Providers; 10 | using IdentityServerExternalAuth.Repositories; 11 | using IdentityServerExternalAuth.Repositories.Interfaces; 12 | using Microsoft.AspNetCore.Identity; 13 | using Microsoft.EntityFrameworkCore; 14 | using Microsoft.Extensions.DependencyInjection; 15 | using System; 16 | using System.Collections.Generic; 17 | using System.Linq; 18 | using System.Net.Http; 19 | using System.Threading.Tasks; 20 | 21 | namespace IdentityServerExternalAuth.Extensions 22 | { 23 | public static class ServiceCollectionExtensions 24 | { 25 | public static IServiceCollection AddDatabaseConfiguration(this IServiceCollection services,string connectionString) 26 | { 27 | services.AddDbContext(cfg => cfg.UseSqlServer(connectionString)); 28 | services.AddIdentity() 29 | .AddEntityFrameworkStores() 30 | .AddDefaultTokenProviders(); 31 | 32 | return services; 33 | } 34 | 35 | public static IServiceCollection AddIdentityServerConfig(this IServiceCollection services) 36 | { 37 | services.AddIdentityServer() 38 | .AddDeveloperSigningCredential() 39 | .AddInMemoryApiResources(Config.GetApiResources()) 40 | .AddInMemoryClients(Config.GetClients()) 41 | .AddInMemoryIdentityResources(Config.GetIdentityResources()) 42 | .AddAspNetIdentity(); 43 | 44 | return services; 45 | } 46 | 47 | public static IServiceCollection AddServices(this IServiceCollection services) where TUser:IdentityUser,new() 48 | { 49 | services.AddScoped>(); 50 | services.AddScoped>(); 51 | services.AddScoped>(); 52 | services.AddSingleton(); 53 | return services; 54 | } 55 | 56 | public static IServiceCollection AddRepositories(this IServiceCollection services) 57 | { 58 | 59 | services.AddScoped(); 60 | return services; 61 | } 62 | 63 | public static IServiceCollection AddProviders(this IServiceCollection services) where TUser: IdentityUser,new() 64 | { 65 | services.AddTransient>(); 66 | services.AddTransient>(); 67 | services.AddTransient>(); 68 | services.AddTransient>(); 69 | services.AddTransient>(); 70 | return services; 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Helpers/ProviderDataSource.cs: -------------------------------------------------------------------------------- 1 | using IdentityServerExternalAuth.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace IdentityServerExternalAuth.Helpers 8 | { 9 | public class ProviderDataSource 10 | { 11 | public static IEnumerable GetProviders() 12 | { 13 | return new List 14 | { 15 | new Provider 16 | { 17 | ProviderId = 1, 18 | Name = "Facebook", 19 | UserInfoEndPoint = "https://graph.facebook.com/v2.8/me" 20 | }, 21 | new Provider 22 | { 23 | ProviderId = 2, 24 | Name = "Google", 25 | UserInfoEndPoint = "https://www.googleapis.com/oauth2/v2/userinfo" 26 | }, 27 | new Provider 28 | { 29 | ProviderId = 3, 30 | Name = "Twitter", 31 | UserInfoEndPoint = "https://api.twitter.com/1.1/account/verify_credentials.json" 32 | }, 33 | new Provider 34 | { 35 | ProviderId = 4, 36 | Name="LinkedIn", 37 | UserInfoEndPoint = "https://api.linkedin.com/v1/people/~:(id,email-address,first-name,last-name,location,industry,picture-url)?" 38 | }, 39 | new Provider 40 | { 41 | ProviderId = 5, 42 | Name = "GitHub", 43 | UserInfoEndPoint = "https://api.github.com/user" 44 | } 45 | }; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Helpers/ProviderType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace IdentityServerExternalAuth.Helpers 7 | { 8 | public enum ProviderType 9 | { 10 | Facebook, 11 | Twitter, 12 | Google, 13 | LinkedIn, 14 | GitHub 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Helpers/QueryBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Security.Cryptography; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace IdentityServerExternalAuth.Helpers 9 | { 10 | public static class QueryBuilder 11 | { 12 | public static string FacebookUserInfoQuery(List fields, string token) 13 | { 14 | return "?fields=" + String.Join(",", fields) + "&access_token=" + token; 15 | } 16 | 17 | public static string GetQuery(Dictionary values, ProviderType provider) 18 | { 19 | switch (provider) 20 | { 21 | case ProviderType.Facebook: 22 | 23 | try 24 | { 25 | var fields = values["fields"]; 26 | var access_token = values["access_token"]; 27 | return $"?fields={fields}&access_token={access_token}"; 28 | } 29 | catch (Exception ex) 30 | { 31 | throw ex; 32 | } 33 | 34 | case ProviderType.Twitter: 35 | try 36 | { 37 | var token = values["tokenString"]; 38 | var userInfoEndpoint = values["endpoint"]; 39 | 40 | var tokenString = token.Split('&').ToDictionary(x => x.Split('=')[0], x => x.Split('=')[1]); 41 | if (tokenString.Count < 4) return null; 42 | 43 | var oauth_consumer_key = tokenString["oauth_consumer_key"]; 44 | var consumerSecret = tokenString["oauth_consumer_secret"]; 45 | var oauth_token_secret = tokenString["oauth_token_secret"]; 46 | var oauth_token = tokenString["oauth_token"]; 47 | var oauth_version = "1.0"; 48 | var oauth_signature_method = "HMAC-SHA1"; 49 | string oauth_nonce = Convert.ToBase64String(new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString())); 50 | 51 | TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); 52 | string oauth_timestamp = Convert.ToInt64(ts.TotalSeconds).ToString(); 53 | 54 | SortedDictionary sd = new SortedDictionary(); 55 | 56 | sd.Add("oauth_version", oauth_version); 57 | sd.Add("oauth_consumer_key", oauth_consumer_key); 58 | sd.Add("oauth_nonce", oauth_nonce); 59 | sd.Add("oauth_signature_method", oauth_signature_method); 60 | sd.Add("oauth_timestamp", oauth_timestamp); 61 | sd.Add("oauth_token", oauth_token); 62 | 63 | //GS - Build the signature string 64 | string baseString = String.Empty; 65 | baseString += "GET" + "&"; 66 | baseString += Uri.EscapeDataString(userInfoEndpoint) + "&"; 67 | foreach (KeyValuePair entry in sd) 68 | { 69 | baseString += Uri.EscapeDataString(entry.Key + "=" + entry.Value + "&"); 70 | } 71 | 72 | baseString = baseString.Substring(0, baseString.Length - 3); 73 | 74 | string signingKey = Uri.EscapeDataString(consumerSecret) + "&" + Uri.EscapeDataString(oauth_token_secret); 75 | 76 | HMACSHA1 hasher = new HMACSHA1(new ASCIIEncoding().GetBytes(signingKey)); 77 | 78 | string signatureString = Convert.ToBase64String(hasher.ComputeHash(new ASCIIEncoding().GetBytes(baseString))); 79 | 80 | //prepare the request 81 | string authorizationHeaderParams = String.Empty; 82 | authorizationHeaderParams += "OAuth "; 83 | authorizationHeaderParams += "oauth_nonce=" + "\"" + 84 | Uri.EscapeDataString(oauth_nonce) + "\","; 85 | 86 | authorizationHeaderParams += 87 | "oauth_signature_method=" + "\"" + 88 | Uri.EscapeDataString(oauth_signature_method) + 89 | "\","; 90 | 91 | authorizationHeaderParams += "oauth_timestamp=" + "\"" + 92 | Uri.EscapeDataString(oauth_timestamp) + "\","; 93 | 94 | authorizationHeaderParams += "oauth_consumer_key=" 95 | + "\"" + Uri.EscapeDataString( 96 | oauth_consumer_key) + "\","; 97 | 98 | authorizationHeaderParams += "oauth_token=" + "\"" + 99 | Uri.EscapeDataString(oauth_token) + "\","; 100 | 101 | authorizationHeaderParams += "oauth_signature=" + "\"" 102 | + Uri.EscapeDataString(signatureString) + "\","; 103 | 104 | authorizationHeaderParams += "oauth_version=" + "\"" + 105 | Uri.EscapeDataString(oauth_version) + "\""; 106 | 107 | return authorizationHeaderParams; 108 | } 109 | catch (Exception ex) 110 | { 111 | throw ex; 112 | } 113 | 114 | case ProviderType.Google: 115 | 116 | var google_access_token = values["token"]; 117 | return $"?access_token={google_access_token}"; 118 | 119 | default: 120 | return null; 121 | } 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/IdentityServerExternalAuth.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | All 19 | 20 | 21 | 22 | All 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Interfaces/IExternalAuthProvider.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace IdentityServerExternalAuth.Interfaces 8 | { 9 | public interface IExternalAuthProvider 10 | { 11 | JObject GetUserInfo(string accessToken); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Interfaces/IFacebookAuthProvider.cs: -------------------------------------------------------------------------------- 1 | using IdentityServerExternalAuth.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace IdentityServerExternalAuth.Interfaces 8 | { 9 | public interface IFacebookAuthProvider : IExternalAuthProvider 10 | { 11 | Provider Provider { get; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Interfaces/IGitHubAuthProvider.cs: -------------------------------------------------------------------------------- 1 | using IdentityServerExternalAuth.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace IdentityServerExternalAuth.Interfaces 8 | { 9 | public interface IGitHubAuthProvider : IExternalAuthProvider 10 | { 11 | Provider Provider { get; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Interfaces/IGoogleAuthProvider.cs: -------------------------------------------------------------------------------- 1 | using IdentityServerExternalAuth.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace IdentityServerExternalAuth.Interfaces 8 | { 9 | public interface IGoogleAuthProvider:IExternalAuthProvider 10 | { 11 | Provider Provider { get; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Interfaces/ILinkedInAuthProvider.cs: -------------------------------------------------------------------------------- 1 | using IdentityServerExternalAuth.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace IdentityServerExternalAuth.Interfaces 8 | { 9 | public interface ILinkedInAuthProvider : IExternalAuthProvider 10 | { 11 | Provider Provider { get; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Interfaces/ITwitterAuthProvider.cs: -------------------------------------------------------------------------------- 1 | using IdentityServerExternalAuth.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace IdentityServerExternalAuth.Interfaces 8 | { 9 | public interface ITwitterAuthProvider : IExternalAuthProvider 10 | { 11 | Provider Provider { get; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Interfaces/Processors/IEmailUserProcessor.cs: -------------------------------------------------------------------------------- 1 | using IdentityServer4.Validation; 2 | using Newtonsoft.Json.Linq; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace IdentityServerExternalAuth.Interfaces.Processors 9 | { 10 | public interface IEmailUserProcessor 11 | { 12 | Task ProcessAsync(JObject userInfo,string email, string provider); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Interfaces/Processors/INonEmailUserProcessor.cs: -------------------------------------------------------------------------------- 1 | using IdentityServer4.Validation; 2 | using Newtonsoft.Json.Linq; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace IdentityServerExternalAuth.Interfaces.Processors 9 | { 10 | public interface INonEmailUserProcessor 11 | { 12 | Task ProcessAsync(JObject userInfo,string provider); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Migrations/20170918174616_init.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using IdentityServerExternalAuth.Data; 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore.Infrastructure; 5 | using Microsoft.EntityFrameworkCore.Metadata; 6 | using Microsoft.EntityFrameworkCore.Migrations; 7 | using Microsoft.EntityFrameworkCore.Storage; 8 | using Microsoft.EntityFrameworkCore.Storage.Internal; 9 | using System; 10 | 11 | namespace IdentityServerExternalAuth.Migrations 12 | { 13 | [DbContext(typeof(DatabaseContext))] 14 | [Migration("20170918174616_init")] 15 | partial class init 16 | { 17 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 18 | { 19 | #pragma warning disable 612, 618 20 | modelBuilder 21 | .HasAnnotation("ProductVersion", "2.0.0-rtm-26452") 22 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 23 | 24 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => 25 | { 26 | b.Property("Id") 27 | .ValueGeneratedOnAdd(); 28 | 29 | b.Property("ConcurrencyStamp") 30 | .IsConcurrencyToken(); 31 | 32 | b.Property("Name") 33 | .HasMaxLength(256); 34 | 35 | b.Property("NormalizedName") 36 | .HasMaxLength(256); 37 | 38 | b.HasKey("Id"); 39 | 40 | b.HasIndex("NormalizedName") 41 | .IsUnique() 42 | .HasName("RoleNameIndex") 43 | .HasFilter("[NormalizedName] IS NOT NULL"); 44 | 45 | b.ToTable("AspNetRoles"); 46 | }); 47 | 48 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => 49 | { 50 | b.Property("Id") 51 | .ValueGeneratedOnAdd(); 52 | 53 | b.Property("ClaimType"); 54 | 55 | b.Property("ClaimValue"); 56 | 57 | b.Property("RoleId") 58 | .IsRequired(); 59 | 60 | b.HasKey("Id"); 61 | 62 | b.HasIndex("RoleId"); 63 | 64 | b.ToTable("AspNetRoleClaims"); 65 | }); 66 | 67 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => 68 | { 69 | b.Property("Id") 70 | .ValueGeneratedOnAdd(); 71 | 72 | b.Property("AccessFailedCount"); 73 | 74 | b.Property("ConcurrencyStamp") 75 | .IsConcurrencyToken(); 76 | 77 | b.Property("Email") 78 | .HasMaxLength(256); 79 | 80 | b.Property("EmailConfirmed"); 81 | 82 | b.Property("LockoutEnabled"); 83 | 84 | b.Property("LockoutEnd"); 85 | 86 | b.Property("NormalizedEmail") 87 | .HasMaxLength(256); 88 | 89 | b.Property("NormalizedUserName") 90 | .HasMaxLength(256); 91 | 92 | b.Property("PasswordHash"); 93 | 94 | b.Property("PhoneNumber"); 95 | 96 | b.Property("PhoneNumberConfirmed"); 97 | 98 | b.Property("SecurityStamp"); 99 | 100 | b.Property("TwoFactorEnabled"); 101 | 102 | b.Property("UserName") 103 | .HasMaxLength(256); 104 | 105 | b.HasKey("Id"); 106 | 107 | b.HasIndex("NormalizedEmail") 108 | .HasName("EmailIndex"); 109 | 110 | b.HasIndex("NormalizedUserName") 111 | .IsUnique() 112 | .HasName("UserNameIndex") 113 | .HasFilter("[NormalizedUserName] IS NOT NULL"); 114 | 115 | b.ToTable("AspNetUsers"); 116 | }); 117 | 118 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => 119 | { 120 | b.Property("Id") 121 | .ValueGeneratedOnAdd(); 122 | 123 | b.Property("ClaimType"); 124 | 125 | b.Property("ClaimValue"); 126 | 127 | b.Property("UserId") 128 | .IsRequired(); 129 | 130 | b.HasKey("Id"); 131 | 132 | b.HasIndex("UserId"); 133 | 134 | b.ToTable("AspNetUserClaims"); 135 | }); 136 | 137 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => 138 | { 139 | b.Property("LoginProvider"); 140 | 141 | b.Property("ProviderKey"); 142 | 143 | b.Property("ProviderDisplayName"); 144 | 145 | b.Property("UserId") 146 | .IsRequired(); 147 | 148 | b.HasKey("LoginProvider", "ProviderKey"); 149 | 150 | b.HasIndex("UserId"); 151 | 152 | b.ToTable("AspNetUserLogins"); 153 | }); 154 | 155 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => 156 | { 157 | b.Property("UserId"); 158 | 159 | b.Property("RoleId"); 160 | 161 | b.HasKey("UserId", "RoleId"); 162 | 163 | b.HasIndex("RoleId"); 164 | 165 | b.ToTable("AspNetUserRoles"); 166 | }); 167 | 168 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => 169 | { 170 | b.Property("UserId"); 171 | 172 | b.Property("LoginProvider"); 173 | 174 | b.Property("Name"); 175 | 176 | b.Property("Value"); 177 | 178 | b.HasKey("UserId", "LoginProvider", "Name"); 179 | 180 | b.ToTable("AspNetUserTokens"); 181 | }); 182 | 183 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => 184 | { 185 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") 186 | .WithMany() 187 | .HasForeignKey("RoleId") 188 | .OnDelete(DeleteBehavior.Cascade); 189 | }); 190 | 191 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => 192 | { 193 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser") 194 | .WithMany() 195 | .HasForeignKey("UserId") 196 | .OnDelete(DeleteBehavior.Cascade); 197 | }); 198 | 199 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => 200 | { 201 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser") 202 | .WithMany() 203 | .HasForeignKey("UserId") 204 | .OnDelete(DeleteBehavior.Cascade); 205 | }); 206 | 207 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => 208 | { 209 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") 210 | .WithMany() 211 | .HasForeignKey("RoleId") 212 | .OnDelete(DeleteBehavior.Cascade); 213 | 214 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser") 215 | .WithMany() 216 | .HasForeignKey("UserId") 217 | .OnDelete(DeleteBehavior.Cascade); 218 | }); 219 | 220 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => 221 | { 222 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser") 223 | .WithMany() 224 | .HasForeignKey("UserId") 225 | .OnDelete(DeleteBehavior.Cascade); 226 | }); 227 | #pragma warning restore 612, 618 228 | } 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Migrations/20170918174616_init.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Metadata; 2 | using Microsoft.EntityFrameworkCore.Migrations; 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | namespace IdentityServerExternalAuth.Migrations 7 | { 8 | public partial class init : Migration 9 | { 10 | protected override void Up(MigrationBuilder migrationBuilder) 11 | { 12 | migrationBuilder.CreateTable( 13 | name: "AspNetRoles", 14 | columns: table => new 15 | { 16 | Id = table.Column(type: "nvarchar(450)", nullable: false), 17 | ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true), 18 | Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), 19 | NormalizedName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true) 20 | }, 21 | constraints: table => 22 | { 23 | table.PrimaryKey("PK_AspNetRoles", x => x.Id); 24 | }); 25 | 26 | migrationBuilder.CreateTable( 27 | name: "AspNetUsers", 28 | columns: table => new 29 | { 30 | Id = table.Column(type: "nvarchar(450)", nullable: false), 31 | AccessFailedCount = table.Column(type: "int", nullable: false), 32 | ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true), 33 | Email = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), 34 | EmailConfirmed = table.Column(type: "bit", nullable: false), 35 | LockoutEnabled = table.Column(type: "bit", nullable: false), 36 | LockoutEnd = table.Column(type: "datetimeoffset", nullable: true), 37 | NormalizedEmail = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), 38 | NormalizedUserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), 39 | PasswordHash = table.Column(type: "nvarchar(max)", nullable: true), 40 | PhoneNumber = table.Column(type: "nvarchar(max)", nullable: true), 41 | PhoneNumberConfirmed = table.Column(type: "bit", nullable: false), 42 | SecurityStamp = table.Column(type: "nvarchar(max)", nullable: true), 43 | TwoFactorEnabled = table.Column(type: "bit", nullable: false), 44 | UserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true) 45 | }, 46 | constraints: table => 47 | { 48 | table.PrimaryKey("PK_AspNetUsers", x => x.Id); 49 | }); 50 | 51 | migrationBuilder.CreateTable( 52 | name: "AspNetRoleClaims", 53 | columns: table => new 54 | { 55 | Id = table.Column(type: "int", nullable: false) 56 | .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), 57 | ClaimType = table.Column(type: "nvarchar(max)", nullable: true), 58 | ClaimValue = table.Column(type: "nvarchar(max)", nullable: true), 59 | RoleId = table.Column(type: "nvarchar(450)", nullable: false) 60 | }, 61 | constraints: table => 62 | { 63 | table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); 64 | table.ForeignKey( 65 | name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", 66 | column: x => x.RoleId, 67 | principalTable: "AspNetRoles", 68 | principalColumn: "Id", 69 | onDelete: ReferentialAction.Cascade); 70 | }); 71 | 72 | migrationBuilder.CreateTable( 73 | name: "AspNetUserClaims", 74 | columns: table => new 75 | { 76 | Id = table.Column(type: "int", nullable: false) 77 | .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), 78 | ClaimType = table.Column(type: "nvarchar(max)", nullable: true), 79 | ClaimValue = table.Column(type: "nvarchar(max)", nullable: true), 80 | UserId = table.Column(type: "nvarchar(450)", nullable: false) 81 | }, 82 | constraints: table => 83 | { 84 | table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); 85 | table.ForeignKey( 86 | name: "FK_AspNetUserClaims_AspNetUsers_UserId", 87 | column: x => x.UserId, 88 | principalTable: "AspNetUsers", 89 | principalColumn: "Id", 90 | onDelete: ReferentialAction.Cascade); 91 | }); 92 | 93 | migrationBuilder.CreateTable( 94 | name: "AspNetUserLogins", 95 | columns: table => new 96 | { 97 | LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), 98 | ProviderKey = table.Column(type: "nvarchar(450)", nullable: false), 99 | ProviderDisplayName = table.Column(type: "nvarchar(max)", nullable: true), 100 | UserId = table.Column(type: "nvarchar(450)", nullable: false) 101 | }, 102 | constraints: table => 103 | { 104 | table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); 105 | table.ForeignKey( 106 | name: "FK_AspNetUserLogins_AspNetUsers_UserId", 107 | column: x => x.UserId, 108 | principalTable: "AspNetUsers", 109 | principalColumn: "Id", 110 | onDelete: ReferentialAction.Cascade); 111 | }); 112 | 113 | migrationBuilder.CreateTable( 114 | name: "AspNetUserRoles", 115 | columns: table => new 116 | { 117 | UserId = table.Column(type: "nvarchar(450)", nullable: false), 118 | RoleId = table.Column(type: "nvarchar(450)", nullable: false) 119 | }, 120 | constraints: table => 121 | { 122 | table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); 123 | table.ForeignKey( 124 | name: "FK_AspNetUserRoles_AspNetRoles_RoleId", 125 | column: x => x.RoleId, 126 | principalTable: "AspNetRoles", 127 | principalColumn: "Id", 128 | onDelete: ReferentialAction.Cascade); 129 | table.ForeignKey( 130 | name: "FK_AspNetUserRoles_AspNetUsers_UserId", 131 | column: x => x.UserId, 132 | principalTable: "AspNetUsers", 133 | principalColumn: "Id", 134 | onDelete: ReferentialAction.Cascade); 135 | }); 136 | 137 | migrationBuilder.CreateTable( 138 | name: "AspNetUserTokens", 139 | columns: table => new 140 | { 141 | UserId = table.Column(type: "nvarchar(450)", nullable: false), 142 | LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), 143 | Name = table.Column(type: "nvarchar(450)", nullable: false), 144 | Value = table.Column(type: "nvarchar(max)", nullable: true) 145 | }, 146 | constraints: table => 147 | { 148 | table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); 149 | table.ForeignKey( 150 | name: "FK_AspNetUserTokens_AspNetUsers_UserId", 151 | column: x => x.UserId, 152 | principalTable: "AspNetUsers", 153 | principalColumn: "Id", 154 | onDelete: ReferentialAction.Cascade); 155 | }); 156 | 157 | migrationBuilder.CreateIndex( 158 | name: "IX_AspNetRoleClaims_RoleId", 159 | table: "AspNetRoleClaims", 160 | column: "RoleId"); 161 | 162 | migrationBuilder.CreateIndex( 163 | name: "RoleNameIndex", 164 | table: "AspNetRoles", 165 | column: "NormalizedName", 166 | unique: true, 167 | filter: "[NormalizedName] IS NOT NULL"); 168 | 169 | migrationBuilder.CreateIndex( 170 | name: "IX_AspNetUserClaims_UserId", 171 | table: "AspNetUserClaims", 172 | column: "UserId"); 173 | 174 | migrationBuilder.CreateIndex( 175 | name: "IX_AspNetUserLogins_UserId", 176 | table: "AspNetUserLogins", 177 | column: "UserId"); 178 | 179 | migrationBuilder.CreateIndex( 180 | name: "IX_AspNetUserRoles_RoleId", 181 | table: "AspNetUserRoles", 182 | column: "RoleId"); 183 | 184 | migrationBuilder.CreateIndex( 185 | name: "EmailIndex", 186 | table: "AspNetUsers", 187 | column: "NormalizedEmail"); 188 | 189 | migrationBuilder.CreateIndex( 190 | name: "UserNameIndex", 191 | table: "AspNetUsers", 192 | column: "NormalizedUserName", 193 | unique: true, 194 | filter: "[NormalizedUserName] IS NOT NULL"); 195 | } 196 | 197 | protected override void Down(MigrationBuilder migrationBuilder) 198 | { 199 | migrationBuilder.DropTable( 200 | name: "AspNetRoleClaims"); 201 | 202 | migrationBuilder.DropTable( 203 | name: "AspNetUserClaims"); 204 | 205 | migrationBuilder.DropTable( 206 | name: "AspNetUserLogins"); 207 | 208 | migrationBuilder.DropTable( 209 | name: "AspNetUserRoles"); 210 | 211 | migrationBuilder.DropTable( 212 | name: "AspNetUserTokens"); 213 | 214 | migrationBuilder.DropTable( 215 | name: "AspNetRoles"); 216 | 217 | migrationBuilder.DropTable( 218 | name: "AspNetUsers"); 219 | } 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Migrations/20170918180510_init_users.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using IdentityServerExternalAuth.Data; 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore.Infrastructure; 5 | using Microsoft.EntityFrameworkCore.Metadata; 6 | using Microsoft.EntityFrameworkCore.Migrations; 7 | using Microsoft.EntityFrameworkCore.Storage; 8 | using Microsoft.EntityFrameworkCore.Storage.Internal; 9 | using System; 10 | 11 | namespace IdentityServerExternalAuth.Migrations 12 | { 13 | [DbContext(typeof(DatabaseContext))] 14 | [Migration("20170918180510_init_users")] 15 | partial class init_users 16 | { 17 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 18 | { 19 | #pragma warning disable 612, 618 20 | modelBuilder 21 | .HasAnnotation("ProductVersion", "2.0.0-rtm-26452") 22 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 23 | 24 | modelBuilder.Entity("IdentityServerExternalAuth.Entities.ApplicationUser", b => 25 | { 26 | b.Property("Id") 27 | .ValueGeneratedOnAdd(); 28 | 29 | b.Property("AccessFailedCount"); 30 | 31 | b.Property("ConcurrencyStamp") 32 | .IsConcurrencyToken(); 33 | 34 | b.Property("Email") 35 | .HasMaxLength(256); 36 | 37 | b.Property("EmailConfirmed"); 38 | 39 | b.Property("LockoutEnabled"); 40 | 41 | b.Property("LockoutEnd"); 42 | 43 | b.Property("NormalizedEmail") 44 | .HasMaxLength(256); 45 | 46 | b.Property("NormalizedUserName") 47 | .HasMaxLength(256); 48 | 49 | b.Property("PasswordHash"); 50 | 51 | b.Property("PhoneNumber"); 52 | 53 | b.Property("PhoneNumberConfirmed"); 54 | 55 | b.Property("SecurityStamp"); 56 | 57 | b.Property("TwoFactorEnabled"); 58 | 59 | b.Property("UserName") 60 | .HasMaxLength(256); 61 | 62 | b.HasKey("Id"); 63 | 64 | b.HasIndex("NormalizedEmail") 65 | .HasName("EmailIndex"); 66 | 67 | b.HasIndex("NormalizedUserName") 68 | .IsUnique() 69 | .HasName("UserNameIndex") 70 | .HasFilter("[NormalizedUserName] IS NOT NULL"); 71 | 72 | b.ToTable("AspNetUsers"); 73 | }); 74 | 75 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => 76 | { 77 | b.Property("Id") 78 | .ValueGeneratedOnAdd(); 79 | 80 | b.Property("ConcurrencyStamp") 81 | .IsConcurrencyToken(); 82 | 83 | b.Property("Name") 84 | .HasMaxLength(256); 85 | 86 | b.Property("NormalizedName") 87 | .HasMaxLength(256); 88 | 89 | b.HasKey("Id"); 90 | 91 | b.HasIndex("NormalizedName") 92 | .IsUnique() 93 | .HasName("RoleNameIndex") 94 | .HasFilter("[NormalizedName] IS NOT NULL"); 95 | 96 | b.ToTable("AspNetRoles"); 97 | }); 98 | 99 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => 100 | { 101 | b.Property("Id") 102 | .ValueGeneratedOnAdd(); 103 | 104 | b.Property("ClaimType"); 105 | 106 | b.Property("ClaimValue"); 107 | 108 | b.Property("RoleId") 109 | .IsRequired(); 110 | 111 | b.HasKey("Id"); 112 | 113 | b.HasIndex("RoleId"); 114 | 115 | b.ToTable("AspNetRoleClaims"); 116 | }); 117 | 118 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => 119 | { 120 | b.Property("Id") 121 | .ValueGeneratedOnAdd(); 122 | 123 | b.Property("ClaimType"); 124 | 125 | b.Property("ClaimValue"); 126 | 127 | b.Property("UserId") 128 | .IsRequired(); 129 | 130 | b.HasKey("Id"); 131 | 132 | b.HasIndex("UserId"); 133 | 134 | b.ToTable("AspNetUserClaims"); 135 | }); 136 | 137 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => 138 | { 139 | b.Property("LoginProvider"); 140 | 141 | b.Property("ProviderKey"); 142 | 143 | b.Property("ProviderDisplayName"); 144 | 145 | b.Property("UserId") 146 | .IsRequired(); 147 | 148 | b.HasKey("LoginProvider", "ProviderKey"); 149 | 150 | b.HasIndex("UserId"); 151 | 152 | b.ToTable("AspNetUserLogins"); 153 | }); 154 | 155 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => 156 | { 157 | b.Property("UserId"); 158 | 159 | b.Property("RoleId"); 160 | 161 | b.HasKey("UserId", "RoleId"); 162 | 163 | b.HasIndex("RoleId"); 164 | 165 | b.ToTable("AspNetUserRoles"); 166 | }); 167 | 168 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => 169 | { 170 | b.Property("UserId"); 171 | 172 | b.Property("LoginProvider"); 173 | 174 | b.Property("Name"); 175 | 176 | b.Property("Value"); 177 | 178 | b.HasKey("UserId", "LoginProvider", "Name"); 179 | 180 | b.ToTable("AspNetUserTokens"); 181 | }); 182 | 183 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => 184 | { 185 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") 186 | .WithMany() 187 | .HasForeignKey("RoleId") 188 | .OnDelete(DeleteBehavior.Cascade); 189 | }); 190 | 191 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => 192 | { 193 | b.HasOne("IdentityServerExternalAuth.Entities.ApplicationUser") 194 | .WithMany() 195 | .HasForeignKey("UserId") 196 | .OnDelete(DeleteBehavior.Cascade); 197 | }); 198 | 199 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => 200 | { 201 | b.HasOne("IdentityServerExternalAuth.Entities.ApplicationUser") 202 | .WithMany() 203 | .HasForeignKey("UserId") 204 | .OnDelete(DeleteBehavior.Cascade); 205 | }); 206 | 207 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => 208 | { 209 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") 210 | .WithMany() 211 | .HasForeignKey("RoleId") 212 | .OnDelete(DeleteBehavior.Cascade); 213 | 214 | b.HasOne("IdentityServerExternalAuth.Entities.ApplicationUser") 215 | .WithMany() 216 | .HasForeignKey("UserId") 217 | .OnDelete(DeleteBehavior.Cascade); 218 | }); 219 | 220 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => 221 | { 222 | b.HasOne("IdentityServerExternalAuth.Entities.ApplicationUser") 223 | .WithMany() 224 | .HasForeignKey("UserId") 225 | .OnDelete(DeleteBehavior.Cascade); 226 | }); 227 | #pragma warning restore 612, 618 228 | } 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Migrations/20170918180510_init_users.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | using System; 3 | using System.Collections.Generic; 4 | 5 | namespace IdentityServerExternalAuth.Migrations 6 | { 7 | public partial class init_users : Migration 8 | { 9 | protected override void Up(MigrationBuilder migrationBuilder) 10 | { 11 | 12 | } 13 | 14 | protected override void Down(MigrationBuilder migrationBuilder) 15 | { 16 | 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Migrations/20170919161256_external_user_table.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using IdentityServerExternalAuth.Data; 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore.Infrastructure; 5 | using Microsoft.EntityFrameworkCore.Metadata; 6 | using Microsoft.EntityFrameworkCore.Migrations; 7 | using Microsoft.EntityFrameworkCore.Storage; 8 | using Microsoft.EntityFrameworkCore.Storage.Internal; 9 | using System; 10 | 11 | namespace IdentityServerExternalAuth.Migrations 12 | { 13 | [DbContext(typeof(DatabaseContext))] 14 | [Migration("20170919161256_external_user_table")] 15 | partial class external_user_table 16 | { 17 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 18 | { 19 | #pragma warning disable 612, 618 20 | modelBuilder 21 | .HasAnnotation("ProductVersion", "2.0.0-rtm-26452") 22 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 23 | 24 | modelBuilder.Entity("IdentityServerExternalAuth.Entities.ApplicationUser", b => 25 | { 26 | b.Property("Id") 27 | .ValueGeneratedOnAdd(); 28 | 29 | b.Property("AccessFailedCount"); 30 | 31 | b.Property("ConcurrencyStamp") 32 | .IsConcurrencyToken(); 33 | 34 | b.Property("Email") 35 | .HasMaxLength(256); 36 | 37 | b.Property("EmailConfirmed"); 38 | 39 | b.Property("LockoutEnabled"); 40 | 41 | b.Property("LockoutEnd"); 42 | 43 | b.Property("NormalizedEmail") 44 | .HasMaxLength(256); 45 | 46 | b.Property("NormalizedUserName") 47 | .HasMaxLength(256); 48 | 49 | b.Property("PasswordHash"); 50 | 51 | b.Property("PhoneNumber"); 52 | 53 | b.Property("PhoneNumberConfirmed"); 54 | 55 | b.Property("SecurityStamp"); 56 | 57 | b.Property("TwoFactorEnabled"); 58 | 59 | b.Property("UserName") 60 | .HasMaxLength(256); 61 | 62 | b.HasKey("Id"); 63 | 64 | b.HasIndex("NormalizedEmail") 65 | .HasName("EmailIndex"); 66 | 67 | b.HasIndex("NormalizedUserName") 68 | .IsUnique() 69 | .HasName("UserNameIndex") 70 | .HasFilter("[NormalizedUserName] IS NOT NULL"); 71 | 72 | b.ToTable("AspNetUsers"); 73 | }); 74 | 75 | modelBuilder.Entity("IdentityServerExternalAuth.Entities.ExternalUser", b => 76 | { 77 | b.Property("Id") 78 | .ValueGeneratedOnAdd(); 79 | 80 | b.Property("ExternalId"); 81 | 82 | b.Property("Provider"); 83 | 84 | b.Property("UserId"); 85 | 86 | b.HasKey("Id"); 87 | 88 | b.HasIndex("UserId"); 89 | 90 | b.ToTable("ExternalUsers"); 91 | }); 92 | 93 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => 94 | { 95 | b.Property("Id") 96 | .ValueGeneratedOnAdd(); 97 | 98 | b.Property("ConcurrencyStamp") 99 | .IsConcurrencyToken(); 100 | 101 | b.Property("Name") 102 | .HasMaxLength(256); 103 | 104 | b.Property("NormalizedName") 105 | .HasMaxLength(256); 106 | 107 | b.HasKey("Id"); 108 | 109 | b.HasIndex("NormalizedName") 110 | .IsUnique() 111 | .HasName("RoleNameIndex") 112 | .HasFilter("[NormalizedName] IS NOT NULL"); 113 | 114 | b.ToTable("AspNetRoles"); 115 | }); 116 | 117 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => 118 | { 119 | b.Property("Id") 120 | .ValueGeneratedOnAdd(); 121 | 122 | b.Property("ClaimType"); 123 | 124 | b.Property("ClaimValue"); 125 | 126 | b.Property("RoleId") 127 | .IsRequired(); 128 | 129 | b.HasKey("Id"); 130 | 131 | b.HasIndex("RoleId"); 132 | 133 | b.ToTable("AspNetRoleClaims"); 134 | }); 135 | 136 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => 137 | { 138 | b.Property("Id") 139 | .ValueGeneratedOnAdd(); 140 | 141 | b.Property("ClaimType"); 142 | 143 | b.Property("ClaimValue"); 144 | 145 | b.Property("UserId") 146 | .IsRequired(); 147 | 148 | b.HasKey("Id"); 149 | 150 | b.HasIndex("UserId"); 151 | 152 | b.ToTable("AspNetUserClaims"); 153 | }); 154 | 155 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => 156 | { 157 | b.Property("LoginProvider"); 158 | 159 | b.Property("ProviderKey"); 160 | 161 | b.Property("ProviderDisplayName"); 162 | 163 | b.Property("UserId") 164 | .IsRequired(); 165 | 166 | b.HasKey("LoginProvider", "ProviderKey"); 167 | 168 | b.HasIndex("UserId"); 169 | 170 | b.ToTable("AspNetUserLogins"); 171 | }); 172 | 173 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => 174 | { 175 | b.Property("UserId"); 176 | 177 | b.Property("RoleId"); 178 | 179 | b.HasKey("UserId", "RoleId"); 180 | 181 | b.HasIndex("RoleId"); 182 | 183 | b.ToTable("AspNetUserRoles"); 184 | }); 185 | 186 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => 187 | { 188 | b.Property("UserId"); 189 | 190 | b.Property("LoginProvider"); 191 | 192 | b.Property("Name"); 193 | 194 | b.Property("Value"); 195 | 196 | b.HasKey("UserId", "LoginProvider", "Name"); 197 | 198 | b.ToTable("AspNetUserTokens"); 199 | }); 200 | 201 | modelBuilder.Entity("IdentityServerExternalAuth.Entities.ExternalUser", b => 202 | { 203 | b.HasOne("IdentityServerExternalAuth.Entities.ApplicationUser", "User") 204 | .WithMany() 205 | .HasForeignKey("UserId"); 206 | }); 207 | 208 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => 209 | { 210 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") 211 | .WithMany() 212 | .HasForeignKey("RoleId") 213 | .OnDelete(DeleteBehavior.Cascade); 214 | }); 215 | 216 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => 217 | { 218 | b.HasOne("IdentityServerExternalAuth.Entities.ApplicationUser") 219 | .WithMany() 220 | .HasForeignKey("UserId") 221 | .OnDelete(DeleteBehavior.Cascade); 222 | }); 223 | 224 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => 225 | { 226 | b.HasOne("IdentityServerExternalAuth.Entities.ApplicationUser") 227 | .WithMany() 228 | .HasForeignKey("UserId") 229 | .OnDelete(DeleteBehavior.Cascade); 230 | }); 231 | 232 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => 233 | { 234 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") 235 | .WithMany() 236 | .HasForeignKey("RoleId") 237 | .OnDelete(DeleteBehavior.Cascade); 238 | 239 | b.HasOne("IdentityServerExternalAuth.Entities.ApplicationUser") 240 | .WithMany() 241 | .HasForeignKey("UserId") 242 | .OnDelete(DeleteBehavior.Cascade); 243 | }); 244 | 245 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => 246 | { 247 | b.HasOne("IdentityServerExternalAuth.Entities.ApplicationUser") 248 | .WithMany() 249 | .HasForeignKey("UserId") 250 | .OnDelete(DeleteBehavior.Cascade); 251 | }); 252 | #pragma warning restore 612, 618 253 | } 254 | } 255 | } 256 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Migrations/20170919161256_external_user_table.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Metadata; 2 | using Microsoft.EntityFrameworkCore.Migrations; 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | namespace IdentityServerExternalAuth.Migrations 7 | { 8 | public partial class external_user_table : Migration 9 | { 10 | protected override void Up(MigrationBuilder migrationBuilder) 11 | { 12 | migrationBuilder.CreateTable( 13 | name: "ExternalUsers", 14 | columns: table => new 15 | { 16 | Id = table.Column(type: "int", nullable: false) 17 | .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), 18 | ExternalId = table.Column(type: "nvarchar(max)", nullable: true), 19 | Provider = table.Column(type: "nvarchar(max)", nullable: true), 20 | UserId = table.Column(type: "nvarchar(450)", nullable: true) 21 | }, 22 | constraints: table => 23 | { 24 | table.PrimaryKey("PK_ExternalUsers", x => x.Id); 25 | table.ForeignKey( 26 | name: "FK_ExternalUsers_AspNetUsers_UserId", 27 | column: x => x.UserId, 28 | principalTable: "AspNetUsers", 29 | principalColumn: "Id", 30 | onDelete: ReferentialAction.Restrict); 31 | }); 32 | 33 | migrationBuilder.CreateIndex( 34 | name: "IX_ExternalUsers_UserId", 35 | table: "ExternalUsers", 36 | column: "UserId"); 37 | } 38 | 39 | protected override void Down(MigrationBuilder migrationBuilder) 40 | { 41 | migrationBuilder.DropTable( 42 | name: "ExternalUsers"); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Migrations/20171017064323_remove_externaluser_table.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using IdentityServerExternalAuth.Data; 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore.Infrastructure; 5 | using Microsoft.EntityFrameworkCore.Metadata; 6 | using Microsoft.EntityFrameworkCore.Migrations; 7 | using Microsoft.EntityFrameworkCore.Storage; 8 | using Microsoft.EntityFrameworkCore.Storage.Internal; 9 | using System; 10 | 11 | namespace IdentityServerExternalAuth.Migrations 12 | { 13 | [DbContext(typeof(DatabaseContext))] 14 | [Migration("20171017064323_remove_externaluser_table")] 15 | partial class remove_externaluser_table 16 | { 17 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 18 | { 19 | #pragma warning disable 612, 618 20 | modelBuilder 21 | .HasAnnotation("ProductVersion", "2.0.0-rtm-26452") 22 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 23 | 24 | modelBuilder.Entity("IdentityServerExternalAuth.Entities.ApplicationUser", b => 25 | { 26 | b.Property("Id") 27 | .ValueGeneratedOnAdd(); 28 | 29 | b.Property("AccessFailedCount"); 30 | 31 | b.Property("ConcurrencyStamp") 32 | .IsConcurrencyToken(); 33 | 34 | b.Property("Email") 35 | .HasMaxLength(256); 36 | 37 | b.Property("EmailConfirmed"); 38 | 39 | b.Property("LockoutEnabled"); 40 | 41 | b.Property("LockoutEnd"); 42 | 43 | b.Property("NormalizedEmail") 44 | .HasMaxLength(256); 45 | 46 | b.Property("NormalizedUserName") 47 | .HasMaxLength(256); 48 | 49 | b.Property("PasswordHash"); 50 | 51 | b.Property("PhoneNumber"); 52 | 53 | b.Property("PhoneNumberConfirmed"); 54 | 55 | b.Property("SecurityStamp"); 56 | 57 | b.Property("TwoFactorEnabled"); 58 | 59 | b.Property("UserName") 60 | .HasMaxLength(256); 61 | 62 | b.HasKey("Id"); 63 | 64 | b.HasIndex("NormalizedEmail") 65 | .HasName("EmailIndex"); 66 | 67 | b.HasIndex("NormalizedUserName") 68 | .IsUnique() 69 | .HasName("UserNameIndex") 70 | .HasFilter("[NormalizedUserName] IS NOT NULL"); 71 | 72 | b.ToTable("AspNetUsers"); 73 | }); 74 | 75 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => 76 | { 77 | b.Property("Id") 78 | .ValueGeneratedOnAdd(); 79 | 80 | b.Property("ConcurrencyStamp") 81 | .IsConcurrencyToken(); 82 | 83 | b.Property("Name") 84 | .HasMaxLength(256); 85 | 86 | b.Property("NormalizedName") 87 | .HasMaxLength(256); 88 | 89 | b.HasKey("Id"); 90 | 91 | b.HasIndex("NormalizedName") 92 | .IsUnique() 93 | .HasName("RoleNameIndex") 94 | .HasFilter("[NormalizedName] IS NOT NULL"); 95 | 96 | b.ToTable("AspNetRoles"); 97 | }); 98 | 99 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => 100 | { 101 | b.Property("Id") 102 | .ValueGeneratedOnAdd(); 103 | 104 | b.Property("ClaimType"); 105 | 106 | b.Property("ClaimValue"); 107 | 108 | b.Property("RoleId") 109 | .IsRequired(); 110 | 111 | b.HasKey("Id"); 112 | 113 | b.HasIndex("RoleId"); 114 | 115 | b.ToTable("AspNetRoleClaims"); 116 | }); 117 | 118 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => 119 | { 120 | b.Property("Id") 121 | .ValueGeneratedOnAdd(); 122 | 123 | b.Property("ClaimType"); 124 | 125 | b.Property("ClaimValue"); 126 | 127 | b.Property("UserId") 128 | .IsRequired(); 129 | 130 | b.HasKey("Id"); 131 | 132 | b.HasIndex("UserId"); 133 | 134 | b.ToTable("AspNetUserClaims"); 135 | }); 136 | 137 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => 138 | { 139 | b.Property("LoginProvider"); 140 | 141 | b.Property("ProviderKey"); 142 | 143 | b.Property("ProviderDisplayName"); 144 | 145 | b.Property("UserId") 146 | .IsRequired(); 147 | 148 | b.HasKey("LoginProvider", "ProviderKey"); 149 | 150 | b.HasIndex("UserId"); 151 | 152 | b.ToTable("AspNetUserLogins"); 153 | }); 154 | 155 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => 156 | { 157 | b.Property("UserId"); 158 | 159 | b.Property("RoleId"); 160 | 161 | b.HasKey("UserId", "RoleId"); 162 | 163 | b.HasIndex("RoleId"); 164 | 165 | b.ToTable("AspNetUserRoles"); 166 | }); 167 | 168 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => 169 | { 170 | b.Property("UserId"); 171 | 172 | b.Property("LoginProvider"); 173 | 174 | b.Property("Name"); 175 | 176 | b.Property("Value"); 177 | 178 | b.HasKey("UserId", "LoginProvider", "Name"); 179 | 180 | b.ToTable("AspNetUserTokens"); 181 | }); 182 | 183 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => 184 | { 185 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") 186 | .WithMany() 187 | .HasForeignKey("RoleId") 188 | .OnDelete(DeleteBehavior.Cascade); 189 | }); 190 | 191 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => 192 | { 193 | b.HasOne("IdentityServerExternalAuth.Entities.ApplicationUser") 194 | .WithMany() 195 | .HasForeignKey("UserId") 196 | .OnDelete(DeleteBehavior.Cascade); 197 | }); 198 | 199 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => 200 | { 201 | b.HasOne("IdentityServerExternalAuth.Entities.ApplicationUser") 202 | .WithMany() 203 | .HasForeignKey("UserId") 204 | .OnDelete(DeleteBehavior.Cascade); 205 | }); 206 | 207 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => 208 | { 209 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") 210 | .WithMany() 211 | .HasForeignKey("RoleId") 212 | .OnDelete(DeleteBehavior.Cascade); 213 | 214 | b.HasOne("IdentityServerExternalAuth.Entities.ApplicationUser") 215 | .WithMany() 216 | .HasForeignKey("UserId") 217 | .OnDelete(DeleteBehavior.Cascade); 218 | }); 219 | 220 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => 221 | { 222 | b.HasOne("IdentityServerExternalAuth.Entities.ApplicationUser") 223 | .WithMany() 224 | .HasForeignKey("UserId") 225 | .OnDelete(DeleteBehavior.Cascade); 226 | }); 227 | #pragma warning restore 612, 618 228 | } 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Migrations/20171017064323_remove_externaluser_table.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Metadata; 2 | using Microsoft.EntityFrameworkCore.Migrations; 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | namespace IdentityServerExternalAuth.Migrations 7 | { 8 | public partial class remove_externaluser_table : Migration 9 | { 10 | protected override void Up(MigrationBuilder migrationBuilder) 11 | { 12 | migrationBuilder.DropTable( 13 | name: "ExternalUsers"); 14 | } 15 | 16 | protected override void Down(MigrationBuilder migrationBuilder) 17 | { 18 | migrationBuilder.CreateTable( 19 | name: "ExternalUsers", 20 | columns: table => new 21 | { 22 | Id = table.Column(nullable: false) 23 | .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), 24 | ExternalId = table.Column(nullable: true), 25 | Provider = table.Column(nullable: true), 26 | UserId = table.Column(nullable: true) 27 | }, 28 | constraints: table => 29 | { 30 | table.PrimaryKey("PK_ExternalUsers", x => x.Id); 31 | table.ForeignKey( 32 | name: "FK_ExternalUsers_AspNetUsers_UserId", 33 | column: x => x.UserId, 34 | principalTable: "AspNetUsers", 35 | principalColumn: "Id", 36 | onDelete: ReferentialAction.Restrict); 37 | }); 38 | 39 | migrationBuilder.CreateIndex( 40 | name: "IX_ExternalUsers_UserId", 41 | table: "ExternalUsers", 42 | column: "UserId"); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Migrations/DatabaseContextModelSnapshot.cs: -------------------------------------------------------------------------------- 1 | // 2 | using IdentityServerExternalAuth.Data; 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore.Infrastructure; 5 | using Microsoft.EntityFrameworkCore.Metadata; 6 | using Microsoft.EntityFrameworkCore.Migrations; 7 | using Microsoft.EntityFrameworkCore.Storage; 8 | using Microsoft.EntityFrameworkCore.Storage.Internal; 9 | using System; 10 | 11 | namespace IdentityServerExternalAuth.Migrations 12 | { 13 | [DbContext(typeof(DatabaseContext))] 14 | partial class DatabaseContextModelSnapshot : ModelSnapshot 15 | { 16 | protected override void BuildModel(ModelBuilder modelBuilder) 17 | { 18 | #pragma warning disable 612, 618 19 | modelBuilder 20 | .HasAnnotation("ProductVersion", "2.0.0-rtm-26452") 21 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 22 | 23 | modelBuilder.Entity("IdentityServerExternalAuth.Entities.ApplicationUser", b => 24 | { 25 | b.Property("Id") 26 | .ValueGeneratedOnAdd(); 27 | 28 | b.Property("AccessFailedCount"); 29 | 30 | b.Property("ConcurrencyStamp") 31 | .IsConcurrencyToken(); 32 | 33 | b.Property("Email") 34 | .HasMaxLength(256); 35 | 36 | b.Property("EmailConfirmed"); 37 | 38 | b.Property("LockoutEnabled"); 39 | 40 | b.Property("LockoutEnd"); 41 | 42 | b.Property("NormalizedEmail") 43 | .HasMaxLength(256); 44 | 45 | b.Property("NormalizedUserName") 46 | .HasMaxLength(256); 47 | 48 | b.Property("PasswordHash"); 49 | 50 | b.Property("PhoneNumber"); 51 | 52 | b.Property("PhoneNumberConfirmed"); 53 | 54 | b.Property("SecurityStamp"); 55 | 56 | b.Property("TwoFactorEnabled"); 57 | 58 | b.Property("UserName") 59 | .HasMaxLength(256); 60 | 61 | b.HasKey("Id"); 62 | 63 | b.HasIndex("NormalizedEmail") 64 | .HasName("EmailIndex"); 65 | 66 | b.HasIndex("NormalizedUserName") 67 | .IsUnique() 68 | .HasName("UserNameIndex") 69 | .HasFilter("[NormalizedUserName] IS NOT NULL"); 70 | 71 | b.ToTable("AspNetUsers"); 72 | }); 73 | 74 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => 75 | { 76 | b.Property("Id") 77 | .ValueGeneratedOnAdd(); 78 | 79 | b.Property("ConcurrencyStamp") 80 | .IsConcurrencyToken(); 81 | 82 | b.Property("Name") 83 | .HasMaxLength(256); 84 | 85 | b.Property("NormalizedName") 86 | .HasMaxLength(256); 87 | 88 | b.HasKey("Id"); 89 | 90 | b.HasIndex("NormalizedName") 91 | .IsUnique() 92 | .HasName("RoleNameIndex") 93 | .HasFilter("[NormalizedName] IS NOT NULL"); 94 | 95 | b.ToTable("AspNetRoles"); 96 | }); 97 | 98 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => 99 | { 100 | b.Property("Id") 101 | .ValueGeneratedOnAdd(); 102 | 103 | b.Property("ClaimType"); 104 | 105 | b.Property("ClaimValue"); 106 | 107 | b.Property("RoleId") 108 | .IsRequired(); 109 | 110 | b.HasKey("Id"); 111 | 112 | b.HasIndex("RoleId"); 113 | 114 | b.ToTable("AspNetRoleClaims"); 115 | }); 116 | 117 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => 118 | { 119 | b.Property("Id") 120 | .ValueGeneratedOnAdd(); 121 | 122 | b.Property("ClaimType"); 123 | 124 | b.Property("ClaimValue"); 125 | 126 | b.Property("UserId") 127 | .IsRequired(); 128 | 129 | b.HasKey("Id"); 130 | 131 | b.HasIndex("UserId"); 132 | 133 | b.ToTable("AspNetUserClaims"); 134 | }); 135 | 136 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => 137 | { 138 | b.Property("LoginProvider"); 139 | 140 | b.Property("ProviderKey"); 141 | 142 | b.Property("ProviderDisplayName"); 143 | 144 | b.Property("UserId") 145 | .IsRequired(); 146 | 147 | b.HasKey("LoginProvider", "ProviderKey"); 148 | 149 | b.HasIndex("UserId"); 150 | 151 | b.ToTable("AspNetUserLogins"); 152 | }); 153 | 154 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => 155 | { 156 | b.Property("UserId"); 157 | 158 | b.Property("RoleId"); 159 | 160 | b.HasKey("UserId", "RoleId"); 161 | 162 | b.HasIndex("RoleId"); 163 | 164 | b.ToTable("AspNetUserRoles"); 165 | }); 166 | 167 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => 168 | { 169 | b.Property("UserId"); 170 | 171 | b.Property("LoginProvider"); 172 | 173 | b.Property("Name"); 174 | 175 | b.Property("Value"); 176 | 177 | b.HasKey("UserId", "LoginProvider", "Name"); 178 | 179 | b.ToTable("AspNetUserTokens"); 180 | }); 181 | 182 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => 183 | { 184 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") 185 | .WithMany() 186 | .HasForeignKey("RoleId") 187 | .OnDelete(DeleteBehavior.Cascade); 188 | }); 189 | 190 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => 191 | { 192 | b.HasOne("IdentityServerExternalAuth.Entities.ApplicationUser") 193 | .WithMany() 194 | .HasForeignKey("UserId") 195 | .OnDelete(DeleteBehavior.Cascade); 196 | }); 197 | 198 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => 199 | { 200 | b.HasOne("IdentityServerExternalAuth.Entities.ApplicationUser") 201 | .WithMany() 202 | .HasForeignKey("UserId") 203 | .OnDelete(DeleteBehavior.Cascade); 204 | }); 205 | 206 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => 207 | { 208 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") 209 | .WithMany() 210 | .HasForeignKey("RoleId") 211 | .OnDelete(DeleteBehavior.Cascade); 212 | 213 | b.HasOne("IdentityServerExternalAuth.Entities.ApplicationUser") 214 | .WithMany() 215 | .HasForeignKey("UserId") 216 | .OnDelete(DeleteBehavior.Cascade); 217 | }); 218 | 219 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => 220 | { 221 | b.HasOne("IdentityServerExternalAuth.Entities.ApplicationUser") 222 | .WithMany() 223 | .HasForeignKey("UserId") 224 | .OnDelete(DeleteBehavior.Cascade); 225 | }); 226 | #pragma warning restore 612, 618 227 | } 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Processors/EmailUserProcessor.cs: -------------------------------------------------------------------------------- 1 | using IdentityServerExternalAuth.Interfaces.Processors; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using IdentityServer4.Validation; 7 | using IdentityServerExternalAuth.Repositories.Interfaces; 8 | using IdentityServerExternalAuth.Entities; 9 | using Microsoft.AspNetCore.Identity; 10 | using Newtonsoft.Json.Linq; 11 | using IdentityServer4.Models; 12 | 13 | namespace IdentityServerExternalAuth.Processors 14 | { 15 | public class EmailUserProcessor : IEmailUserProcessor where TUser: IdentityUser,new() 16 | { 17 | private readonly UserManager _userManager; 18 | public EmailUserProcessor( 19 | UserManager userManager 20 | ) 21 | { 22 | _userManager = userManager ?? throw new ArgumentNullException(nameof(userManager)); 23 | } 24 | public async Task ProcessAsync(JObject userInfo,string email,string provider) 25 | { 26 | var userEmail = email; 27 | var userExternalId = userInfo.Value("id"); 28 | 29 | 30 | 31 | if (string.IsNullOrWhiteSpace(userExternalId)) 32 | { 33 | return new GrantValidationResult(TokenRequestErrors.InvalidRequest, "could not retrieve user Id from the token provided"); 34 | } 35 | 36 | var existingUser = _userManager.FindByEmailAsync(userEmail).Result; 37 | if(existingUser != null) 38 | { 39 | return new GrantValidationResult(TokenRequestErrors.InvalidRequest, "User with specified email already exists"); 40 | 41 | } 42 | 43 | var newUser = new TUser { Email = userEmail ,UserName = userEmail}; 44 | var result = _userManager.CreateAsync(newUser).Result; 45 | if (result.Succeeded) 46 | { 47 | await _userManager.AddLoginAsync(newUser, new UserLoginInfo(provider, userExternalId, provider)); 48 | var userClaims = _userManager.GetClaimsAsync(newUser).Result; 49 | return new GrantValidationResult(newUser.Id, provider, userClaims, provider, null); 50 | } 51 | return new GrantValidationResult(TokenRequestErrors.InvalidRequest, "could not create user , please try again."); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Processors/NonEmailUserProcessor.cs: -------------------------------------------------------------------------------- 1 | using IdentityServerExternalAuth.Interfaces.Processors; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using IdentityServer4.Validation; 7 | using IdentityServerExternalAuth.Repositories.Interfaces; 8 | using IdentityServerExternalAuth.Entities; 9 | using Microsoft.AspNetCore.Identity; 10 | using Newtonsoft.Json.Linq; 11 | using IdentityServer4.Models; 12 | 13 | namespace IdentityServerExternalAuth.Processors 14 | { 15 | public class NonEmailUserProcessor : INonEmailUserProcessor where TUser : IdentityUser , new() 16 | { 17 | // private readonly IExternalUserRepository _externalUserRepository; 18 | private readonly UserManager _userManager; 19 | public NonEmailUserProcessor( 20 | // IExternalUserRepository externalUserRepository, 21 | UserManager userManager 22 | ) 23 | { 24 | // _externalUserRepository = externalUserRepository ?? throw new ArgumentNullException(nameof(externalUserRepository)); 25 | _userManager = userManager ?? throw new ArgumentNullException(nameof(userManager)); 26 | } 27 | public async Task ProcessAsync(JObject userInfo,string provider) 28 | { 29 | 30 | var userEmail = userInfo.Value("email"); 31 | 32 | if (provider.ToLower() == "linkedin") 33 | userEmail = userInfo.Value("emailAddress"); 34 | 35 | var userExternalId = userInfo.Value("id"); 36 | 37 | if (userEmail == null) 38 | { 39 | var existingUser = await _userManager.FindByLoginAsync(provider, userExternalId); 40 | if (existingUser == null) 41 | { 42 | var customResponse = new Dictionary(); 43 | customResponse.Add("userInfo", userInfo); 44 | return new GrantValidationResult(TokenRequestErrors.InvalidRequest, "could not retrieve user's email from the given provider, include email paramater and send request again.", customResponse); 45 | 46 | } 47 | else 48 | { 49 | existingUser = await _userManager.FindByIdAsync(existingUser.Id); 50 | var userClaims = await _userManager.GetClaimsAsync(existingUser); 51 | return new GrantValidationResult(existingUser.Id, provider, userClaims, provider, null); 52 | } 53 | 54 | } 55 | else 56 | { 57 | var newUser = new TUser { Email = userEmail,UserName = userEmail }; 58 | var result = await _userManager.CreateAsync(newUser); 59 | if (result.Succeeded) 60 | { 61 | await _userManager.AddLoginAsync(newUser, new UserLoginInfo(provider, userExternalId, provider)); 62 | var userClaims = await _userManager.GetClaimsAsync(newUser); 63 | return new GrantValidationResult(newUser.Id, provider, userClaims, provider, null); 64 | } 65 | return new GrantValidationResult(TokenRequestErrors.InvalidRequest, "user could not be created, please try again"); 66 | } 67 | 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace IdentityServerExternalAuth 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | BuildWebHost(args).Run(); 18 | } 19 | 20 | public static IWebHost BuildWebHost(string[] args) => 21 | WebHost.CreateDefaultBuilder(args) 22 | .UseStartup() 23 | .ConfigureAppConfiguration((hostingContext,config) => 24 | { 25 | var env = hostingContext.HostingEnvironment; 26 | config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); 27 | 28 | }) 29 | .Build(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:17640/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "launchUrl": "http://localhost:17640/", 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "IdentityServerExternalAuth": { 20 | "commandName": "Project", 21 | "launchBrowser": true, 22 | "environmentVariables": { 23 | "ASPNETCORE_ENVIRONMENT": "Development" 24 | }, 25 | "applicationUrl": "http://localhost:17641/" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Providers/FacebookAuthProvider.cs: -------------------------------------------------------------------------------- 1 | using IdentityServerExternalAuth.Interfaces; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Newtonsoft.Json.Linq; 7 | using IdentityServerExternalAuth.Repositories.Interfaces; 8 | using IdentityServerExternalAuth.Entities; 9 | using IdentityServerExternalAuth.Helpers; 10 | using System.Net.Http; 11 | using Microsoft.AspNetCore.Identity; 12 | 13 | namespace IdentityServerExternalAuth.Providers 14 | { 15 | public class FacebookAuthProvider : IFacebookAuthProvider where TUser:IdentityUser , new() 16 | { 17 | 18 | private readonly IProviderRepository _providerRepository; 19 | private readonly HttpClient _httpClient; 20 | public FacebookAuthProvider( 21 | IProviderRepository providerRepository, 22 | HttpClient httpClient 23 | ) 24 | { 25 | _providerRepository = providerRepository; 26 | _httpClient = httpClient; 27 | } 28 | 29 | public Provider Provider => _providerRepository.Get() 30 | .FirstOrDefault(x => x.Name.ToLower() == ProviderType.Facebook.ToString().ToLower()); 31 | 32 | public JObject GetUserInfo(string accessToken) 33 | { 34 | if(Provider == null) 35 | { 36 | throw new ArgumentNullException(nameof(Provider)); 37 | } 38 | 39 | var request = new Dictionary(); 40 | 41 | request.Add("fields", "id,email,name,gender,birthday"); 42 | request.Add("access_token", accessToken); 43 | 44 | var result = _httpClient.GetAsync(Provider.UserInfoEndPoint + QueryBuilder.GetQuery(request, ProviderType.Facebook)).Result; 45 | if (result.IsSuccessStatusCode) 46 | { 47 | var infoObject = JObject.Parse(result.Content.ReadAsStringAsync().Result); 48 | return infoObject; 49 | } 50 | return null; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Providers/GitHubAuthProvider.cs: -------------------------------------------------------------------------------- 1 | using IdentityServerExternalAuth.Interfaces; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using IdentityServerExternalAuth.Entities; 7 | using Newtonsoft.Json.Linq; 8 | using IdentityServerExternalAuth.Repositories.Interfaces; 9 | using System.Net.Http; 10 | using IdentityServerExternalAuth.Helpers; 11 | using System.Net.Http.Headers; 12 | using System.Web; 13 | using System.Net; 14 | using Microsoft.AspNetCore.Identity; 15 | 16 | namespace IdentityServerExternalAuth.Providers 17 | { 18 | public class GitHubAuthProvider : IGitHubAuthProvider where TUser:IdentityUser,new() 19 | { 20 | private readonly IProviderRepository _providerRepository; 21 | private readonly HttpClient _httpClient; 22 | public GitHubAuthProvider( 23 | IProviderRepository providerRepository, 24 | HttpClient httpClient 25 | ) 26 | { 27 | _providerRepository = providerRepository; 28 | _httpClient = httpClient; 29 | } 30 | public Provider Provider => _providerRepository.Get() 31 | .FirstOrDefault(x => x.Name.ToLower() == ProviderType.GitHub.ToString().ToLower()); 32 | 33 | public JObject GetUserInfo(string accessToken) 34 | { 35 | if (Provider == null) throw new ArgumentNullException(nameof(Provider)); 36 | 37 | var request = $"{Provider.UserInfoEndPoint}?access_token={accessToken}"; 38 | 39 | _httpClient.DefaultRequestHeaders.Clear(); 40 | _httpClient.DefaultRequestHeaders.Add("cache-control", "no-cache"); 41 | _httpClient.DefaultRequestHeaders.Add("Connection", "keep-alive"); 42 | _httpClient.DefaultRequestHeaders.Add("Authorization", "token " + accessToken); 43 | 44 | try 45 | { 46 | var result = _httpClient.GetAsync(Provider.UserInfoEndPoint).Result; 47 | if (result.IsSuccessStatusCode) 48 | { 49 | var infoObject = JObject.Parse(result.Content.ReadAsStringAsync().Result); 50 | return infoObject; 51 | } 52 | return null; 53 | } 54 | catch (Exception) 55 | { 56 | 57 | throw; 58 | } 59 | 60 | 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Providers/GoogleAuthProvider.cs: -------------------------------------------------------------------------------- 1 | using IdentityServerExternalAuth.Interfaces; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using IdentityServerExternalAuth.Entities; 7 | using Newtonsoft.Json.Linq; 8 | using IdentityServerExternalAuth.Repositories.Interfaces; 9 | using System.Net.Http; 10 | using IdentityServerExternalAuth.Helpers; 11 | using Microsoft.AspNetCore.Identity; 12 | 13 | namespace IdentityServerExternalAuth.Providers 14 | { 15 | public class GoogleAuthProvider : IGoogleAuthProvider where TUser:IdentityUser,new() 16 | { 17 | 18 | private readonly IProviderRepository _providerRepository; 19 | private readonly HttpClient _httpClient; 20 | public GoogleAuthProvider( 21 | 22 | IProviderRepository providerRepository, 23 | HttpClient httpClient 24 | ) 25 | { 26 | 27 | _providerRepository = providerRepository; 28 | _httpClient = httpClient; 29 | } 30 | public Provider Provider => _providerRepository.Get() 31 | .FirstOrDefault(x => x.Name.ToLower() == ProviderType.Google.ToString().ToLower()); 32 | public JObject GetUserInfo(string accessToken) 33 | { 34 | var request = new Dictionary(); 35 | request.Add("token", accessToken); 36 | 37 | var result = _httpClient.GetAsync(Provider.UserInfoEndPoint + QueryBuilder.GetQuery(request, ProviderType.Google)).Result; 38 | if (result.IsSuccessStatusCode) 39 | { 40 | var infoObject = JObject.Parse(result.Content.ReadAsStringAsync().Result); 41 | return infoObject; 42 | } 43 | return null; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Providers/LinkedInAuthProvider.cs: -------------------------------------------------------------------------------- 1 | using IdentityServerExternalAuth.Interfaces; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using IdentityServerExternalAuth.Entities; 7 | using Newtonsoft.Json.Linq; 8 | using IdentityServerExternalAuth.Repositories.Interfaces; 9 | using System.Net.Http; 10 | using IdentityServerExternalAuth.Helpers; 11 | using Microsoft.AspNetCore.Identity; 12 | 13 | namespace IdentityServerExternalAuth.Providers 14 | { 15 | public class LinkedInAuthProvider : ILinkedInAuthProvider where TUser : IdentityUser, new() 16 | { 17 | 18 | private readonly IProviderRepository _providerRepository; 19 | private readonly HttpClient _httpClient; 20 | public LinkedInAuthProvider( 21 | 22 | IProviderRepository providerRepository, 23 | HttpClient httpClient 24 | ) 25 | { 26 | 27 | _providerRepository = providerRepository; 28 | _httpClient = httpClient; 29 | } 30 | public Provider Provider => _providerRepository.Get() 31 | .FirstOrDefault(x => x.Name.ToLower() == ProviderType.LinkedIn.ToString().ToLower()); 32 | 33 | public JObject GetUserInfo(string accessToken) 34 | { 35 | var urlParams = $"oauth2_access_token={accessToken}&format=json"; 36 | 37 | var result = _httpClient.GetAsync($"{Provider.UserInfoEndPoint}{urlParams}").Result; 38 | if (result.IsSuccessStatusCode) 39 | { 40 | var infoObject = JObject.Parse(result.Content.ReadAsStringAsync().Result); 41 | return infoObject; 42 | } 43 | return null; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Providers/TwitterAuthProvider.cs: -------------------------------------------------------------------------------- 1 | using IdentityServerExternalAuth.Interfaces; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using IdentityServerExternalAuth.Entities; 7 | using Newtonsoft.Json.Linq; 8 | using IdentityServerExternalAuth.Repositories.Interfaces; 9 | using System.Net.Http; 10 | using IdentityServerExternalAuth.Helpers; 11 | using System.Net.Http.Headers; 12 | using Microsoft.AspNetCore.Identity; 13 | 14 | namespace IdentityServerExternalAuth.Providers 15 | { 16 | public class TwitterAuthProvider : ITwitterAuthProvider where TUser:IdentityUser,new() 17 | { 18 | private readonly IProviderRepository _providerRepository; 19 | private readonly HttpClient _httpClient; 20 | public TwitterAuthProvider( 21 | IProviderRepository providerRepository, 22 | HttpClient httpClient 23 | ) 24 | { 25 | _providerRepository = providerRepository; 26 | _httpClient = httpClient; 27 | } 28 | public Provider Provider => _providerRepository.Get() 29 | .FirstOrDefault(x => x.Name.ToLower() == ProviderType.Twitter.ToString().ToLower()); 30 | 31 | public JObject GetUserInfo(string accessToken) 32 | { 33 | if (Provider == null) 34 | { 35 | throw new ArgumentNullException(nameof(Provider)); 36 | } 37 | 38 | var request = new Dictionary(); 39 | request.Add("tokenString", accessToken); 40 | request.Add("endpoint", Provider.UserInfoEndPoint); 41 | 42 | var authorizationHeaderParams = QueryBuilder.GetQuery(request, ProviderType.Twitter); 43 | 44 | _httpClient.DefaultRequestHeaders.Clear(); 45 | _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded")); 46 | _httpClient.DefaultRequestHeaders.Add("Authorization", authorizationHeaderParams); 47 | 48 | var result = _httpClient.GetAsync(Provider.UserInfoEndPoint).Result; 49 | 50 | if (result.IsSuccessStatusCode) 51 | { 52 | var infoObject = JObject.Parse(result.Content.ReadAsStringAsync().Result); 53 | return infoObject; 54 | } 55 | return null; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Repositories/Interfaces/IProviderRepository.cs: -------------------------------------------------------------------------------- 1 | using IdentityServerExternalAuth.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace IdentityServerExternalAuth.Repositories.Interfaces 8 | { 9 | public interface IProviderRepository 10 | { 11 | IEnumerable Get(); 12 | 13 | 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Repositories/ProviderRepository.cs: -------------------------------------------------------------------------------- 1 | using IdentityServerExternalAuth.Repositories.Interfaces; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using IdentityServerExternalAuth.Entities; 7 | using IdentityServerExternalAuth.Helpers; 8 | 9 | namespace IdentityServerExternalAuth.Repositories 10 | { 11 | public class ProviderRepository : IProviderRepository 12 | { 13 | 14 | public IEnumerable Get() 15 | { 16 | return ProviderDataSource.GetProviders(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Microsoft.Extensions.Configuration; 5 | using IdentityServerExternalAuth.Extensions; 6 | using System; 7 | using IdentityServerExternalAuth.Entities; 8 | 9 | namespace IdentityServerExternalAuth 10 | { 11 | public class Startup 12 | { 13 | 14 | public Startup(IConfiguration configuration) 15 | { 16 | Configuration = configuration; 17 | } 18 | // This method gets called by the runtime. Use this method to add services to the container. 19 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 20 | public void ConfigureServices(IServiceCollection services) 21 | { 22 | 23 | services.AddDatabaseConfiguration(Configuration.GetConnectionString("DefaultConnection")) 24 | .AddIdentityServerConfig() 25 | .AddServices() 26 | .AddRepositories() 27 | .AddProviders(); 28 | 29 | services.AddMvc(); 30 | } 31 | 32 | 33 | 34 | public IConfiguration Configuration; 35 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 36 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 37 | { 38 | if (env.IsDevelopment()) 39 | { 40 | app.UseDeveloperExceptionPage(); 41 | } 42 | 43 | app.UseAuthentication(); 44 | app.UseIdentityServer(); 45 | app.UseMvcWithDefaultRoute(); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @using IdentityServerExternalAuth.Entities 2 |
3 |

IdentityServer4 with External Authentication Providers Running...

4 | 5 | Supported providers 6 |
    7 | 8 | @foreach(var provider in ViewBag.Providers as IEnumerable) 9 | { 10 | 11 |
  1. @provider.Name
  2. 12 | } 13 |
14 |
-------------------------------------------------------------------------------- /IdentityServerExternalAuth/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @ViewBag.Title 7 | 8 | 9 |
10 | @RenderBody() 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "DefaultConnection": "Data Source=.;Initial Catalog=IdSrv;Integrated Security=True" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/obj/Debug/netcoreapp2.0/IdentityServerExternalAuth.AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | using System; 12 | using System.Reflection; 13 | 14 | [assembly: System.Reflection.AssemblyCompanyAttribute("IdentityServerExternalAuth")] 15 | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] 16 | [assembly: System.Reflection.AssemblyDescriptionAttribute("Package Description")] 17 | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] 18 | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] 19 | [assembly: System.Reflection.AssemblyProductAttribute("IdentityServerExternalAuth")] 20 | [assembly: System.Reflection.AssemblyTitleAttribute("IdentityServerExternalAuth")] 21 | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] 22 | 23 | // Generated by the MSBuild WriteCodeFragment class. 24 | 25 | -------------------------------------------------------------------------------- /IdentityServerExternalAuth/obj/Debug/netcoreapp2.0/IdentityServerExternalAuth.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waqaskhan540/IdentityServerExternalAuth/4817655c3c9fdb8b9acb452546791eaf4a3d49b8/IdentityServerExternalAuth/obj/Debug/netcoreapp2.0/IdentityServerExternalAuth.dll -------------------------------------------------------------------------------- /IdentityServerExternalAuth/obj/Debug/netcoreapp2.0/IdentityServerExternalAuth.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waqaskhan540/IdentityServerExternalAuth/4817655c3c9fdb8b9acb452546791eaf4a3d49b8/IdentityServerExternalAuth/obj/Debug/netcoreapp2.0/IdentityServerExternalAuth.pdb -------------------------------------------------------------------------------- /IdentityServerExternalAuth/tempkey.rsa: -------------------------------------------------------------------------------- 1 | {"KeyId":"4a874b23720e98907baf326cc863fda5","Parameters":{"D":"AdpjJi1pbm9YHth11p+LeAAX+eRsLUwsBCpNKDgviT23gjGkUpbLgilw4YV5ycbUxUPHVeBUgHKxsceQHvceu1rv8jhMDuOeGJs5t0SCQAeihsdq8gxkKZ+3UKu6ltBVsbxkQlC9hbsenb1VfeqCxTcg4LlMOJDDEVAjSt3YJV2cZnX5CfwBec8bPQCt+bhQ6Qz+xzPU2XXHaSmuW+8px/umhgU/qmfPK+4N6UUjkQg6hjBsray1asYIT37aHGOfMWttW6ht/+/qRooP1pvreaCP+aEjCfwo4ap4i0CECq6cj3rPA9E6f3hItbHChyWufV/MKoGtfUD7ziO44r+b3Q==","DP":"QPi/aWLDwlmNxHeAE1tsv9/HsHhnoRolEKjjhPCOQchXsMU1sjAC0NCwZkCJkt4xCi9OOMbIKEwE0+R5Tt15w7AT7Dy65NvK4WAQx8/nv/X/9JG+ZLjjhVk/UwWzAAdlLNHdVB3yz3lyNcko9ONGOPvTr7o+8V5dq3o4P2fMCEc=","DQ":"Q607jpYH5d2egOX0F0IhnbSiS59KqQx9/tasrcuRg95Y/u+hAerN5nj4Iy9RTXsHzIdnvHHzQ9ZySD4kONKHhjwDcoiDQ0nnDbxHWwgyCDstwt6B64aMfmNizxFIzeqjYkcGokD7JIPe6ovnoQIMdMlEIz3OPtcMFFr7H3bgrBk=","Exponent":"AQAB","InverseQ":"m72l6Y9NIkE7dne7MACGx/8hMiEHI3LIG227cwGBzmGpE2IUI6Le3qsCGPbJtkqRLotDxhv7GSaoKhzFlbil2acJIuj7B7qywc+LWrGysu/yw22B/6hoOFSB9MoSyvWKV5DdcSoTEXk+tmCwj9RxJn8WIQDwRhNhzG0dHsc1s4s=","Modulus":"rb22OhIrKO+5BPlKvjezp/FXho4gIFtO3VLjQgxc0HtUkXON0Yfo6UZVUc001KUB3cZas1V4xvBN0NmCNTFUxmEpzwNl4dmKJ04gaNOCNik46xqiafdJnolRFIaBHUVnq8v+D797mDlCmoiw+/jtOLrQs4VKS84OrU4690Ko6ZOwz/TzrobyE0BzZDYX0h1F1bYEGlKj9ROKw7bBRdi1N/cfuF+xByf36wjYneTYmpC28Q2TMyt/1C7f78BqlRwYeYH9QURBr8Zz17iJL4FqbRo30bd005WTeYjb1LrbT0Ulc0+c7P7WoRwc4CuR3PUyZ+A+4qZW+IDO0/Em4eU8KQ==","P":"09Upe1jsIkAP3nHjr89M01E1vCvC1kMlCGruW+BNqqCqrB8bQmmxiIHrYVNGw76WnfPN7KEKuXWT0mw+Pl0oJRwaSlv3TxwuRVhZdDJGYC08cCWIFjOvO7o3jnYv/A6Vv7k3ikMaeFsBU9S7zQ9pXZhdk3249Je/BUIoi6+A2Q8=","Q":"0fdcruthJNwh6j1uP5QakAxo54n9ShvpEBofXpQ68IjbdwPtBCqoCDonaZ8zMzHAZQN+U2YJqxdkFhwrhMJ9E5QdEVqTBjgQ9kv5fvPMCgyUT9e57cdhcovqUAjSLkmaERe3NH6WPoWLJ4q3GolZbGmXWOEjlsZl1xM9D3zsZ0c="}} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > Project Available as Nuget Package , [click here](https://github.com/waqaskhan540/identityserver-token-exchange) 2 | # Exchanging external Tokens (Google, Twitter, Facebook,LinkedIn) with IdentityServer access tokens using an extension grant 3 | 4 | ## Supported providers 5 | 6 | - [x] Facebook 7 | - [x] LinkedIn 8 | - [x] Twitter 9 | - [x] Google 10 | - [ ] GitHub 11 | 12 | ## How to exchange external tokens for IdentityServer access token ? 13 | * Request authentication using the provider's native library. 14 | * Exchange external token with IdentityServer token by making following request to IdentityServer. 15 | 16 | ``` 17 | POST connect/token 18 | 19 | client_id = [your_client_id] 20 | client_secret = [your_client_secret] 21 | scopes = [your_scopes] 22 | grant_type = external 23 | provider = facebook 24 | external_token = [facebook_access_token] 25 | ``` 26 | * If user is already registered then IdentityServer will return the access token, otherwise it will send the user's data and prompt for an email parameter to be added, in this case make another request with an extra ```email``` parameter. 27 | 28 | ``` 29 | POST connect/token 30 | 31 | client_id = [your_client_id] 32 | client_secret = [your_client_secret] 33 | scopes = [your_scopes] 34 | grant_type = external 35 | provider = facebook 36 | email = myemail@abc.com 37 | external_token = [facebook_access_token] 38 | ``` 39 | 40 | You can change ```provider``` to ```Facebook``` , ```Google``` , ```Twitter``` and ```LinkedIn``` and provide respective token in the ```external_token``` parameter. 41 | 42 | ## How to setup an external provider 43 | 44 | 1. ##### Derive an interface from ```IExternalAuthProvider``` 45 | 46 | ```csharp 47 | 48 | public interface IMyCustomProvider : IExternalAuthProvider { 49 | Provider provider {get;} 50 | } 51 | ``` 52 | 2. ##### Add your provider to ```ProviderType``` enum 53 | 54 | ```csharp 55 | public enum ProviderType { 56 | 57 | Facebook, 58 | Twitter, 59 | Google, 60 | MyCustomProvider 61 | } 62 | ``` 63 | 3. ##### Add provider info to ```ProviderDataSource``` 64 | 65 | ```csharp 66 | 67 | public class ProviderDataSource 68 | { 69 | public static IEnumerable GetProviders() 70 | { 71 | return new List 72 | { 73 | new Provider 74 | { 75 | ProviderId = 1, 76 | Name = "Facebook", 77 | UserInfoEndPoint = "https://graph.facebook.com/v2.8/me" 78 | }, 79 | new Provider 80 | { 81 | ProviderId = 2, 82 | Name = "Google", 83 | UserInfoEndPoint = "https://www.googleapis.com/oauth2/v2/userinfo" 84 | }, 85 | new Provider 86 | { 87 | ProviderId = 3, 88 | Name = "Twitter", 89 | UserInfoEndPoint = "https://api.twitter.com/1.1/account/verify_credentials.json" 90 | }, 91 | new Provider 92 | { 93 | ProviderId = 4, 94 | Name="MyCustomProvider", 95 | UserInfoEndPoint = "[url to end point which validates the token and returns user data]" 96 | } 97 | }; 98 | } 99 | } 100 | 101 | ``` 102 | 103 | 4. ##### Provide an implementation for ```IMyCustomProvider``` 104 | 105 | ```csharp 106 | public class MyCustomProvider : IMyCustomProvider { 107 | 108 | private readonly HttpClient _httpClient; 109 | public MyCustomProvider(HttpClient httpClient) { 110 | _httpClient = httpClient; 111 | } 112 | 113 | public Provider =>_providerRepository.Get() 114 | .FirstOrDefault(x => x.Name.ToLower() == ProviderType.MyCustomProvider.ToString().ToLower()); 115 | 116 | public JObject GetUserInfo(string accessToken) { 117 | 118 | var query = "[build your request according to your providers configuration]"; 119 | 120 | var result = _httpClient.GetAsync(Provider.UserInfoEndPoint + query).Result; 121 | if (result.IsSuccessStatusCode) 122 | { 123 | var infoObject = JObject.Parse(result.Content.ReadAsStringAsync().Result); 124 | return infoObject; 125 | } 126 | return null; 127 | 128 | } 129 | } 130 | ``` 131 | 5. ##### Bind ```IMyCustomProvider``` in ```ServiceCollectionExtensions``` 132 | 133 | ```csharp 134 | public static IServiceCollection AddProviders(this IServiceCollection services) 135 | { 136 | services.AddTransient(); 137 | services.AddTransient(); 138 | services.AddTransient(); 139 | services.AddTransient(); 140 | return services; 141 | } 142 | ``` 143 | 144 | 6. ##### Add ```MyCustomProvider``` to ```ExternalAuthenticationGrant``` 145 | ```csharp 146 | providers = new Dictionary(); 147 | providers.Add(ProviderType.Facebook, _facebookAuthProvider); 148 | providers.Add(ProviderType.Google, _googleAuthProvider); 149 | providers.Add(ProviderType.Twitter, _twitterAuthProvider); 150 | providers.Add(ProviderType.LinkedIn, _linkedAuthProvider); 151 | providers.Add(ProviderType.MyCustomProvider, _myCustomProvider); 152 | ``` 153 | 7. ##### Make a request to IdentityServer using new provider 154 | 155 | ``` 156 | POST connect/token 157 | 158 | client_id = [your_client_id] 159 | client_secret = [your_client_secret] 160 | scopes = [your_scopes] 161 | grant_type = external 162 | provider = mycustomprovider 163 | external_token = [access_token_from_custom_provider] 164 | ``` 165 | -------------------------------------------------------------------------------- /Sample/Api/Api.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | en-001 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Sample/Api/Controllers/ValuesController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using Microsoft.AspNetCore.Mvc; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace Api.Controllers 9 | { 10 | [Authorize] 11 | [Route("[controller]/[action]")] 12 | public class ValuesController : Controller 13 | { 14 | [HttpGet] 15 | public IActionResult Get() 16 | { 17 | var claims = from c in User.Claims 18 | select new { c.Type, c.Value }; 19 | 20 | return new JsonResult(claims); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Sample/Api/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace Api 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | BuildWebHost(args).Run(); 18 | } 19 | 20 | public static IWebHost BuildWebHost(string[] args) => 21 | WebHost.CreateDefaultBuilder(args) 22 | .UseStartup() 23 | .Build(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Sample/Api/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:4343/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "Api": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:4344/" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Sample/Api/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.Http; 8 | using Microsoft.Extensions.DependencyInjection; 9 | using Microsoft.AspNetCore.Authentication.JwtBearer; 10 | 11 | namespace Api 12 | { 13 | public class Startup 14 | { 15 | // This method gets called by the runtime. Use this method to add services to the container. 16 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 17 | public void ConfigureServices(IServiceCollection services) 18 | { 19 | 20 | services.AddAuthentication(o => 21 | { 22 | o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; 23 | o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; 24 | }).AddJwtBearer(o => 25 | { 26 | o.Authority = "http://localhost:17640/"; 27 | o.Audience = "Test.WebApi"; 28 | o.RequireHttpsMetadata = false; 29 | }); 30 | 31 | services.AddCors(options => 32 | { 33 | options.AddPolicy("Cors", builder => 34 | { 35 | builder.AllowAnyHeader(); 36 | builder.AllowAnyMethod(); 37 | builder.AllowAnyOrigin(); 38 | }); 39 | }); 40 | 41 | services.AddMvc(); 42 | } 43 | 44 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 45 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 46 | { 47 | if (env.IsDevelopment()) 48 | { 49 | app.UseDeveloperExceptionPage(); 50 | } 51 | 52 | app.UseCors("Cors"); 53 | app.UseAuthentication(); 54 | app.UseMvc(); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Sample/Api/obj/Debug/netcoreapp2.0/Api.AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | using System; 12 | using System.Reflection; 13 | 14 | [assembly: System.Reflection.AssemblyCompanyAttribute("Api")] 15 | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] 16 | [assembly: System.Reflection.AssemblyDescriptionAttribute("Package Description")] 17 | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] 18 | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] 19 | [assembly: System.Reflection.AssemblyProductAttribute("Api")] 20 | [assembly: System.Reflection.AssemblyTitleAttribute("Api")] 21 | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] 22 | 23 | // Generated by the MSBuild WriteCodeFragment class. 24 | 25 | -------------------------------------------------------------------------------- /Sample/Client/Client/Client.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | en-001 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Sample/Client/Client/Controllers/ExternalAuthController.cs: -------------------------------------------------------------------------------- 1 | using Client.Models; 2 | using IdentityModel.Client; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Newtonsoft.Json.Linq; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Net.Http; 9 | using System.Threading.Tasks; 10 | 11 | namespace Client.Controllers 12 | { 13 | [Route("[controller]/[action]")] 14 | public class ExternalAuthController : Controller 15 | { 16 | private const string Authority = "http://localhost:17640/"; 17 | private const string ClientId = "Test.Client"; 18 | private const string Secret = "secret"; 19 | private const string ApiBaseAddress = "http://localhost:4343/"; 20 | 21 | [HttpPost] 22 | public async Task Login(ExternalUserViewModel model) 23 | { 24 | if (ModelState.IsValid) 25 | { 26 | var disco = await DiscoveryClient.GetAsync(Authority); 27 | if (disco.IsError) throw new Exception(disco.Error); 28 | 29 | var tokenClient = new TokenClient(disco.TokenEndpoint, ClientId, Secret); 30 | 31 | var payload = new 32 | { 33 | // provider can be [facebook, google , twitter] 34 | provider = model.Provider, 35 | 36 | //retrieve access token from your respective provider 37 | //in case of facebook , use facebook javascript SDK or C# SDK 38 | external_token = model.AccessToken, 39 | 40 | //email is optional, because it may or maynot be retrieved from 41 | //the provider, if email is retrieved from the provider then a new user 42 | //is created using that email, else the extension grant sends the user object 43 | // and prompts to provide an email in order to create a user, this would happen for the 44 | // first time only, every subsequent request (after user creation) would only require the 45 | //respective access token from the provider. 46 | email = model.Email 47 | }; 48 | 49 | //Use our custom ExtensionGrant i.e. "external" 50 | 51 | var result = await tokenClient.RequestCustomGrantAsync("external", "Test.WebApi", payload); 52 | 53 | /* 54 | * 55 | * if there is an Error in the result then it means the user has not yet been created, so 56 | * the user object is returned and user is prompted to provide an email 57 | * 58 | * */ 59 | if(result.IsError) return new JsonResult(result.Json); 60 | 61 | 62 | /* 63 | * 64 | * If we get the access_token back from the Identity server then it means 65 | * use is Logged In successfully. 66 | * So make an API request to our protected API. 67 | * 68 | * */ 69 | 70 | if (!string.IsNullOrWhiteSpace(result.AccessToken)) 71 | { 72 | return new JsonResult(new { access_token = result.AccessToken }); 73 | } 74 | 75 | 76 | } 77 | return new JsonResult(null); 78 | } 79 | 80 | private async Task ApiRequest(string accessToken) 81 | { 82 | var client = new HttpClient 83 | { 84 | BaseAddress = new Uri(ApiBaseAddress) 85 | }; 86 | 87 | client.SetBearerToken(accessToken); 88 | 89 | var result = await client.GetStringAsync("Values/Get"); 90 | return new JsonResult(JArray.Parse(result)); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Sample/Client/Client/Models/ExternalUserViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Client.Models 4 | { 5 | public class ExternalUserViewModel 6 | { 7 | public string Email { get; set; } 8 | [Required] 9 | public string AccessToken { get; set; } 10 | [Required] 11 | public string Provider { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /Sample/Client/Client/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace Client 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | BuildWebHost(args).Run(); 18 | } 19 | 20 | public static IWebHost BuildWebHost(string[] args) => 21 | WebHost.CreateDefaultBuilder(args) 22 | .UseStartup() 23 | .Build(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Sample/Client/Client/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:4420/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "Client": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:4421/" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Sample/Client/Client/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.Http; 8 | using Microsoft.Extensions.DependencyInjection; 9 | 10 | namespace Client 11 | { 12 | public class Startup 13 | { 14 | // This method gets called by the runtime. Use this method to add services to the container. 15 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 16 | public void ConfigureServices(IServiceCollection services) 17 | { 18 | services.AddCors(opts => 19 | { 20 | opts.AddPolicy("CorsPolicy", builder => 21 | { 22 | builder.AllowAnyOrigin() 23 | .AllowAnyMethod() 24 | .AllowAnyHeader() 25 | .AllowCredentials(); 26 | }); 27 | }); 28 | services.AddMvc(); 29 | } 30 | 31 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 32 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 33 | { 34 | if (env.IsDevelopment()) 35 | { 36 | app.UseDeveloperExceptionPage(); 37 | } 38 | 39 | app.UseCors("CorsPolicy"); 40 | app.UseMvc(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Sample/Client/Client/obj/Debug/netcoreapp2.0/Client.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Client\Client\bin\Debug\netcoreapp2.0\Client.deps.json 2 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Client\Client\bin\Debug\netcoreapp2.0\Client.runtimeconfig.json 3 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Client\Client\bin\Debug\netcoreapp2.0\Client.runtimeconfig.dev.json 4 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Client\Client\bin\Debug\netcoreapp2.0\Client.dll 5 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Client\Client\obj\Debug\netcoreapp2.0\Client.csproj.CoreCompileInputs.cache 6 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Client\Client\obj\Debug\netcoreapp2.0\Client.AssemblyInfoInputs.cache 7 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Client\Client\obj\Debug\netcoreapp2.0\Client.AssemblyInfo.cs 8 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Client\Client\obj\Debug\netcoreapp2.0\Client.csprojResolveAssemblyReference.cache 9 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Client\Client\bin\Debug\netcoreapp2.0\Client.pdb 10 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Client\Client\obj\Debug\netcoreapp2.0\Client.dll 11 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Client\Client\obj\Debug\netcoreapp2.0\Client.pdb 12 | -------------------------------------------------------------------------------- /Sample/Google/01-JavaScriptClient/JavaScriptClient/JavaScriptClient.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sample/Google/01-JavaScriptClient/JavaScriptClient/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace JavaScriptClient 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | BuildWebHost(args).Run(); 18 | } 19 | 20 | public static IWebHost BuildWebHost(string[] args) => 21 | WebHost.CreateDefaultBuilder(args) 22 | .UseStartup() 23 | .Build(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Sample/Google/01-JavaScriptClient/JavaScriptClient/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:16519/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "JavaScriptClient": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:16520/" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Sample/Google/01-JavaScriptClient/JavaScriptClient/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.Http; 8 | using Microsoft.Extensions.DependencyInjection; 9 | 10 | namespace JavaScriptClient 11 | { 12 | public class Startup 13 | { 14 | // This method gets called by the runtime. Use this method to add services to the container. 15 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 16 | public void ConfigureServices(IServiceCollection services) 17 | { 18 | } 19 | 20 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 21 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 22 | { 23 | if (env.IsDevelopment()) 24 | { 25 | app.UseDeveloperExceptionPage(); 26 | } 27 | 28 | app.UseDefaultFiles(); 29 | app.UseStaticFiles(); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Sample/Google/01-JavaScriptClient/JavaScriptClient/obj/Debug/netcoreapp2.0/JavaScriptClient.AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | using System; 12 | using System.Reflection; 13 | 14 | [assembly: System.Reflection.AssemblyCompanyAttribute("JavaScriptClient")] 15 | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] 16 | [assembly: System.Reflection.AssemblyDescriptionAttribute("Package Description")] 17 | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] 18 | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] 19 | [assembly: System.Reflection.AssemblyProductAttribute("JavaScriptClient")] 20 | [assembly: System.Reflection.AssemblyTitleAttribute("JavaScriptClient")] 21 | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] 22 | 23 | // Generated by the MSBuild WriteCodeFragment class. 24 | 25 | -------------------------------------------------------------------------------- /Sample/Google/01-JavaScriptClient/JavaScriptClient/obj/Debug/netcoreapp2.0/JavaScriptClient.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Google\01-JavaScriptClient\JavaScriptClient\bin\Debug\netcoreapp2.0\JavaScriptClient.deps.json 2 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Google\01-JavaScriptClient\JavaScriptClient\bin\Debug\netcoreapp2.0\JavaScriptClient.runtimeconfig.json 3 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Google\01-JavaScriptClient\JavaScriptClient\bin\Debug\netcoreapp2.0\JavaScriptClient.runtimeconfig.dev.json 4 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Google\01-JavaScriptClient\JavaScriptClient\bin\Debug\netcoreapp2.0\JavaScriptClient.dll 5 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Google\01-JavaScriptClient\JavaScriptClient\bin\Debug\netcoreapp2.0\JavaScriptClient.pdb 6 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Google\01-JavaScriptClient\JavaScriptClient\obj\Debug\netcoreapp2.0\JavaScriptClient.csprojResolveAssemblyReference.cache 7 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Google\01-JavaScriptClient\JavaScriptClient\obj\Debug\netcoreapp2.0\JavaScriptClient.csproj.CoreCompileInputs.cache 8 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Google\01-JavaScriptClient\JavaScriptClient\obj\Debug\netcoreapp2.0\JavaScriptClient.AssemblyInfoInputs.cache 9 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Google\01-JavaScriptClient\JavaScriptClient\obj\Debug\netcoreapp2.0\JavaScriptClient.AssemblyInfo.cs 10 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Google\01-JavaScriptClient\JavaScriptClient\obj\Debug\netcoreapp2.0\JavaScriptClient.dll 11 | D:\GitHub\IdentityServerExternal\IdentityServerExternalAuth\Sample\Google\01-JavaScriptClient\JavaScriptClient\obj\Debug\netcoreapp2.0\JavaScriptClient.pdb 12 | -------------------------------------------------------------------------------- /Sample/Google/01-JavaScriptClient/JavaScriptClient/obj/Debug/netcoreapp2.0/JavaScriptClient.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waqaskhan540/IdentityServerExternalAuth/4817655c3c9fdb8b9acb452546791eaf4a3d49b8/Sample/Google/01-JavaScriptClient/JavaScriptClient/obj/Debug/netcoreapp2.0/JavaScriptClient.dll -------------------------------------------------------------------------------- /Sample/Google/01-JavaScriptClient/JavaScriptClient/wwwroot/index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | JavaScript Client 7 | 8 | 9 | 64 | 65 | 66 |

67 |
68 |
69 |
70 | 71 | -------------------------------------------------------------------------------- /screenshots/id1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waqaskhan540/IdentityServerExternalAuth/4817655c3c9fdb8b9acb452546791eaf4a3d49b8/screenshots/id1.PNG -------------------------------------------------------------------------------- /screenshots/id2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waqaskhan540/IdentityServerExternalAuth/4817655c3c9fdb8b9acb452546791eaf4a3d49b8/screenshots/id2.PNG --------------------------------------------------------------------------------