├── .gitattributes ├── .gitignore ├── IdentityServer ├── Config.cs ├── IdentityServer.csproj ├── Program.cs ├── Properties │ └── launchSettings.json ├── Quickstart │ ├── Account │ │ ├── AccountController.cs │ │ ├── AccountOptions.cs │ │ ├── ExternalController.cs │ │ ├── ExternalProvider.cs │ │ ├── LoggedOutViewModel.cs │ │ ├── LoginInputModel.cs │ │ ├── LoginViewModel.cs │ │ ├── LogoutInputModel.cs │ │ ├── LogoutViewModel.cs │ │ └── RedirectViewModel.cs │ ├── Consent │ │ ├── ConsentController.cs │ │ ├── ConsentInputModel.cs │ │ ├── ConsentOptions.cs │ │ ├── ConsentViewModel.cs │ │ ├── ProcessConsentResult.cs │ │ └── ScopeViewModel.cs │ ├── Diagnostics │ │ ├── DiagnosticsController.cs │ │ └── DiagnosticsViewModel.cs │ ├── Extensions.cs │ ├── Grants │ │ ├── GrantsController.cs │ │ └── GrantsViewModel.cs │ ├── Home │ │ ├── ErrorViewModel.cs │ │ └── HomeController.cs │ ├── SecurityHeadersAttribute.cs │ └── TestUsers.cs ├── Startup.cs ├── Views │ ├── Account │ │ ├── LoggedOut.cshtml │ │ ├── Login.cshtml │ │ └── Logout.cshtml │ ├── Consent │ │ ├── Index.cshtml │ │ └── _ScopeListItem.cshtml │ ├── Diagnostics │ │ └── Index.cshtml │ ├── Grants │ │ └── Index.cshtml │ ├── Home │ │ └── Index.cshtml │ ├── Shared │ │ ├── Error.cshtml │ │ ├── Redirect.cshtml │ │ ├── _Layout.cshtml │ │ └── _ValidationSummary.cshtml │ ├── _ViewImports.cshtml │ └── _ViewStart.cshtml ├── appsettings.Development.json ├── appsettings.json ├── tempkey.rsa └── wwwroot │ ├── css │ ├── site.css │ ├── site.less │ └── site.min.css │ ├── favicon.ico │ ├── icon.jpg │ ├── icon.png │ ├── images │ ├── banner1.svg │ ├── banner2.svg │ └── banner3.svg │ ├── js │ ├── signin-redirect.js │ ├── signout-redirect.js │ ├── site.js │ └── site.min.js │ └── lib │ ├── bootstrap │ ├── .bower.json │ ├── LICENSE │ ├── css │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ └── bootstrap.min.css │ ├── dist │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap-theme.min.css.map │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ └── npm.js │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ └── js │ │ ├── bootstrap.js │ │ └── bootstrap.min.js │ ├── jquery-validation-unobtrusive │ ├── .bower.json │ ├── LICENSE.txt │ ├── jquery.validate.unobtrusive.js │ └── jquery.validate.unobtrusive.min.js │ ├── jquery-validation │ ├── .bower.json │ ├── LICENSE.md │ └── dist │ │ ├── additional-methods.js │ │ ├── additional-methods.min.js │ │ ├── jquery.validate.js │ │ └── jquery.validate.min.js │ └── jquery │ ├── .bower.json │ ├── LICENSE.txt │ ├── dist │ ├── jquery.js │ ├── jquery.min.js │ └── jquery.min.map │ ├── jquery.js │ ├── jquery.min.js │ └── jquery.min.map ├── IdentityServerWithMvc.sln ├── MvcClient ├── Controllers │ ├── AdminController.cs │ └── HomeController.cs ├── Models │ └── ErrorViewModel.cs ├── MvcClient.csproj ├── Program.cs ├── Properties │ └── launchSettings.json ├── Startup.cs ├── Views │ ├── Admin │ │ └── Secure.cshtml │ ├── Home │ │ ├── About.cshtml │ │ ├── Contact.cshtml │ │ ├── Index.cshtml │ │ └── Privacy.cshtml │ ├── Shared │ │ ├── Error.cshtml │ │ ├── _CookieConsentPartial.cshtml │ │ ├── _Layout.cshtml │ │ └── _ValidationScriptsPartial.cshtml │ ├── _ViewImports.cshtml │ └── _ViewStart.cshtml ├── appsettings.Development.json ├── appsettings.json └── wwwroot │ ├── css │ ├── site.css │ └── site.min.css │ ├── favicon.ico │ ├── images │ ├── banner1.svg │ ├── banner2.svg │ └── banner3.svg │ ├── js │ ├── site.js │ └── site.min.js │ └── lib │ ├── bootstrap │ ├── .bower.json │ ├── LICENSE │ └── dist │ │ ├── css │ │ ├── bootstrap-theme.css │ │ ├── bootstrap-theme.css.map │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap-theme.min.css.map │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ ├── bootstrap.js │ │ ├── bootstrap.min.js │ │ └── npm.js │ ├── jquery-validation-unobtrusive │ ├── .bower.json │ ├── LICENSE.txt │ ├── jquery.validate.unobtrusive.js │ └── jquery.validate.unobtrusive.min.js │ ├── jquery-validation │ ├── .bower.json │ ├── LICENSE.md │ └── dist │ │ ├── additional-methods.js │ │ ├── additional-methods.min.js │ │ ├── jquery.validate.js │ │ └── jquery.validate.min.js │ └── jquery │ ├── .bower.json │ ├── LICENSE.txt │ └── dist │ ├── jquery.js │ ├── jquery.min.js │ └── jquery.min.map └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc -------------------------------------------------------------------------------- /IdentityServer/Config.cs: -------------------------------------------------------------------------------- 1 | using IdentityModel; 2 | using IdentityServer4; 3 | using IdentityServer4.Models; 4 | using IdentityServer4.Test; 5 | using System.Collections.Generic; 6 | using System.Security.Claims; 7 | 8 | namespace IdentityServer 9 | { 10 | public class Config 11 | { 12 | // scopes define the resources in your system 13 | public static IEnumerable GetIdentityResources() 14 | { 15 | return new List 16 | { 17 | new IdentityResources.OpenId(), 18 | new IdentityResources.Profile(), 19 | }; 20 | } 21 | 22 | // clients want to access resources (aka scopes) 23 | public static IEnumerable GetClients() 24 | { 25 | // client credentials client 26 | return new List 27 | { 28 | // OpenID Connect implicit flow client (MVC) 29 | new Client 30 | { 31 | ClientId = "mvc", 32 | ClientName = "MVC Client", 33 | AllowedGrantTypes = GrantTypes.Code, 34 | RequireConsent = false, 35 | 36 | RedirectUris = { "https://localhost:5001/signin-oidc" }, 37 | PostLogoutRedirectUris = { "https://localhost:5001/signout-callback-oidc" }, 38 | ClientSecrets = {new Secret("super-secret".ToSha256(),"mvc-secret") }, 39 | AllowedScopes = 40 | { 41 | IdentityServerConstants.StandardScopes.OpenId, 42 | IdentityServerConstants.StandardScopes.Profile, 43 | IdentityServerConstants.StandardScopes.Email, 44 | IdentityServerConstants.StandardScopes.Address, 45 | "website" 46 | } 47 | } 48 | }; 49 | } 50 | 51 | public static List GetUsers() 52 | { 53 | return new List 54 | { 55 | new TestUser 56 | { 57 | SubjectId = "1", 58 | Username = "bruno", 59 | Password = "1234", 60 | 61 | Claims = new List 62 | { 63 | new Claim(JwtClaimTypes.Name, "Bruno"), 64 | new Claim(JwtClaimTypes.GivenName, "Bruno Brito"), 65 | new Claim(JwtClaimTypes.FamilyName, "Brito"), 66 | new Claim(JwtClaimTypes.Email, "bhdebrito@gmail.com"), 67 | new Claim(JwtClaimTypes.EmailVerified, "true", ClaimValueTypes.Boolean), 68 | new Claim(JwtClaimTypes.WebSite, "http://www.saindodacaixinha.com.br"), 69 | new Claim(JwtClaimTypes.Address, @"{ 'street_address': 'Av Paulista', 'locality': 'Sao Paulo', 'postal_code': 0332303, 'country': 'Brazil' }", IdentityServer4.IdentityServerConstants.ClaimValueTypes.Json) 70 | 71 | } 72 | }, 73 | new TestUser 74 | { 75 | SubjectId = "2", 76 | Username = "jp", 77 | Password = "1234", 78 | 79 | Claims = new List 80 | { 81 | new Claim(JwtClaimTypes.Name, "JP"), 82 | new Claim(JwtClaimTypes.GivenName, "Joao Pedro"), 83 | new Claim(JwtClaimTypes.FamilyName, "Silva"), 84 | new Claim(JwtClaimTypes.Email, "BobSmith@email.com"), 85 | new Claim(JwtClaimTypes.EmailVerified, "true", ClaimValueTypes.Boolean), 86 | new Claim(JwtClaimTypes.WebSite, "http://globo.com"), 87 | new Claim(JwtClaimTypes.Address, @"{ 'street_address': 'Rua da Consolacao', 'locality': 'Sao Paulo', 'postal_code': 02565333, 'country': 'Brasil' }", IdentityServer4.IdentityServerConstants.ClaimValueTypes.Json), 88 | new Claim("location", "Brazil") 89 | } 90 | } 91 | }; 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /IdentityServer/IdentityServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /IdentityServer/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Hosting; 3 | 4 | namespace IdentityServer 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | CreateHostBuilder(args).Build().Run(); 11 | } 12 | 13 | public static IHostBuilder CreateHostBuilder(string[] args) => 14 | Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args) 15 | .ConfigureWebHostDefaults(webBuilder => 16 | { 17 | webBuilder.UseStartup(); 18 | }); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /IdentityServer/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:5000", 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 | "IdentityServer": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:5000" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Account/AccountOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | using System; 6 | 7 | namespace IdentityServer.Quickstart.Account 8 | { 9 | public class AccountOptions 10 | { 11 | public static bool AllowLocalLogin = true; 12 | public static bool AllowRememberLogin = true; 13 | public static TimeSpan RememberMeLoginDuration = TimeSpan.FromDays(30); 14 | 15 | public static bool ShowLogoutPrompt = true; 16 | public static bool AutomaticRedirectAfterSignOut = false; 17 | 18 | // specify the Windows authentication scheme being used 19 | public static readonly string WindowsAuthenticationSchemeName = Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme; 20 | // if user uses windows auth, should we load the groups from windows 21 | public static bool IncludeWindowsGroups = false; 22 | 23 | public static string InvalidCredentialsErrorMessage = "Invalid username or password"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Account/ExternalController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Security.Claims; 5 | using System.Security.Principal; 6 | using System.Threading.Tasks; 7 | using IdentityModel; 8 | using IdentityServer4.Events; 9 | using IdentityServer4.Services; 10 | using IdentityServer4.Stores; 11 | using IdentityServer4.Test; 12 | using Microsoft.AspNetCore.Authentication; 13 | using Microsoft.AspNetCore.Authorization; 14 | using Microsoft.AspNetCore.Http; 15 | using Microsoft.AspNetCore.Mvc; 16 | 17 | namespace IdentityServer.Quickstart.Account 18 | { 19 | [SecurityHeaders] 20 | [AllowAnonymous] 21 | public class ExternalController : Controller 22 | { 23 | private readonly TestUserStore _users; 24 | private readonly IIdentityServerInteractionService _interaction; 25 | private readonly IClientStore _clientStore; 26 | private readonly IEventService _events; 27 | 28 | public ExternalController( 29 | IIdentityServerInteractionService interaction, 30 | IClientStore clientStore, 31 | IEventService events, 32 | TestUserStore users = null) 33 | { 34 | // if the TestUserStore is not in DI, then we'll just use the global users collection 35 | // this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity) 36 | _users = users ?? new TestUserStore(TestUsers.Users); 37 | 38 | _interaction = interaction; 39 | _clientStore = clientStore; 40 | _events = events; 41 | } 42 | 43 | /// 44 | /// initiate roundtrip to external authentication provider 45 | /// 46 | [HttpGet] 47 | public async Task Challenge(string provider, string returnUrl) 48 | { 49 | if (string.IsNullOrEmpty(returnUrl)) returnUrl = "~/"; 50 | 51 | // validate returnUrl - either it is a valid OIDC URL or back to a local page 52 | if (Url.IsLocalUrl(returnUrl) == false && _interaction.IsValidReturnUrl(returnUrl) == false) 53 | { 54 | // user might have clicked on a malicious link - should be logged 55 | throw new Exception("invalid return URL"); 56 | } 57 | 58 | if (AccountOptions.WindowsAuthenticationSchemeName == provider) 59 | { 60 | // windows authentication needs special handling 61 | return await ProcessWindowsLoginAsync(returnUrl); 62 | } 63 | else 64 | { 65 | // start challenge and roundtrip the return URL and scheme 66 | var props = new AuthenticationProperties 67 | { 68 | RedirectUri = Url.Action(nameof(Callback)), 69 | Items = 70 | { 71 | { "returnUrl", returnUrl }, 72 | { "scheme", provider }, 73 | } 74 | }; 75 | 76 | return Challenge(props, provider); 77 | } 78 | } 79 | 80 | /// 81 | /// Post processing of external authentication 82 | /// 83 | [HttpGet] 84 | public async Task Callback() 85 | { 86 | // read external identity from the temporary cookie 87 | var result = await HttpContext.AuthenticateAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); 88 | if (result?.Succeeded != true) 89 | { 90 | throw new Exception("External authentication error"); 91 | } 92 | 93 | // lookup our user and external provider info 94 | var (user, provider, providerUserId, claims) = FindUserFromExternalProvider(result); 95 | if (user == null) 96 | { 97 | // this might be where you might initiate a custom workflow for user registration 98 | // in this sample we don't show how that would be done, as our sample implementation 99 | // simply auto-provisions new external user 100 | user = AutoProvisionUser(provider, providerUserId, claims); 101 | } 102 | 103 | // this allows us to collect any additonal claims or properties 104 | // for the specific prtotocols used and store them in the local auth cookie. 105 | // this is typically used to store data needed for signout from those protocols. 106 | var additionalLocalClaims = new List(); 107 | var localSignInProps = new AuthenticationProperties(); 108 | ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps); 109 | ProcessLoginCallbackForWsFed(result, additionalLocalClaims, localSignInProps); 110 | ProcessLoginCallbackForSaml2p(result, additionalLocalClaims, localSignInProps); 111 | 112 | // issue authentication cookie for user 113 | await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.SubjectId, user.Username)); 114 | await HttpContext.SignInAsync(user.SubjectId, user.Username, provider, localSignInProps, additionalLocalClaims.ToArray()); 115 | 116 | // delete temporary cookie used during external authentication 117 | await HttpContext.SignOutAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); 118 | 119 | // retrieve return URL 120 | var returnUrl = result.Properties.Items["returnUrl"] ?? "~/"; 121 | 122 | // check if external login is in the context of an OIDC request 123 | var context = await _interaction.GetAuthorizationContextAsync(returnUrl); 124 | if (context != null) 125 | { 126 | if (await _clientStore.IsPkceClientAsync(context.ClientId)) 127 | { 128 | // if the client is PKCE then we assume it's native, so this change in how to 129 | // return the response is for better UX for the end user. 130 | return View("Redirect", new RedirectViewModel { RedirectUrl = returnUrl }); 131 | } 132 | } 133 | 134 | return Redirect(returnUrl); 135 | } 136 | 137 | private async Task ProcessWindowsLoginAsync(string returnUrl) 138 | { 139 | // see if windows auth has already been requested and succeeded 140 | var result = await HttpContext.AuthenticateAsync(AccountOptions.WindowsAuthenticationSchemeName); 141 | if (result?.Principal is WindowsPrincipal wp) 142 | { 143 | // we will issue the external cookie and then redirect the 144 | // user back to the external callback, in essence, tresting windows 145 | // auth the same as any other external authentication mechanism 146 | var props = new AuthenticationProperties() 147 | { 148 | RedirectUri = Url.Action("Callback"), 149 | Items = 150 | { 151 | { "returnUrl", returnUrl }, 152 | { "scheme", AccountOptions.WindowsAuthenticationSchemeName }, 153 | } 154 | }; 155 | 156 | var id = new ClaimsIdentity(AccountOptions.WindowsAuthenticationSchemeName); 157 | id.AddClaim(new Claim(JwtClaimTypes.Subject, wp.Identity.Name)); 158 | id.AddClaim(new Claim(JwtClaimTypes.Name, wp.Identity.Name)); 159 | 160 | // add the groups as claims -- be careful if the number of groups is too large 161 | if (AccountOptions.IncludeWindowsGroups) 162 | { 163 | var wi = wp.Identity as WindowsIdentity; 164 | var groups = wi.Groups.Translate(typeof(NTAccount)); 165 | var roles = groups.Select(x => new Claim(JwtClaimTypes.Role, x.Value)); 166 | id.AddClaims(roles); 167 | } 168 | 169 | await HttpContext.SignInAsync( 170 | IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme, 171 | new ClaimsPrincipal(id), 172 | props); 173 | return Redirect(props.RedirectUri); 174 | } 175 | else 176 | { 177 | // trigger windows auth 178 | // since windows auth don't support the redirect uri, 179 | // this URL is re-triggered when we call challenge 180 | return Challenge(AccountOptions.WindowsAuthenticationSchemeName); 181 | } 182 | } 183 | 184 | private (TestUser user, string provider, string providerUserId, IEnumerable claims) FindUserFromExternalProvider(AuthenticateResult result) 185 | { 186 | var externalUser = result.Principal; 187 | 188 | // try to determine the unique id of the external user (issued by the provider) 189 | // the most common claim type for that are the sub claim and the NameIdentifier 190 | // depending on the external provider, some other claim type might be used 191 | var userIdClaim = externalUser.FindFirst(JwtClaimTypes.Subject) ?? 192 | externalUser.FindFirst(ClaimTypes.NameIdentifier) ?? 193 | throw new Exception("Unknown userid"); 194 | 195 | // remove the user id claim so we don't include it as an extra claim if/when we provision the user 196 | var claims = externalUser.Claims.ToList(); 197 | claims.Remove(userIdClaim); 198 | 199 | var provider = result.Properties.Items["scheme"]; 200 | var providerUserId = userIdClaim.Value; 201 | 202 | // find external user 203 | var user = _users.FindByExternalProvider(provider, providerUserId); 204 | 205 | return (user, provider, providerUserId, claims); 206 | } 207 | 208 | private TestUser AutoProvisionUser(string provider, string providerUserId, IEnumerable claims) 209 | { 210 | var user = _users.AutoProvisionUser(provider, providerUserId, claims.ToList()); 211 | return user; 212 | } 213 | 214 | private void ProcessLoginCallbackForOidc(AuthenticateResult externalResult, List localClaims, AuthenticationProperties localSignInProps) 215 | { 216 | // if the external system sent a session id claim, copy it over 217 | // so we can use it for single sign-out 218 | var sid = externalResult.Principal.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId); 219 | if (sid != null) 220 | { 221 | localClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value)); 222 | } 223 | 224 | // if the external provider issued an id_token, we'll keep it for signout 225 | var id_token = externalResult.Properties.GetTokenValue("id_token"); 226 | if (id_token != null) 227 | { 228 | localSignInProps.StoreTokens(new[] { new AuthenticationToken { Name = "id_token", Value = id_token } }); 229 | } 230 | } 231 | 232 | private void ProcessLoginCallbackForWsFed(AuthenticateResult externalResult, List localClaims, AuthenticationProperties localSignInProps) 233 | { 234 | } 235 | 236 | private void ProcessLoginCallbackForSaml2p(AuthenticateResult externalResult, List localClaims, AuthenticationProperties localSignInProps) 237 | { 238 | } 239 | } 240 | } -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Account/ExternalProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | namespace IdentityServer.Quickstart.Account 6 | { 7 | public class ExternalProvider 8 | { 9 | public string DisplayName { get; set; } 10 | public string AuthenticationScheme { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Account/LoggedOutViewModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | namespace IdentityServer.Quickstart.Account 6 | { 7 | public class LoggedOutViewModel 8 | { 9 | public string PostLogoutRedirectUri { get; set; } 10 | public string ClientName { get; set; } 11 | public string SignOutIframeUrl { get; set; } 12 | 13 | public bool AutomaticRedirectAfterSignOut { get; set; } = false; 14 | 15 | public string LogoutId { get; set; } 16 | public bool TriggerExternalSignout => ExternalAuthenticationScheme != null; 17 | public string ExternalAuthenticationScheme { get; set; } 18 | } 19 | } -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Account/LoginInputModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | using System.ComponentModel.DataAnnotations; 6 | 7 | namespace IdentityServer.Quickstart.Account 8 | { 9 | public class LoginInputModel 10 | { 11 | [Required] 12 | public string Username { get; set; } 13 | [Required] 14 | public string Password { get; set; } 15 | public bool RememberLogin { get; set; } 16 | public string ReturnUrl { get; set; } 17 | } 18 | } -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Account/LoginViewModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | 9 | namespace IdentityServer.Quickstart.Account 10 | { 11 | public class LoginViewModel : LoginInputModel 12 | { 13 | public bool AllowRememberLogin { get; set; } = true; 14 | public bool EnableLocalLogin { get; set; } = true; 15 | 16 | public IEnumerable ExternalProviders { get; set; } 17 | public IEnumerable VisibleExternalProviders => ExternalProviders.Where(x => !String.IsNullOrWhiteSpace(x.DisplayName)); 18 | 19 | public bool IsExternalLoginOnly => EnableLocalLogin == false && ExternalProviders?.Count() == 1; 20 | public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null; 21 | } 22 | } -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Account/LogoutInputModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | namespace IdentityServer.Quickstart.Account 6 | { 7 | public class LogoutInputModel 8 | { 9 | public string LogoutId { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Account/LogoutViewModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | namespace IdentityServer.Quickstart.Account 6 | { 7 | public class LogoutViewModel : LogoutInputModel 8 | { 9 | public bool ShowLogoutPrompt { get; set; } = true; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Account/RedirectViewModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | 6 | namespace IdentityServer.Quickstart.Account 7 | { 8 | public class RedirectViewModel 9 | { 10 | public string RedirectUrl { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Consent/ConsentController.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using IdentityServer.Quickstart.Account; 8 | using IdentityServer4.Events; 9 | using IdentityServer4.Extensions; 10 | using IdentityServer4.Models; 11 | using IdentityServer4.Services; 12 | using IdentityServer4.Stores; 13 | using Microsoft.AspNetCore.Authorization; 14 | using Microsoft.AspNetCore.Mvc; 15 | using Microsoft.Extensions.Logging; 16 | 17 | namespace IdentityServer.Quickstart.Consent 18 | { 19 | /// 20 | /// This controller processes the consent UI 21 | /// 22 | [SecurityHeaders] 23 | [Authorize] 24 | public class ConsentController : Controller 25 | { 26 | private readonly IIdentityServerInteractionService _interaction; 27 | private readonly IClientStore _clientStore; 28 | private readonly IResourceStore _resourceStore; 29 | private readonly IEventService _events; 30 | private readonly ILogger _logger; 31 | 32 | public ConsentController( 33 | IIdentityServerInteractionService interaction, 34 | IClientStore clientStore, 35 | IResourceStore resourceStore, 36 | IEventService events, 37 | ILogger logger) 38 | { 39 | _interaction = interaction; 40 | _clientStore = clientStore; 41 | _resourceStore = resourceStore; 42 | _events = events; 43 | _logger = logger; 44 | } 45 | 46 | /// 47 | /// Shows the consent screen 48 | /// 49 | /// 50 | /// 51 | [HttpGet] 52 | public async Task Index(string returnUrl) 53 | { 54 | var vm = await BuildViewModelAsync(returnUrl); 55 | if (vm != null) 56 | { 57 | return View("Index", vm); 58 | } 59 | 60 | return View("Error"); 61 | } 62 | 63 | /// 64 | /// Handles the consent screen postback 65 | /// 66 | [HttpPost] 67 | [ValidateAntiForgeryToken] 68 | public async Task Index(ConsentInputModel model) 69 | { 70 | var result = await ProcessConsent(model); 71 | 72 | if (result.IsRedirect) 73 | { 74 | if (await _clientStore.IsPkceClientAsync(result.ClientId)) 75 | { 76 | // if the client is PKCE then we assume it's native, so this change in how to 77 | // return the response is for better UX for the end user. 78 | return View("Redirect", new RedirectViewModel { RedirectUrl = result.RedirectUri }); 79 | } 80 | 81 | return Redirect(result.RedirectUri); 82 | } 83 | 84 | if (result.HasValidationError) 85 | { 86 | ModelState.AddModelError("", result.ValidationError); 87 | } 88 | 89 | if (result.ShowView) 90 | { 91 | return View("Index", result.ViewModel); 92 | } 93 | 94 | return View("Error"); 95 | } 96 | 97 | /*****************************************/ 98 | /* helper APIs for the ConsentController */ 99 | /*****************************************/ 100 | private async Task ProcessConsent(ConsentInputModel model) 101 | { 102 | var result = new ProcessConsentResult(); 103 | 104 | // validate return url is still valid 105 | var request = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl); 106 | if (request == null) return result; 107 | 108 | ConsentResponse grantedConsent = null; 109 | 110 | // user clicked 'no' - send back the standard 'access_denied' response 111 | if (model.Button == "no") 112 | { 113 | grantedConsent = ConsentResponse.Denied; 114 | 115 | // emit event 116 | await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), result.ClientId, request.ScopesRequested)); 117 | } 118 | // user clicked 'yes' - validate the data 119 | else if (model.Button == "yes" && model != null) 120 | { 121 | // if the user consented to some scope, build the response model 122 | if (model.ScopesConsented != null && model.ScopesConsented.Any()) 123 | { 124 | var scopes = model.ScopesConsented; 125 | if (ConsentOptions.EnableOfflineAccess == false) 126 | { 127 | scopes = scopes.Where(x => x != IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess); 128 | } 129 | 130 | grantedConsent = new ConsentResponse 131 | { 132 | RememberConsent = model.RememberConsent, 133 | ScopesConsented = scopes.ToArray() 134 | }; 135 | 136 | // emit event 137 | await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.ClientId, request.ScopesRequested, grantedConsent.ScopesConsented, grantedConsent.RememberConsent)); 138 | } 139 | else 140 | { 141 | result.ValidationError = ConsentOptions.MustChooseOneErrorMessage; 142 | } 143 | } 144 | else 145 | { 146 | result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage; 147 | } 148 | 149 | if (grantedConsent != null) 150 | { 151 | // communicate outcome of consent back to identityserver 152 | await _interaction.GrantConsentAsync(request, grantedConsent); 153 | 154 | // indicate that's it ok to redirect back to authorization endpoint 155 | result.RedirectUri = model.ReturnUrl; 156 | result.ClientId = request.ClientId; 157 | } 158 | else 159 | { 160 | // we need to redisplay the consent UI 161 | result.ViewModel = await BuildViewModelAsync(model.ReturnUrl, model); 162 | } 163 | 164 | return result; 165 | } 166 | 167 | private async Task BuildViewModelAsync(string returnUrl, ConsentInputModel model = null) 168 | { 169 | var request = await _interaction.GetAuthorizationContextAsync(returnUrl); 170 | if (request != null) 171 | { 172 | var client = await _clientStore.FindEnabledClientByIdAsync(request.ClientId); 173 | if (client != null) 174 | { 175 | var resources = await _resourceStore.FindEnabledResourcesByScopeAsync(request.ScopesRequested); 176 | if (resources != null && (resources.IdentityResources.Any() || resources.ApiResources.Any())) 177 | { 178 | return CreateConsentViewModel(model, returnUrl, request, client, resources); 179 | } 180 | else 181 | { 182 | _logger.LogError("No scopes matching: {0}", request.ScopesRequested.Aggregate((x, y) => x + ", " + y)); 183 | } 184 | } 185 | else 186 | { 187 | _logger.LogError("Invalid client id: {0}", request.ClientId); 188 | } 189 | } 190 | else 191 | { 192 | _logger.LogError("No consent request matching request: {0}", returnUrl); 193 | } 194 | 195 | return null; 196 | } 197 | 198 | private ConsentViewModel CreateConsentViewModel( 199 | ConsentInputModel model, string returnUrl, 200 | AuthorizationRequest request, 201 | Client client, Resources resources) 202 | { 203 | var vm = new ConsentViewModel 204 | { 205 | RememberConsent = model?.RememberConsent ?? true, 206 | ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty(), 207 | 208 | ReturnUrl = returnUrl, 209 | 210 | ClientName = client.ClientName ?? client.ClientId, 211 | ClientUrl = client.ClientUri, 212 | ClientLogoUrl = client.LogoUri, 213 | AllowRememberConsent = client.AllowRememberConsent 214 | }; 215 | 216 | vm.IdentityScopes = resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray(); 217 | vm.ResourceScopes = resources.ApiResources.SelectMany(x => x.Scopes).Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray(); 218 | if (ConsentOptions.EnableOfflineAccess && resources.OfflineAccess) 219 | { 220 | vm.ResourceScopes = vm.ResourceScopes.Union(new ScopeViewModel[] { 221 | GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null) 222 | }); 223 | } 224 | 225 | return vm; 226 | } 227 | 228 | private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check) 229 | { 230 | return new ScopeViewModel 231 | { 232 | Name = identity.Name, 233 | DisplayName = identity.DisplayName, 234 | Description = identity.Description, 235 | Emphasize = identity.Emphasize, 236 | Required = identity.Required, 237 | Checked = check || identity.Required 238 | }; 239 | } 240 | 241 | public ScopeViewModel CreateScopeViewModel(Scope scope, bool check) 242 | { 243 | return new ScopeViewModel 244 | { 245 | Name = scope.Name, 246 | DisplayName = scope.DisplayName, 247 | Description = scope.Description, 248 | Emphasize = scope.Emphasize, 249 | Required = scope.Required, 250 | Checked = check || scope.Required 251 | }; 252 | } 253 | 254 | private ScopeViewModel GetOfflineAccessScope(bool check) 255 | { 256 | return new ScopeViewModel 257 | { 258 | Name = IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess, 259 | DisplayName = ConsentOptions.OfflineAccessDisplayName, 260 | Description = ConsentOptions.OfflineAccessDescription, 261 | Emphasize = true, 262 | Checked = check 263 | }; 264 | } 265 | } 266 | } -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Consent/ConsentInputModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | using System.Collections.Generic; 6 | 7 | namespace IdentityServer.Quickstart.Consent 8 | { 9 | public class ConsentInputModel 10 | { 11 | public string Button { get; set; } 12 | public IEnumerable ScopesConsented { get; set; } 13 | public bool RememberConsent { get; set; } 14 | public string ReturnUrl { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Consent/ConsentOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | namespace IdentityServer.Quickstart.Consent 6 | { 7 | public class ConsentOptions 8 | { 9 | public static bool EnableOfflineAccess = true; 10 | public static string OfflineAccessDisplayName = "Offline Access"; 11 | public static string OfflineAccessDescription = "Access to your applications and resources, even when you are offline"; 12 | 13 | public static readonly string MustChooseOneErrorMessage = "You must pick at least one permission"; 14 | public static readonly string InvalidSelectionErrorMessage = "Invalid selection"; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Consent/ConsentViewModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | using System.Collections.Generic; 6 | 7 | namespace IdentityServer.Quickstart.Consent 8 | { 9 | public class ConsentViewModel : ConsentInputModel 10 | { 11 | public string ClientName { get; set; } 12 | public string ClientUrl { get; set; } 13 | public string ClientLogoUrl { get; set; } 14 | public bool AllowRememberConsent { get; set; } 15 | 16 | public IEnumerable IdentityScopes { get; set; } 17 | public IEnumerable ResourceScopes { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Consent/ProcessConsentResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | namespace IdentityServer.Quickstart.Consent 6 | { 7 | public class ProcessConsentResult 8 | { 9 | public bool IsRedirect => RedirectUri != null; 10 | public string RedirectUri { get; set; } 11 | public string ClientId { get; set; } 12 | 13 | public bool ShowView => ViewModel != null; 14 | public ConsentViewModel ViewModel { get; set; } 15 | 16 | public bool HasValidationError => ValidationError != null; 17 | public string ValidationError { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Consent/ScopeViewModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | namespace IdentityServer.Quickstart.Consent 6 | { 7 | public class ScopeViewModel 8 | { 9 | public string Name { get; set; } 10 | public string DisplayName { get; set; } 11 | public string Description { get; set; } 12 | public bool Emphasize { get; set; } 13 | public bool Required { get; set; } 14 | public bool Checked { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Diagnostics/DiagnosticsController.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using Microsoft.AspNetCore.Authentication; 8 | using Microsoft.AspNetCore.Authorization; 9 | using Microsoft.AspNetCore.Mvc; 10 | 11 | namespace IdentityServer.Quickstart.Diagnostics 12 | { 13 | [SecurityHeaders] 14 | [Authorize] 15 | public class DiagnosticsController : Controller 16 | { 17 | public async Task Index() 18 | { 19 | var localAddresses = new string[] { "127.0.0.1", "::1", HttpContext.Connection.LocalIpAddress.ToString() }; 20 | if (!localAddresses.Contains(HttpContext.Connection.RemoteIpAddress.ToString())) 21 | { 22 | return NotFound(); 23 | } 24 | 25 | var model = new DiagnosticsViewModel(await HttpContext.AuthenticateAsync()); 26 | return View(model); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Diagnostics/DiagnosticsViewModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | using System.Collections.Generic; 6 | using System.Text; 7 | using IdentityModel; 8 | using Microsoft.AspNetCore.Authentication; 9 | using Newtonsoft.Json; 10 | 11 | namespace IdentityServer.Quickstart.Diagnostics 12 | { 13 | public class DiagnosticsViewModel 14 | { 15 | public DiagnosticsViewModel(AuthenticateResult result) 16 | { 17 | AuthenticateResult = result; 18 | 19 | if (result.Properties.Items.ContainsKey("client_list")) 20 | { 21 | var encoded = result.Properties.Items["client_list"]; 22 | var bytes = Base64Url.Decode(encoded); 23 | var value = Encoding.UTF8.GetString(bytes); 24 | 25 | Clients = JsonConvert.DeserializeObject(value); 26 | } 27 | } 28 | 29 | public AuthenticateResult AuthenticateResult { get; } 30 | public IEnumerable Clients { get; } = new List(); 31 | } 32 | } -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using IdentityServer4.Stores; 3 | 4 | namespace IdentityServer.Quickstart 5 | { 6 | public static class Extensions 7 | { 8 | /// 9 | /// Determines whether the client is configured to use PKCE. 10 | /// 11 | /// The store. 12 | /// The client identifier. 13 | /// 14 | public static async Task IsPkceClientAsync(this IClientStore store, string client_id) 15 | { 16 | if (!string.IsNullOrWhiteSpace(client_id)) 17 | { 18 | var client = await store.FindEnabledClientByIdAsync(client_id); 19 | return client?.RequirePkce == true; 20 | } 21 | 22 | return false; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Grants/GrantsController.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | using IdentityServer4.Events; 9 | using IdentityServer4.Extensions; 10 | using IdentityServer4.Services; 11 | using IdentityServer4.Stores; 12 | using Microsoft.AspNetCore.Authorization; 13 | using Microsoft.AspNetCore.Mvc; 14 | 15 | namespace IdentityServer.Quickstart.Grants 16 | { 17 | /// 18 | /// This sample controller allows a user to revoke grants given to clients 19 | /// 20 | [SecurityHeaders] 21 | [Authorize] 22 | public class GrantsController : Controller 23 | { 24 | private readonly IIdentityServerInteractionService _interaction; 25 | private readonly IClientStore _clients; 26 | private readonly IResourceStore _resources; 27 | private readonly IEventService _events; 28 | 29 | public GrantsController(IIdentityServerInteractionService interaction, 30 | IClientStore clients, 31 | IResourceStore resources, 32 | IEventService events) 33 | { 34 | _interaction = interaction; 35 | _clients = clients; 36 | _resources = resources; 37 | _events = events; 38 | } 39 | 40 | /// 41 | /// Show list of grants 42 | /// 43 | [HttpGet] 44 | public async Task Index() 45 | { 46 | return View("Index", await BuildViewModelAsync()); 47 | } 48 | 49 | /// 50 | /// Handle postback to revoke a client 51 | /// 52 | [HttpPost] 53 | [ValidateAntiForgeryToken] 54 | public async Task Revoke(string clientId) 55 | { 56 | await _interaction.RevokeUserConsentAsync(clientId); 57 | await _events.RaiseAsync(new GrantsRevokedEvent(User.GetSubjectId(), clientId)); 58 | 59 | return RedirectToAction("Index"); 60 | } 61 | 62 | private async Task BuildViewModelAsync() 63 | { 64 | var grants = await _interaction.GetAllUserConsentsAsync(); 65 | 66 | var list = new List(); 67 | foreach(var grant in grants) 68 | { 69 | var client = await _clients.FindClientByIdAsync(grant.ClientId); 70 | if (client != null) 71 | { 72 | var resources = await _resources.FindResourcesByScopeAsync(grant.Scopes); 73 | 74 | var item = new GrantViewModel() 75 | { 76 | ClientId = client.ClientId, 77 | ClientName = client.ClientName ?? client.ClientId, 78 | ClientLogoUrl = client.LogoUri, 79 | ClientUrl = client.ClientUri, 80 | Created = grant.CreationTime, 81 | Expires = grant.Expiration, 82 | IdentityGrantNames = resources.IdentityResources.Select(x => x.DisplayName ?? x.Name).ToArray(), 83 | ApiGrantNames = resources.ApiResources.Select(x => x.DisplayName ?? x.Name).ToArray() 84 | }; 85 | 86 | list.Add(item); 87 | } 88 | } 89 | 90 | return new GrantsViewModel 91 | { 92 | Grants = list 93 | }; 94 | } 95 | } 96 | } -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Grants/GrantsViewModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | 8 | namespace IdentityServer.Quickstart.Grants 9 | { 10 | public class GrantsViewModel 11 | { 12 | public IEnumerable Grants { get; set; } 13 | } 14 | 15 | public class GrantViewModel 16 | { 17 | public string ClientId { get; set; } 18 | public string ClientName { get; set; } 19 | public string ClientUrl { get; set; } 20 | public string ClientLogoUrl { get; set; } 21 | public DateTime Created { get; set; } 22 | public DateTime? Expires { get; set; } 23 | public IEnumerable IdentityGrantNames { get; set; } 24 | public IEnumerable ApiGrantNames { get; set; } 25 | } 26 | } -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Home/ErrorViewModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | using IdentityServer4.Models; 6 | 7 | namespace IdentityServer.Quickstart.Home 8 | { 9 | public class ErrorViewModel 10 | { 11 | public ErrorMessage Error { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /IdentityServer/Quickstart/Home/HomeController.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | using System.Threading.Tasks; 6 | using IdentityServer4.Services; 7 | using Microsoft.AspNetCore.Authorization; 8 | using Microsoft.AspNetCore.Hosting; 9 | using Microsoft.AspNetCore.Mvc; 10 | 11 | namespace IdentityServer.Quickstart.Home 12 | { 13 | [SecurityHeaders] 14 | [AllowAnonymous] 15 | public class HomeController : Controller 16 | { 17 | private readonly IIdentityServerInteractionService _interaction; 18 | private readonly IHostingEnvironment _environment; 19 | 20 | public HomeController(IIdentityServerInteractionService interaction, IHostingEnvironment environment) 21 | { 22 | _interaction = interaction; 23 | _environment = environment; 24 | } 25 | 26 | public IActionResult Index() 27 | { 28 | if (_environment.IsDevelopment()) 29 | { 30 | // only show in development 31 | return View(); 32 | } 33 | 34 | return NotFound(); 35 | } 36 | 37 | /// 38 | /// Shows the error page 39 | /// 40 | public async Task Error(string errorId) 41 | { 42 | var vm = new ErrorViewModel(); 43 | 44 | // retrieve error details from identityserver 45 | var message = await _interaction.GetErrorContextAsync(errorId); 46 | if (message != null) 47 | { 48 | vm.Error = message; 49 | 50 | if (!_environment.IsDevelopment()) 51 | { 52 | // only show in development 53 | message.ErrorDescription = null; 54 | } 55 | } 56 | 57 | return View("Error", vm); 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /IdentityServer/Quickstart/SecurityHeadersAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.AspNetCore.Mvc.Filters; 7 | 8 | namespace IdentityServer.Quickstart 9 | { 10 | public class SecurityHeadersAttribute : ActionFilterAttribute 11 | { 12 | public override void OnResultExecuting(ResultExecutingContext context) 13 | { 14 | var result = context.Result; 15 | if (result is ViewResult) 16 | { 17 | // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options 18 | if (!context.HttpContext.Response.Headers.ContainsKey("X-Content-Type-Options")) 19 | { 20 | context.HttpContext.Response.Headers.Add("X-Content-Type-Options", "nosniff"); 21 | } 22 | 23 | // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options 24 | if (!context.HttpContext.Response.Headers.ContainsKey("X-Frame-Options")) 25 | { 26 | context.HttpContext.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN"); 27 | } 28 | 29 | // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy 30 | var csp = "default-src 'self'; object-src 'none'; frame-ancestors 'none'; sandbox allow-forms allow-same-origin allow-scripts; base-uri 'self';"; 31 | // also consider adding upgrade-insecure-requests once you have HTTPS in place for production 32 | //csp += "upgrade-insecure-requests;"; 33 | // also an example if you need client images to be displayed from twitter 34 | // csp += "img-src 'self' https://pbs.twimg.com;"; 35 | 36 | // once for standards compliant browsers 37 | if (!context.HttpContext.Response.Headers.ContainsKey("Content-Security-Policy")) 38 | { 39 | context.HttpContext.Response.Headers.Add("Content-Security-Policy", csp); 40 | } 41 | // and once again for IE 42 | if (!context.HttpContext.Response.Headers.ContainsKey("X-Content-Security-Policy")) 43 | { 44 | context.HttpContext.Response.Headers.Add("X-Content-Security-Policy", csp); 45 | } 46 | 47 | // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy 48 | var referrer_policy = "no-referrer"; 49 | if (!context.HttpContext.Response.Headers.ContainsKey("Referrer-Policy")) 50 | { 51 | context.HttpContext.Response.Headers.Add("Referrer-Policy", referrer_policy); 52 | } 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /IdentityServer/Quickstart/TestUsers.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | using System.Collections.Generic; 6 | using System.Security.Claims; 7 | using IdentityModel; 8 | using IdentityServer4.Test; 9 | 10 | namespace IdentityServer.Quickstart 11 | { 12 | public class TestUsers 13 | { 14 | public static List Users = new List 15 | { 16 | new TestUser{SubjectId = "818727", Username = "alice", Password = "alice", 17 | Claims = 18 | { 19 | new Claim(JwtClaimTypes.Name, "Alice Smith"), 20 | new Claim(JwtClaimTypes.GivenName, "Alice"), 21 | new Claim(JwtClaimTypes.FamilyName, "Smith"), 22 | new Claim(JwtClaimTypes.Email, "AliceSmith@email.com"), 23 | new Claim(JwtClaimTypes.EmailVerified, "true", ClaimValueTypes.Boolean), 24 | new Claim(JwtClaimTypes.WebSite, "http://alice.com"), 25 | new Claim(JwtClaimTypes.Address, @"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }", IdentityServer4.IdentityServerConstants.ClaimValueTypes.Json) 26 | } 27 | }, 28 | new TestUser{SubjectId = "88421113", Username = "bob", Password = "bob", 29 | Claims = 30 | { 31 | new Claim(JwtClaimTypes.Name, "Bob Smith"), 32 | new Claim(JwtClaimTypes.GivenName, "Bob"), 33 | new Claim(JwtClaimTypes.FamilyName, "Smith"), 34 | new Claim(JwtClaimTypes.Email, "BobSmith@email.com"), 35 | new Claim(JwtClaimTypes.EmailVerified, "true", ClaimValueTypes.Boolean), 36 | new Claim(JwtClaimTypes.WebSite, "http://bob.com"), 37 | new Claim(JwtClaimTypes.Address, @"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }", IdentityServer4.IdentityServerConstants.ClaimValueTypes.Json), 38 | new Claim("location", "somewhere") 39 | } 40 | } 41 | }; 42 | } 43 | } -------------------------------------------------------------------------------- /IdentityServer/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Microsoft.Extensions.Hosting; 5 | 6 | namespace IdentityServer 7 | { 8 | public class Startup 9 | { 10 | public void ConfigureServices(IServiceCollection services) 11 | { 12 | services.AddControllersWithViews(); 13 | 14 | // configure identity server with in-memory stores, keys, clients and scopes 15 | services.AddIdentityServer() 16 | .AddDeveloperSigningCredential() 17 | .AddInMemoryIdentityResources(Config.GetIdentityResources()) 18 | .AddInMemoryClients(Config.GetClients()) 19 | .AddTestUsers(Config.GetUsers()); 20 | } 21 | 22 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 23 | { 24 | if (env.IsDevelopment()) 25 | { 26 | app.UseDeveloperExceptionPage(); 27 | } 28 | else 29 | { 30 | app.UseExceptionHandler("/Home/Error"); 31 | } 32 | app.UseStaticFiles(); 33 | 34 | app.UseIdentityServer(); 35 | 36 | app.UseRouting(); 37 | 38 | app.UseAuthorization(); 39 | 40 | app.UseEndpoints(endpoints => 41 | { 42 | endpoints.MapControllerRoute( 43 | name: "default", 44 | pattern: "{controller=Home}/{action=Index}/{id?}"); 45 | }); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /IdentityServer/Views/Account/LoggedOut.cshtml: -------------------------------------------------------------------------------- 1 | @model IdentityServer.Quickstart.Account.LoggedOutViewModel 2 | 3 | @{ 4 | // set this so the layout rendering sees an anonymous user 5 | ViewData["signed-out"] = true; 6 | } 7 | 8 | 27 | 28 | @section scripts 29 | { 30 | @if (Model.AutomaticRedirectAfterSignOut) 31 | { 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /IdentityServer/Views/Account/Login.cshtml: -------------------------------------------------------------------------------- 1 | @model IdentityServer.Quickstart.Account.LoginViewModel 2 | 3 | -------------------------------------------------------------------------------- /IdentityServer/Views/Account/Logout.cshtml: -------------------------------------------------------------------------------- 1 | @model IdentityServer.Quickstart.Account.LogoutViewModel 2 | 3 |
4 | 7 | 8 |
9 |
10 |

Would you like to logout of IdentityServer?

11 |
12 | 13 |
14 |
15 | 16 |
17 |
18 |
19 |
20 |
21 |
-------------------------------------------------------------------------------- /IdentityServer/Views/Consent/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model IdentityServer.Quickstart.Consent.ConsentViewModel 2 | 3 | -------------------------------------------------------------------------------- /IdentityServer/Views/Consent/_ScopeListItem.cshtml: -------------------------------------------------------------------------------- 1 | @model IdentityServer.Quickstart.Consent.ScopeViewModel 2 | 3 |
  • 4 | 24 | @if (Model.Required) 25 | { 26 | (required) 27 | } 28 | @if (Model.Description != null) 29 | { 30 | 33 | } 34 |
  • -------------------------------------------------------------------------------- /IdentityServer/Views/Diagnostics/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model IdentityServer.Quickstart.Diagnostics.DiagnosticsViewModel 2 | 3 |

    Authentication cookie

    4 | 5 |

    Claims

    6 |
    7 | @foreach (var claim in Model.AuthenticateResult.Principal.Claims) 8 | { 9 |
    @claim.Type
    10 |
    @claim.Value
    11 | } 12 |
    13 | 14 |

    Properties

    15 |
    16 | @foreach (var prop in Model.AuthenticateResult.Properties.Items) 17 | { 18 |
    @prop.Key
    19 |
    @prop.Value
    20 | } 21 |
    22 | 23 | @if (Model.Clients.Any()) 24 | { 25 |

    Clients

    26 |
      27 | @foreach (var client in Model.Clients) 28 | { 29 |
    • @client
    • 30 | } 31 |
    32 | } -------------------------------------------------------------------------------- /IdentityServer/Views/Grants/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model IdentityServer.Quickstart.Grants.GrantsViewModel 2 | 3 |
    4 | 12 | 13 | @if (Model.Grants.Any() == false) 14 | { 15 |
    16 |
    17 |
    18 | You have not given access to any applications 19 |
    20 |
    21 |
    22 | } 23 | else 24 | { 25 | foreach (var grant in Model.Grants) 26 | { 27 |
    28 |
    29 | @if (grant.ClientLogoUrl != null) 30 | { 31 | 32 | } 33 |
    34 |
    35 |
    @grant.ClientName
    36 |
    37 | Created: @grant.Created.ToString("yyyy-MM-dd") 38 |
    39 | @if (grant.Expires.HasValue) 40 | { 41 |
    42 | Expires: @grant.Expires.Value.ToString("yyyy-MM-dd") 43 |
    44 | } 45 | @if (grant.IdentityGrantNames.Any()) 46 | { 47 |
    48 |
    Identity Grants
    49 |
      50 | @foreach (var name in grant.IdentityGrantNames) 51 | { 52 |
    • @name
    • 53 | } 54 |
    55 |
    56 | } 57 | @if (grant.ApiGrantNames.Any()) 58 | { 59 |
    60 |
    API Grants
    61 |
      62 | @foreach (var name in grant.ApiGrantNames) 63 | { 64 |
    • @name
    • 65 | } 66 |
    67 |
    68 | } 69 |
    70 |
    71 |
    72 | 73 | 74 |
    75 |
    76 |
    77 | } 78 | } 79 |
    -------------------------------------------------------------------------------- /IdentityServer/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 |
    2 | 11 | 12 |
    13 |
    14 |

    15 | IdentityServer publishes a 16 | discovery document 17 | where you can find metadata and links to all the endpoints, key material, etc. 18 |

    19 |
    20 |
    21 |

    22 | Click here to manage your stored grants. 23 |

    24 |
    25 |
    26 |
    27 |
    28 |

    29 | Here are links to the 30 | source code repository, 31 | and ready to use samples. 32 |

    33 |
    34 |
    35 |
    36 | -------------------------------------------------------------------------------- /IdentityServer/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model IdentityServer.Quickstart.Home.ErrorViewModel 2 | 3 | @{ 4 | var error = Model?.Error?.Error; 5 | var errorDescription = Model?.Error?.ErrorDescription; 6 | var request_id = Model?.Error?.RequestId; 7 | } 8 | 9 |
    10 | 13 | 14 |
    15 |
    16 |
    17 | Sorry, there was an error 18 | 19 | @if (error != null) 20 | { 21 | 22 | 23 | : @error 24 | 25 | 26 | 27 | if (errorDescription != null) 28 | { 29 |
    @errorDescription
    30 | } 31 | } 32 |
    33 | 34 | @if (request_id != null) 35 | { 36 |
    Request Id: @request_id
    37 | } 38 |
    39 |
    40 |
    41 | -------------------------------------------------------------------------------- /IdentityServer/Views/Shared/Redirect.cshtml: -------------------------------------------------------------------------------- 1 | @model IdentityServer.Quickstart.Account.RedirectViewModel 2 | 3 |

    You are now being returned to the application.

    4 |

    Once complete, you may close this tab

    5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /IdentityServer/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | @using IdentityServer4.Extensions 2 | @{ 3 | string name = null; 4 | if (!true.Equals(ViewData["signed-out"])) 5 | { 6 | name = Context.User?.GetDisplayName(); 7 | } 8 | } 9 | 10 | 11 | 12 | 13 | 14 | 15 | IdentityServer4 16 | 17 | 18 | 19 | 20 | 21 | 22 | 52 | 53 |
    54 | @RenderBody() 55 |
    56 | 57 | 58 | 59 | @RenderSection("scripts", required: false) 60 | 61 | 62 | -------------------------------------------------------------------------------- /IdentityServer/Views/Shared/_ValidationSummary.cshtml: -------------------------------------------------------------------------------- 1 | @if (ViewContext.ModelState.IsValid == false) 2 | { 3 |
    4 | Error 5 |
    6 |
    7 | } -------------------------------------------------------------------------------- /IdentityServer/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 2 | -------------------------------------------------------------------------------- /IdentityServer/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /IdentityServer/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /IdentityServer/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Warning" 5 | } 6 | }, 7 | "AllowedHosts": "*" 8 | } 9 | -------------------------------------------------------------------------------- /IdentityServer/tempkey.rsa: -------------------------------------------------------------------------------- 1 | {"KeyId":"be1f715496050c65aeab235008896408","Parameters":{"D":"SFVnb5Bxbp5DMApG5zEv3ZioVD8/YY+WveBP+4f3Dv13PehKANFoMTS595rFbBDO/OzMelepbgzxjuNh4HfblFOOiYRNxiTZ3H7syq7UX4OqtWPrqDGzawUwpvQnX7MakJAkAMpPyXpyWAt9g+YaptBaTarVwlmcH5GFRNC/toyH86siL8OzHIRwvOS1R5CR9j7agsBbHfGpmjDFbE63PbXmXgpLqg+35Uo2EmZoKvXPoMXmDU6rjDKzpi6KxRJ4EDQvTteXBf0suyXLyt8pNNXjh6dm6xll4sWAs18zKxCqmY5hUX/kUnVF2RdXH6i7OsXaUWadPPfR0IdPmz43jQ==","DP":"xWJBtdXkhW4gWO6zuzGHSuuRhUm+xNexC2opagxr0TDo+nG2lVu4RdbESn3X/AZTxgyLpeBw++WD0Zhv2kYrhS5916Sees/9YvtboNxipucEu/oLcaMAmTBIrPExDAO5r+fRAntS56z5BadHJO+XhaZdleC8ttmgtMnQhHchNMU=","DQ":"2iBED9u8sq9FBeuYjQfOTjKQMGBWGQ/QLHI1zDILBTqueuhBnAY6i9LwSmqGHcA56CqzJ6NrFcYrODFRmJL21jgANow1EygKu2p5Vwfv8fZZXU2QJdDqbOGwUfehBxOWmwP3KhMU+Y9JJYWyuCdDaYb3YrtdPWPnBFurpXej9xc=","Exponent":"AQAB","InverseQ":"eBrYmXpyDcFkk3LxwKwqb0yZnRjKA+TzN10Ux5oPot8ljhVUZl4MxjQ5FaOF1LTPeVLOxAl5MYTSx7TaSIYEMmKx1HjvIF1SOqcbo4ukyE/9kiEf+szZuSxP3jnjuRcXFyN/Y3q335SF/8XkwV+L392BjrO5eZzKiwvZnkj3XYY=","Modulus":"wTL8GP8qUVrnFAQJfRsQe3OME1FivO9XX2bmwqmbzy2Qdll+ySAiakhLKhW7kRjk7EoXLHUZoaVUyf88ZXiDwK6j6smgBN5PqUmJTrxPUSO8cgqsdl5f+OlonYzSFPR0A5NVXSlaVs6OGwqLHDfIIRVzsbiRc5VF54pyehGjPcjSkWfb337nYITgLyEpGQa3vb05n95A8exTw+Efnhc2jxaXV3DlfQMW3pIjKvtD8JJ1XXk4H8xbBUkP+ETuZ/LxByz9Y5UrppfpDF24m7Qu3aQUDEql8IzfL99EBXjMqpYfC80XttUU3ZeaFILhHtnDfHo3HQwnX7I6EvQFlBiwZQ==","P":"0K2K7oNiOejIK7zjCsihigSgiH3j1GJPpmHcWnKuYQjOIqapj8Op4KB47DpBZ9ai2ASAB9jHmRTrfP2RyAJ3/WX5iJARtK87cEohb1hQ0tHabp8OnAvvkIjqW3BxgW+qcpjaKBvn7ZCEfddmbPghdKe+xK6uMGBvVIMl6WrXmlc=","Q":"7QLZSZnbZfIaRxzvm0pwfj+mgcUfuWYHCc1KBP/MFGFZEzwDdvCOnriFVJB2z1kcAHpara6/o5RiNUTwzOd8doyXwYqbc7yBXdPEq37Y+POKNVjr99acG4m9VhSDWYVaWk5RcP/QPrL67ENRI6YEaLXms8Ll0dFFZH0bgz79DaM="}} -------------------------------------------------------------------------------- /IdentityServer/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin-top: 65px; 3 | } 4 | .navbar-header { 5 | position: relative; 6 | top: -4px; 7 | } 8 | .navbar-brand > .icon-banner { 9 | position: relative; 10 | top: -2px; 11 | display: inline; 12 | } 13 | .icon { 14 | position: relative; 15 | top: -10px; 16 | } 17 | .logged-out iframe { 18 | display: none; 19 | width: 0; 20 | height: 0; 21 | } 22 | .page-consent .client-logo { 23 | float: left; 24 | } 25 | .page-consent .client-logo img { 26 | width: 80px; 27 | height: 80px; 28 | } 29 | .page-consent .consent-buttons { 30 | margin-top: 25px; 31 | } 32 | .page-consent .consent-form .consent-scopecheck { 33 | display: inline-block; 34 | margin-right: 5px; 35 | } 36 | .page-consent .consent-form .consent-description { 37 | margin-left: 25px; 38 | } 39 | .page-consent .consent-form .consent-description label { 40 | font-weight: normal; 41 | } 42 | .page-consent .consent-form .consent-remember { 43 | padding-left: 16px; 44 | } 45 | .grants .page-header { 46 | margin-bottom: 10px; 47 | } 48 | .grants .grant { 49 | margin-top: 20px; 50 | padding-bottom: 20px; 51 | border-bottom: 1px solid lightgray; 52 | } 53 | .grants .grant img { 54 | width: 100px; 55 | height: 100px; 56 | } 57 | .grants .grant .clientname { 58 | font-size: 140%; 59 | font-weight: bold; 60 | } 61 | .grants .grant .granttype { 62 | font-size: 120%; 63 | font-weight: bold; 64 | } 65 | .grants .grant .created { 66 | font-size: 120%; 67 | font-weight: bold; 68 | } 69 | .grants .grant .expires { 70 | font-size: 120%; 71 | font-weight: bold; 72 | } 73 | .grants .grant li { 74 | list-style-type: none; 75 | display: inline; 76 | } 77 | .grants .grant li:after { 78 | content: ', '; 79 | } 80 | .grants .grant li:last-child:after { 81 | content: ''; 82 | } -------------------------------------------------------------------------------- /IdentityServer/wwwroot/css/site.less: -------------------------------------------------------------------------------- 1 | body { 2 | margin-top: 65px; 3 | } 4 | 5 | .navbar-header { 6 | position: relative; 7 | top: -4px; 8 | } 9 | 10 | .navbar-brand > .icon-banner { 11 | position: relative; 12 | top: -2px; 13 | display: inline; 14 | } 15 | 16 | .icon { 17 | position: relative; 18 | top: -10px; 19 | } 20 | 21 | .logged-out iframe { 22 | display: none; 23 | width: 0; 24 | height: 0; 25 | } 26 | 27 | .page-consent { 28 | .client-logo { 29 | float: left; 30 | 31 | img { 32 | width: 80px; 33 | height: 80px; 34 | } 35 | } 36 | 37 | .consent-buttons { 38 | margin-top: 25px; 39 | } 40 | 41 | .consent-form { 42 | .consent-scopecheck { 43 | display: inline-block; 44 | margin-right: 5px; 45 | } 46 | 47 | .consent-scopecheck[disabled] { 48 | //visibility:hidden; 49 | } 50 | 51 | .consent-description { 52 | margin-left: 25px; 53 | 54 | label { 55 | font-weight: normal; 56 | } 57 | } 58 | 59 | .consent-remember { 60 | padding-left: 16px; 61 | } 62 | } 63 | } 64 | 65 | .grants { 66 | .page-header { 67 | margin-bottom: 10px; 68 | } 69 | 70 | .grant { 71 | margin-top: 20px; 72 | padding-bottom: 20px; 73 | border-bottom: 1px solid lightgray; 74 | 75 | img { 76 | width: 100px; 77 | height: 100px; 78 | } 79 | 80 | .clientname { 81 | font-size: 140%; 82 | font-weight: bold; 83 | } 84 | 85 | .granttype { 86 | font-size: 120%; 87 | font-weight: bold; 88 | } 89 | 90 | .created { 91 | font-size: 120%; 92 | font-weight: bold; 93 | } 94 | 95 | .expires { 96 | font-size: 120%; 97 | font-weight: bold; 98 | } 99 | 100 | li { 101 | list-style-type: none; 102 | display: inline; 103 | 104 | &:after { 105 | content: ', '; 106 | } 107 | 108 | &:last-child:after { 109 | content: ''; 110 | } 111 | 112 | .displayname { 113 | } 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /IdentityServer/wwwroot/css/site.min.css: -------------------------------------------------------------------------------- 1 | body{margin-top:65px;}.navbar-header{position:relative;top:-4px;}.navbar-brand>.icon-banner{position:relative;top:-2px;display:inline;}.icon{position:relative;top:-10px;}.logged-out iframe{display:none;width:0;height:0;}.page-consent .client-logo{float:left;}.page-consent .client-logo img{width:80px;height:80px;}.page-consent .consent-buttons{margin-top:25px;}.page-consent .consent-form .consent-scopecheck{display:inline-block;margin-right:5px;}.page-consent .consent-form .consent-description{margin-left:25px;}.page-consent .consent-form .consent-description label{font-weight:normal;}.page-consent .consent-form .consent-remember{padding-left:16px;}.grants .page-header{margin-bottom:10px;}.grants .grant{margin-top:20px;padding-bottom:20px;border-bottom:1px solid #d3d3d3;}.grants .grant img{width:100px;height:100px;}.grants .grant .clientname{font-size:140%;font-weight:bold;}.grants .grant .granttype{font-size:120%;font-weight:bold;}.grants .grant .created{font-size:120%;font-weight:bold;}.grants .grant .expires{font-size:120%;font-weight:bold;}.grants .grant li{list-style-type:none;display:inline;}.grants .grant li:after{content:', ';}.grants .grant li:last-child:after{content:'';} -------------------------------------------------------------------------------- /IdentityServer/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobritodev/AspNetCore-IdentityServer4-Example/aa0f6294485127c895b441491e5401de290808ba/IdentityServer/wwwroot/favicon.ico -------------------------------------------------------------------------------- /IdentityServer/wwwroot/icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobritodev/AspNetCore-IdentityServer4-Example/aa0f6294485127c895b441491e5401de290808ba/IdentityServer/wwwroot/icon.jpg -------------------------------------------------------------------------------- /IdentityServer/wwwroot/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobritodev/AspNetCore-IdentityServer4-Example/aa0f6294485127c895b441491e5401de290808ba/IdentityServer/wwwroot/icon.png -------------------------------------------------------------------------------- /IdentityServer/wwwroot/images/banner1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /IdentityServer/wwwroot/images/banner2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /IdentityServer/wwwroot/images/banner3.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /IdentityServer/wwwroot/js/signin-redirect.js: -------------------------------------------------------------------------------- 1 | window.location.href = document.querySelector("meta[http-equiv=refresh]").getAttribute("data-url"); 2 | -------------------------------------------------------------------------------- /IdentityServer/wwwroot/js/signout-redirect.js: -------------------------------------------------------------------------------- 1 | window.addEventListener("load", function () { 2 | var a = document.querySelector("a.PostLogoutRedirectUri"); 3 | if (a) { 4 | window.location = a.href; 5 | } 6 | }); 7 | -------------------------------------------------------------------------------- /IdentityServer/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | // for details on configuring this project to bundle and minify static web assets. 3 | 4 | // Write your JavaScript code. 5 | -------------------------------------------------------------------------------- /IdentityServer/wwwroot/js/site.min.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobritodev/AspNetCore-IdentityServer4-Example/aa0f6294485127c895b441491e5401de290808ba/IdentityServer/wwwroot/js/site.min.js -------------------------------------------------------------------------------- /IdentityServer/wwwroot/lib/bootstrap/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bootstrap", 3 | "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", 4 | "keywords": [ 5 | "css", 6 | "js", 7 | "less", 8 | "mobile-first", 9 | "responsive", 10 | "front-end", 11 | "framework", 12 | "web" 13 | ], 14 | "homepage": "http://getbootstrap.com", 15 | "license": "MIT", 16 | "moduleType": "globals", 17 | "main": [ 18 | "less/bootstrap.less", 19 | "dist/js/bootstrap.js" 20 | ], 21 | "ignore": [ 22 | "/.*", 23 | "_config.yml", 24 | "CNAME", 25 | "composer.json", 26 | "CONTRIBUTING.md", 27 | "docs", 28 | "js/tests", 29 | "test-infra" 30 | ], 31 | "dependencies": { 32 | "jquery": "1.9.1 - 3" 33 | }, 34 | "version": "3.3.7", 35 | "_release": "3.3.7", 36 | "_resolution": { 37 | "type": "version", 38 | "tag": "v3.3.7", 39 | "commit": "0b9c4a4007c44201dce9a6cc1a38407005c26c86" 40 | }, 41 | "_source": "https://github.com/twbs/bootstrap.git", 42 | "_target": "v3.3.7", 43 | "_originalSource": "bootstrap", 44 | "_direct": true 45 | } -------------------------------------------------------------------------------- /IdentityServer/wwwroot/lib/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2016 Twitter, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /IdentityServer/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobritodev/AspNetCore-IdentityServer4-Example/aa0f6294485127c895b441491e5401de290808ba/IdentityServer/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /IdentityServer/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobritodev/AspNetCore-IdentityServer4-Example/aa0f6294485127c895b441491e5401de290808ba/IdentityServer/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /IdentityServer/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobritodev/AspNetCore-IdentityServer4-Example/aa0f6294485127c895b441491e5401de290808ba/IdentityServer/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /IdentityServer/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobritodev/AspNetCore-IdentityServer4-Example/aa0f6294485127c895b441491e5401de290808ba/IdentityServer/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /IdentityServer/wwwroot/lib/bootstrap/dist/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /IdentityServer/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobritodev/AspNetCore-IdentityServer4-Example/aa0f6294485127c895b441491e5401de290808ba/IdentityServer/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /IdentityServer/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobritodev/AspNetCore-IdentityServer4-Example/aa0f6294485127c895b441491e5401de290808ba/IdentityServer/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /IdentityServer/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobritodev/AspNetCore-IdentityServer4-Example/aa0f6294485127c895b441491e5401de290808ba/IdentityServer/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /IdentityServer/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobritodev/AspNetCore-IdentityServer4-Example/aa0f6294485127c895b441491e5401de290808ba/IdentityServer/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /IdentityServer/wwwroot/lib/jquery-validation-unobtrusive/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-validation-unobtrusive", 3 | "homepage": "https://github.com/aspnet/jquery-validation-unobtrusive", 4 | "version": "3.2.9", 5 | "_release": "3.2.9", 6 | "_resolution": { 7 | "type": "version", 8 | "tag": "v3.2.9", 9 | "commit": "a91f5401898e125f10771c5f5f0909d8c4c82396" 10 | }, 11 | "_source": "https://github.com/aspnet/jquery-validation-unobtrusive.git", 12 | "_target": "^3.2.9", 13 | "_originalSource": "jquery-validation-unobtrusive", 14 | "_direct": true 15 | } -------------------------------------------------------------------------------- /IdentityServer/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) .NET Foundation. All rights reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | these files except in compliance with the License. You may obtain a copy of the 5 | License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | -------------------------------------------------------------------------------- /IdentityServer/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js: -------------------------------------------------------------------------------- 1 | // Unobtrusive validation support library for jQuery and jQuery Validate 2 | // Copyright (C) Microsoft Corporation. All rights reserved. 3 | // @version v3.2.9 4 | !function(a){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery.validation"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery-validation")):jQuery.validator.unobtrusive=a(jQuery)}(function(a){function e(a,e,n){a.rules[e]=n,a.message&&(a.messages[e]=a.message)}function n(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function t(a){return a.replace(/([!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function r(a){return a.substr(0,a.lastIndexOf(".")+1)}function i(a,e){return 0===a.indexOf("*.")&&(a=a.replace("*.",e)),a}function o(e,n){var r=a(this).find("[data-valmsg-for='"+t(n[0].name)+"']"),i=r.attr("data-valmsg-replace"),o=i?a.parseJSON(i)!==!1:null;r.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",r),o?(r.empty(),e.removeClass("input-validation-error").appendTo(r)):e.hide()}function d(e,n){var t=a(this).find("[data-valmsg-summary=true]"),r=t.find("ul");r&&r.length&&n.errorList.length&&(r.empty(),t.addClass("validation-summary-errors").removeClass("validation-summary-valid"),a.each(n.errorList,function(){a("
  • ").html(this.message).appendTo(r)}))}function s(e){var n=e.data("unobtrusiveContainer");if(n){var t=n.attr("data-valmsg-replace"),r=t?a.parseJSON(t):null;n.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),r&&n.empty()}}function l(e){var n=a(this),t="__jquery_unobtrusive_validation_form_reset";if(!n.data(t)){n.data(t,!0);try{n.data("validator").resetForm()}finally{n.removeData(t)}n.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),n.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function u(e){var n=a(e),t=n.data(v),r=a.proxy(l,e),i=f.unobtrusive.options||{},u=function(n,t){var r=i[n];r&&a.isFunction(r)&&r.apply(e,t)};return t||(t={options:{errorClass:i.errorClass||"input-validation-error",errorElement:i.errorElement||"span",errorPlacement:function(){o.apply(e,arguments),u("errorPlacement",arguments)},invalidHandler:function(){d.apply(e,arguments),u("invalidHandler",arguments)},messages:{},rules:{},success:function(){s.apply(e,arguments),u("success",arguments)}},attachValidation:function(){n.off("reset."+v,r).on("reset."+v,r).validate(this.options)},validate:function(){return n.validate(),n.valid()}},n.data(v,t)),t}var m,f=a.validator,v="unobtrusiveValidation";return f.unobtrusive={adapters:[],parseElement:function(e,n){var t,r,i,o=a(e),d=o.parents("form")[0];d&&(t=u(d),t.options.rules[e.name]=r={},t.options.messages[e.name]=i={},a.each(this.adapters,function(){var n="data-val-"+this.name,t=o.attr(n),s={};void 0!==t&&(n+="-",a.each(this.params,function(){s[this]=o.attr(n+this)}),this.adapt({element:e,form:d,message:t,params:s,rules:r,messages:i}))}),a.extend(r,{__dummy__:!0}),n||t.attachValidation())},parse:function(e){var n=a(e),t=n.parents().addBack().filter("form").add(n.find("form")).has("[data-val=true]");n.find("[data-val=true]").each(function(){f.unobtrusive.parseElement(this,!0)}),t.each(function(){var a=u(this);a&&a.attachValidation()})}},m=f.unobtrusive.adapters,m.add=function(a,e,n){return n||(n=e,e=[]),this.push({name:a,params:e,adapt:n}),this},m.addBool=function(a,n){return this.add(a,function(t){e(t,n||a,!0)})},m.addMinMax=function(a,n,t,r,i,o){return this.add(a,[i||"min",o||"max"],function(a){var i=a.params.min,o=a.params.max;i&&o?e(a,r,[i,o]):i?e(a,n,i):o&&e(a,t,o)})},m.addSingleVal=function(a,n,t){return this.add(a,[n||"val"],function(r){e(r,t||a,r.params[n])})},f.addMethod("__dummy__",function(a,e,n){return!0}),f.addMethod("regex",function(a,e,n){var t;return!!this.optional(e)||(t=new RegExp(n).exec(a),t&&0===t.index&&t[0].length===a.length)}),f.addMethod("nonalphamin",function(a,e,n){var t;return n&&(t=a.match(/\W/g),t=t&&t.length>=n),t}),f.methods.extension?(m.addSingleVal("accept","mimtype"),m.addSingleVal("extension","extension")):m.addSingleVal("extension","extension","accept"),m.addSingleVal("regex","pattern"),m.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),m.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),m.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),m.add("equalto",["other"],function(n){var o=r(n.element.name),d=n.params.other,s=i(d,o),l=a(n.form).find(":input").filter("[name='"+t(s)+"']")[0];e(n,"equalTo",l)}),m.add("required",function(a){"INPUT"===a.element.tagName.toUpperCase()&&"CHECKBOX"===a.element.type.toUpperCase()||e(a,"required",!0)}),m.add("remote",["url","type","additionalfields"],function(o){var d={url:o.params.url,type:o.params.type||"GET",data:{}},s=r(o.element.name);a.each(n(o.params.additionalfields||o.element.name),function(e,n){var r=i(n,s);d.data[r]=function(){var e=a(o.form).find(":input").filter("[name='"+t(r)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),e(o,"remote",d)}),m.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&e(a,"minlength",a.params.min),a.params.nonalphamin&&e(a,"nonalphamin",a.params.nonalphamin),a.params.regex&&e(a,"regex",a.params.regex)}),m.add("fileextensions",["extensions"],function(a){e(a,"extension",a.params.extensions)}),a(function(){f.unobtrusive.parse(document)}),f.unobtrusive}); -------------------------------------------------------------------------------- /IdentityServer/wwwroot/lib/jquery-validation/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-validation", 3 | "homepage": "https://jqueryvalidation.org/", 4 | "repository": { 5 | "type": "git", 6 | "url": "git://github.com/jquery-validation/jquery-validation.git" 7 | }, 8 | "authors": [ 9 | "Jörn Zaefferer " 10 | ], 11 | "description": "Form validation made easy", 12 | "main": "dist/jquery.validate.js", 13 | "keywords": [ 14 | "forms", 15 | "validation", 16 | "validate" 17 | ], 18 | "license": "MIT", 19 | "ignore": [ 20 | "**/.*", 21 | "node_modules", 22 | "bower_components", 23 | "test", 24 | "demo", 25 | "lib" 26 | ], 27 | "dependencies": { 28 | "jquery": ">= 1.7.2" 29 | }, 30 | "version": "1.17.0", 31 | "_release": "1.17.0", 32 | "_resolution": { 33 | "type": "version", 34 | "tag": "1.17.0", 35 | "commit": "fc9b12d3bfaa2d0c04605855b896edb2934c0772" 36 | }, 37 | "_source": "https://github.com/jzaefferer/jquery-validation.git", 38 | "_target": "^1.17.0", 39 | "_originalSource": "jquery-validation", 40 | "_direct": true 41 | } -------------------------------------------------------------------------------- /IdentityServer/wwwroot/lib/jquery-validation/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright Jörn Zaefferer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /IdentityServer/wwwroot/lib/jquery/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery", 3 | "main": "dist/jquery.js", 4 | "license": "MIT", 5 | "ignore": [ 6 | "package.json" 7 | ], 8 | "keywords": [ 9 | "jquery", 10 | "javascript", 11 | "browser", 12 | "library" 13 | ], 14 | "homepage": "https://github.com/jquery/jquery-dist", 15 | "version": "3.3.1", 16 | "_release": "3.3.1", 17 | "_resolution": { 18 | "type": "version", 19 | "tag": "3.3.1", 20 | "commit": "9e8ec3d10fad04748176144f108d7355662ae75e" 21 | }, 22 | "_source": "https://github.com/jquery/jquery-dist.git", 23 | "_target": "^3.3.1", 24 | "_originalSource": "jquery", 25 | "_direct": true 26 | } -------------------------------------------------------------------------------- /IdentityServer/wwwroot/lib/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright JS Foundation and other contributors, https://js.foundation/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | All files located in the node_modules and external directories are 34 | externally maintained libraries used by this software which have their 35 | own licenses; we recommend you read them, as their terms may differ from 36 | the terms above. 37 | -------------------------------------------------------------------------------- /IdentityServerWithMvc.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27703.2026 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IdentityServer", "IdentityServer\IdentityServer.csproj", "{056581F6-725B-4CCD-BF24-344C9A3458B6}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MvcClient", "MvcClient\MvcClient.csproj", "{614A919B-6349-4930-BB98-68E78F6678A0}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {056581F6-725B-4CCD-BF24-344C9A3458B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {056581F6-725B-4CCD-BF24-344C9A3458B6}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {056581F6-725B-4CCD-BF24-344C9A3458B6}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {056581F6-725B-4CCD-BF24-344C9A3458B6}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {614A919B-6349-4930-BB98-68E78F6678A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {614A919B-6349-4930-BB98-68E78F6678A0}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {614A919B-6349-4930-BB98-68E78F6678A0}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {614A919B-6349-4930-BB98-68E78F6678A0}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {3FBDA6D5-CA56-449D-BA34-9F1CC99C9BE5} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /MvcClient/Controllers/AdminController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authentication; 2 | using Microsoft.AspNetCore.Authorization; 3 | using Microsoft.AspNetCore.Mvc; 4 | using System.Threading.Tasks; 5 | 6 | namespace MvcClient.Controllers 7 | { 8 | [Authorize] 9 | public class AdminController : Controller 10 | { 11 | public IActionResult Secure() 12 | { 13 | return View(); 14 | } 15 | 16 | public async Task Logout() 17 | { 18 | await HttpContext.SignOutAsync("Cookies"); 19 | await HttpContext.SignOutAsync("oidc"); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /MvcClient/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using MvcClient.Models; 3 | using System.Diagnostics; 4 | 5 | namespace MvcClient.Controllers 6 | { 7 | public class HomeController : Controller 8 | { 9 | public IActionResult Index() 10 | { 11 | return View(); 12 | } 13 | public IActionResult About() 14 | { 15 | ViewData["Message"] = "Your application description page."; 16 | 17 | return View(); 18 | } 19 | 20 | public IActionResult Contact() 21 | { 22 | ViewData["Message"] = "Your contact page."; 23 | 24 | return View(); 25 | } 26 | 27 | public IActionResult Privacy() 28 | { 29 | return View(); 30 | } 31 | 32 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 33 | public IActionResult Error() 34 | { 35 | return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /MvcClient/Models/ErrorViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MvcClient.Models 4 | { 5 | public class ErrorViewModel 6 | { 7 | public string RequestId { get; set; } 8 | 9 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 10 | } 11 | } -------------------------------------------------------------------------------- /MvcClient/MvcClient.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /MvcClient/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Hosting; 3 | 4 | namespace MvcClient 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | CreateHostBuilder(args).Build().Run(); 11 | } 12 | 13 | public static IHostBuilder CreateHostBuilder(string[] args) => 14 | Host.CreateDefaultBuilder(args) 15 | .ConfigureWebHostDefaults(webBuilder => 16 | { 17 | webBuilder.UseStartup(); 18 | }); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /MvcClient/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:5001", 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 | "MvcClient": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "https://localhost:5001" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /MvcClient/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authentication.Cookies; 2 | using Microsoft.AspNetCore.Authentication.OpenIdConnect; 3 | using Microsoft.AspNetCore.Builder; 4 | using Microsoft.AspNetCore.Hosting; 5 | using Microsoft.Extensions.DependencyInjection; 6 | using Microsoft.Extensions.Hosting; 7 | using Microsoft.IdentityModel.Protocols.OpenIdConnect; 8 | 9 | namespace MvcClient 10 | { 11 | public class Startup 12 | { 13 | public void ConfigureServices(IServiceCollection services) 14 | { 15 | services.AddControllersWithViews(); 16 | 17 | services.AddAuthentication(options => 18 | { 19 | options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; 20 | options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; 21 | }) 22 | .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme) 23 | .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options => 24 | { 25 | options.Authority = "http://localhost:5000"; 26 | options.RequireHttpsMetadata = false; 27 | options.ClientId = "mvc"; 28 | options.SaveTokens = true; 29 | options.ClientSecret = "super-secret"; 30 | options.ResponseType = OpenIdConnectResponseType.Code; 31 | options.Scope.Add("openid"); 32 | options.Scope.Add("profile"); 33 | }); 34 | services.AddAuthorization(); 35 | } 36 | 37 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 38 | { 39 | if (env.IsDevelopment()) 40 | { 41 | app.UseDeveloperExceptionPage(); 42 | } 43 | else 44 | { 45 | app.UseExceptionHandler("/Home/Error"); 46 | } 47 | app.UseStaticFiles(); 48 | 49 | app.UseRouting(); 50 | 51 | app.UseAuthentication(); 52 | app.UseAuthorization(); 53 | 54 | app.UseEndpoints(endpoints => 55 | { 56 | endpoints.MapDefaultControllerRoute() 57 | .RequireAuthorization(); 58 | }); 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /MvcClient/Views/Admin/Secure.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Secure"; 3 | } 4 |

    @ViewData["Title"]

    5 |

    User claims

    6 |
    7 | @foreach (var claim in User.Claims) 8 | { 9 |
    @claim.Type
    10 |
    @claim.Value
    11 | 12 | } 13 |
    14 | -------------------------------------------------------------------------------- /MvcClient/Views/Home/About.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "About"; 3 | } 4 |

    @ViewData["Title"]

    5 |

    @ViewData["Message"]

    6 | 7 |

    Use this area to provide additional information.

    8 | -------------------------------------------------------------------------------- /MvcClient/Views/Home/Contact.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Contact"; 3 | } 4 |

    @ViewData["Title"]

    5 |

    @ViewData["Message"]

    6 | 7 |
    8 | One Microsoft Way
    9 | Redmond, WA 98052-6399
    10 | P: 11 | 425.555.0100 12 |
    13 | 14 |
    15 | Support: Support@example.com
    16 | Marketing: Marketing@example.com 17 |
    18 | -------------------------------------------------------------------------------- /MvcClient/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Home Page"; 3 | } 4 |

    Página publica de um Client MVC

    5 |

    Clique aqui para ter acesso a informações secretas.

    -------------------------------------------------------------------------------- /MvcClient/Views/Home/Privacy.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Privacy Policy"; 3 | } 4 |

    @ViewData["Title"]

    5 | 6 |

    Use this page to detail your site's privacy policy.

    7 | -------------------------------------------------------------------------------- /MvcClient/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model ErrorViewModel 2 | @{ 3 | ViewData["Title"] = "Error"; 4 | } 5 | 6 |

    Error.

    7 |

    An error occurred while processing your request.

    8 | 9 | @if (Model.ShowRequestId) 10 | { 11 |

    12 | Request ID: @Model.RequestId 13 |

    14 | } 15 | 16 |

    Development Mode

    17 |

    18 | Swapping to Development environment will display more detailed information about the error that occurred. 19 |

    20 |

    21 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 22 |

    23 | -------------------------------------------------------------------------------- /MvcClient/Views/Shared/_CookieConsentPartial.cshtml: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Http.Features 2 | 3 | @{ 4 | var consentFeature = Context.Features.Get(); 5 | var showBanner = !consentFeature?.CanTrack ?? false; 6 | var cookieString = consentFeature?.CreateConsentCookie(); 7 | } 8 | 9 | @if (showBanner) 10 | { 11 | 33 | 41 | } -------------------------------------------------------------------------------- /MvcClient/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @ViewData["Title"] - MvcClient 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 40 | 41 | 42 | 43 |
    44 | @RenderBody() 45 |
    46 |
    47 |

    © 2018 - MvcClient

    48 |
    49 |
    50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 69 | 70 | 71 | 72 | @RenderSection("Scripts", required: false) 73 | 74 | 75 | -------------------------------------------------------------------------------- /MvcClient/Views/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 12 | 18 | 19 | -------------------------------------------------------------------------------- /MvcClient/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using MvcClient 2 | @using MvcClient.Models 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | -------------------------------------------------------------------------------- /MvcClient/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /MvcClient/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /MvcClient/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Warning" 5 | } 6 | }, 7 | "AllowedHosts": "*" 8 | } 9 | -------------------------------------------------------------------------------- /MvcClient/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | /* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\ 2 | for details on configuring this project to bundle and minify static web assets. */ 3 | body { 4 | padding-top: 50px; 5 | padding-bottom: 20px; 6 | } 7 | 8 | /* Wrapping element */ 9 | /* Set some basic padding to keep content from hitting the edges */ 10 | .body-content { 11 | padding-left: 15px; 12 | padding-right: 15px; 13 | } 14 | 15 | /* Carousel */ 16 | .carousel-caption p { 17 | font-size: 20px; 18 | line-height: 1.4; 19 | } 20 | 21 | /* Make .svg files in the carousel display properly in older browsers */ 22 | .carousel-inner .item img[src$=".svg"] { 23 | width: 100%; 24 | } 25 | 26 | /* QR code generator */ 27 | #qrCode { 28 | margin: 15px; 29 | } 30 | 31 | /* Hide/rearrange for smaller screens */ 32 | @media screen and (max-width: 767px) { 33 | /* Hide captions */ 34 | .carousel-caption { 35 | display: none; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /MvcClient/wwwroot/css/site.min.css: -------------------------------------------------------------------------------- 1 | body{padding-top:50px;padding-bottom:20px}.body-content{padding-left:15px;padding-right:15px}.carousel-caption p{font-size:20px;line-height:1.4}.carousel-inner .item img[src$=".svg"]{width:100%}#qrCode{margin:15px}@media screen and (max-width:767px){.carousel-caption{display:none}} -------------------------------------------------------------------------------- /MvcClient/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobritodev/AspNetCore-IdentityServer4-Example/aa0f6294485127c895b441491e5401de290808ba/MvcClient/wwwroot/favicon.ico -------------------------------------------------------------------------------- /MvcClient/wwwroot/images/banner1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /MvcClient/wwwroot/images/banner2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /MvcClient/wwwroot/images/banner3.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /MvcClient/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | // for details on configuring this project to bundle and minify static web assets. 3 | 4 | // Write your JavaScript code. 5 | -------------------------------------------------------------------------------- /MvcClient/wwwroot/js/site.min.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobritodev/AspNetCore-IdentityServer4-Example/aa0f6294485127c895b441491e5401de290808ba/MvcClient/wwwroot/js/site.min.js -------------------------------------------------------------------------------- /MvcClient/wwwroot/lib/bootstrap/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bootstrap", 3 | "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", 4 | "keywords": [ 5 | "css", 6 | "js", 7 | "less", 8 | "mobile-first", 9 | "responsive", 10 | "front-end", 11 | "framework", 12 | "web" 13 | ], 14 | "homepage": "http://getbootstrap.com", 15 | "license": "MIT", 16 | "moduleType": "globals", 17 | "main": [ 18 | "less/bootstrap.less", 19 | "dist/js/bootstrap.js" 20 | ], 21 | "ignore": [ 22 | "/.*", 23 | "_config.yml", 24 | "CNAME", 25 | "composer.json", 26 | "CONTRIBUTING.md", 27 | "docs", 28 | "js/tests", 29 | "test-infra" 30 | ], 31 | "dependencies": { 32 | "jquery": "1.9.1 - 3" 33 | }, 34 | "version": "3.3.7", 35 | "_release": "3.3.7", 36 | "_resolution": { 37 | "type": "version", 38 | "tag": "v3.3.7", 39 | "commit": "0b9c4a4007c44201dce9a6cc1a38407005c26c86" 40 | }, 41 | "_source": "https://github.com/twbs/bootstrap.git", 42 | "_target": "v3.3.7", 43 | "_originalSource": "bootstrap", 44 | "_direct": true 45 | } -------------------------------------------------------------------------------- /MvcClient/wwwroot/lib/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2016 Twitter, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /MvcClient/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobritodev/AspNetCore-IdentityServer4-Example/aa0f6294485127c895b441491e5401de290808ba/MvcClient/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /MvcClient/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobritodev/AspNetCore-IdentityServer4-Example/aa0f6294485127c895b441491e5401de290808ba/MvcClient/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /MvcClient/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobritodev/AspNetCore-IdentityServer4-Example/aa0f6294485127c895b441491e5401de290808ba/MvcClient/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /MvcClient/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobritodev/AspNetCore-IdentityServer4-Example/aa0f6294485127c895b441491e5401de290808ba/MvcClient/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /MvcClient/wwwroot/lib/bootstrap/dist/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /MvcClient/wwwroot/lib/jquery-validation-unobtrusive/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-validation-unobtrusive", 3 | "homepage": "https://github.com/aspnet/jquery-validation-unobtrusive", 4 | "version": "3.2.9", 5 | "_release": "3.2.9", 6 | "_resolution": { 7 | "type": "version", 8 | "tag": "v3.2.9", 9 | "commit": "a91f5401898e125f10771c5f5f0909d8c4c82396" 10 | }, 11 | "_source": "https://github.com/aspnet/jquery-validation-unobtrusive.git", 12 | "_target": "^3.2.9", 13 | "_originalSource": "jquery-validation-unobtrusive", 14 | "_direct": true 15 | } -------------------------------------------------------------------------------- /MvcClient/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) .NET Foundation. All rights reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | these files except in compliance with the License. You may obtain a copy of the 5 | License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | -------------------------------------------------------------------------------- /MvcClient/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js: -------------------------------------------------------------------------------- 1 | // Unobtrusive validation support library for jQuery and jQuery Validate 2 | // Copyright (C) Microsoft Corporation. All rights reserved. 3 | // @version v3.2.9 4 | !function(a){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery.validation"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery-validation")):jQuery.validator.unobtrusive=a(jQuery)}(function(a){function e(a,e,n){a.rules[e]=n,a.message&&(a.messages[e]=a.message)}function n(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function t(a){return a.replace(/([!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function r(a){return a.substr(0,a.lastIndexOf(".")+1)}function i(a,e){return 0===a.indexOf("*.")&&(a=a.replace("*.",e)),a}function o(e,n){var r=a(this).find("[data-valmsg-for='"+t(n[0].name)+"']"),i=r.attr("data-valmsg-replace"),o=i?a.parseJSON(i)!==!1:null;r.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",r),o?(r.empty(),e.removeClass("input-validation-error").appendTo(r)):e.hide()}function d(e,n){var t=a(this).find("[data-valmsg-summary=true]"),r=t.find("ul");r&&r.length&&n.errorList.length&&(r.empty(),t.addClass("validation-summary-errors").removeClass("validation-summary-valid"),a.each(n.errorList,function(){a("
  • ").html(this.message).appendTo(r)}))}function s(e){var n=e.data("unobtrusiveContainer");if(n){var t=n.attr("data-valmsg-replace"),r=t?a.parseJSON(t):null;n.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),r&&n.empty()}}function l(e){var n=a(this),t="__jquery_unobtrusive_validation_form_reset";if(!n.data(t)){n.data(t,!0);try{n.data("validator").resetForm()}finally{n.removeData(t)}n.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),n.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function u(e){var n=a(e),t=n.data(v),r=a.proxy(l,e),i=f.unobtrusive.options||{},u=function(n,t){var r=i[n];r&&a.isFunction(r)&&r.apply(e,t)};return t||(t={options:{errorClass:i.errorClass||"input-validation-error",errorElement:i.errorElement||"span",errorPlacement:function(){o.apply(e,arguments),u("errorPlacement",arguments)},invalidHandler:function(){d.apply(e,arguments),u("invalidHandler",arguments)},messages:{},rules:{},success:function(){s.apply(e,arguments),u("success",arguments)}},attachValidation:function(){n.off("reset."+v,r).on("reset."+v,r).validate(this.options)},validate:function(){return n.validate(),n.valid()}},n.data(v,t)),t}var m,f=a.validator,v="unobtrusiveValidation";return f.unobtrusive={adapters:[],parseElement:function(e,n){var t,r,i,o=a(e),d=o.parents("form")[0];d&&(t=u(d),t.options.rules[e.name]=r={},t.options.messages[e.name]=i={},a.each(this.adapters,function(){var n="data-val-"+this.name,t=o.attr(n),s={};void 0!==t&&(n+="-",a.each(this.params,function(){s[this]=o.attr(n+this)}),this.adapt({element:e,form:d,message:t,params:s,rules:r,messages:i}))}),a.extend(r,{__dummy__:!0}),n||t.attachValidation())},parse:function(e){var n=a(e),t=n.parents().addBack().filter("form").add(n.find("form")).has("[data-val=true]");n.find("[data-val=true]").each(function(){f.unobtrusive.parseElement(this,!0)}),t.each(function(){var a=u(this);a&&a.attachValidation()})}},m=f.unobtrusive.adapters,m.add=function(a,e,n){return n||(n=e,e=[]),this.push({name:a,params:e,adapt:n}),this},m.addBool=function(a,n){return this.add(a,function(t){e(t,n||a,!0)})},m.addMinMax=function(a,n,t,r,i,o){return this.add(a,[i||"min",o||"max"],function(a){var i=a.params.min,o=a.params.max;i&&o?e(a,r,[i,o]):i?e(a,n,i):o&&e(a,t,o)})},m.addSingleVal=function(a,n,t){return this.add(a,[n||"val"],function(r){e(r,t||a,r.params[n])})},f.addMethod("__dummy__",function(a,e,n){return!0}),f.addMethod("regex",function(a,e,n){var t;return!!this.optional(e)||(t=new RegExp(n).exec(a),t&&0===t.index&&t[0].length===a.length)}),f.addMethod("nonalphamin",function(a,e,n){var t;return n&&(t=a.match(/\W/g),t=t&&t.length>=n),t}),f.methods.extension?(m.addSingleVal("accept","mimtype"),m.addSingleVal("extension","extension")):m.addSingleVal("extension","extension","accept"),m.addSingleVal("regex","pattern"),m.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),m.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),m.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),m.add("equalto",["other"],function(n){var o=r(n.element.name),d=n.params.other,s=i(d,o),l=a(n.form).find(":input").filter("[name='"+t(s)+"']")[0];e(n,"equalTo",l)}),m.add("required",function(a){"INPUT"===a.element.tagName.toUpperCase()&&"CHECKBOX"===a.element.type.toUpperCase()||e(a,"required",!0)}),m.add("remote",["url","type","additionalfields"],function(o){var d={url:o.params.url,type:o.params.type||"GET",data:{}},s=r(o.element.name);a.each(n(o.params.additionalfields||o.element.name),function(e,n){var r=i(n,s);d.data[r]=function(){var e=a(o.form).find(":input").filter("[name='"+t(r)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),e(o,"remote",d)}),m.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&e(a,"minlength",a.params.min),a.params.nonalphamin&&e(a,"nonalphamin",a.params.nonalphamin),a.params.regex&&e(a,"regex",a.params.regex)}),m.add("fileextensions",["extensions"],function(a){e(a,"extension",a.params.extensions)}),a(function(){f.unobtrusive.parse(document)}),f.unobtrusive}); -------------------------------------------------------------------------------- /MvcClient/wwwroot/lib/jquery-validation/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-validation", 3 | "homepage": "https://jqueryvalidation.org/", 4 | "repository": { 5 | "type": "git", 6 | "url": "git://github.com/jquery-validation/jquery-validation.git" 7 | }, 8 | "authors": [ 9 | "Jörn Zaefferer " 10 | ], 11 | "description": "Form validation made easy", 12 | "main": "dist/jquery.validate.js", 13 | "keywords": [ 14 | "forms", 15 | "validation", 16 | "validate" 17 | ], 18 | "license": "MIT", 19 | "ignore": [ 20 | "**/.*", 21 | "node_modules", 22 | "bower_components", 23 | "test", 24 | "demo", 25 | "lib" 26 | ], 27 | "dependencies": { 28 | "jquery": ">= 1.7.2" 29 | }, 30 | "version": "1.17.0", 31 | "_release": "1.17.0", 32 | "_resolution": { 33 | "type": "version", 34 | "tag": "1.17.0", 35 | "commit": "fc9b12d3bfaa2d0c04605855b896edb2934c0772" 36 | }, 37 | "_source": "https://github.com/jzaefferer/jquery-validation.git", 38 | "_target": "^1.17.0", 39 | "_originalSource": "jquery-validation", 40 | "_direct": true 41 | } -------------------------------------------------------------------------------- /MvcClient/wwwroot/lib/jquery-validation/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright Jörn Zaefferer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /MvcClient/wwwroot/lib/jquery/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery", 3 | "main": "dist/jquery.js", 4 | "license": "MIT", 5 | "ignore": [ 6 | "package.json" 7 | ], 8 | "keywords": [ 9 | "jquery", 10 | "javascript", 11 | "browser", 12 | "library" 13 | ], 14 | "homepage": "https://github.com/jquery/jquery-dist", 15 | "version": "3.3.1", 16 | "_release": "3.3.1", 17 | "_resolution": { 18 | "type": "version", 19 | "tag": "3.3.1", 20 | "commit": "9e8ec3d10fad04748176144f108d7355662ae75e" 21 | }, 22 | "_source": "https://github.com/jquery/jquery-dist.git", 23 | "_target": "^3.3.1", 24 | "_originalSource": "jquery", 25 | "_direct": true 26 | } -------------------------------------------------------------------------------- /MvcClient/wwwroot/lib/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright JS Foundation and other contributors, https://js.foundation/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | All files located in the node_modules and external directories are 34 | externally maintained libraries used by this software which have their 35 | own licenses; we recommend you read them, as their terms may differ from 36 | the terms above. 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ASP.NET Core 3.1 com IdentityServer4 2 | 3 | 4 | 5 | Example App - Building IdentityServer4 ASP.NET Core 3.1 Server and a MVC Client as well 6 | 7 | Pre reqs 8 | 9 | * ASP.NET Core 3.1 10 | 11 | # How to run 12 | 13 | 1. Clone this repo 14 | 2. Open Project 15 | 3. Configure both projects to run at same time. 16 | 17 | 18 | More about on [ASP.NET Core 3.1 com IdentityServer4](https://www.brunobrito.net.br/aspnet-core-identityserver4/) - Portuguese only --------------------------------------------------------------------------------