├── .github └── FUNDING.yml ├── .gitignore ├── Exercises ├── Authentication.Roles │ ├── Authorization.Roles.csproj │ ├── Controllers │ │ ├── AdminController.cs │ │ ├── HomeController.cs │ │ └── LoginViewModel.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── Views │ │ ├── Admin │ │ │ ├── Administrator.cshtml │ │ │ ├── Index.cshtml │ │ │ ├── Login.cshtml │ │ │ └── Manager.cshtml │ │ ├── Home │ │ │ ├── AccessDenied.cshtml │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ ├── _Menu.cshtml │ │ │ └── _UserInfo.cshtml │ │ └── _ViewImports.cshtml │ ├── appsettings.Development.json │ └── appsettings.json ├── Authorization.Basics │ ├── Authorization.Basics.csproj │ ├── Controllers │ │ ├── AdminController.cs │ │ ├── HomeController.cs │ │ └── LoginViewModel.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── Views │ │ ├── Admin │ │ │ ├── Index.cshtml │ │ │ └── Login.cshtml │ │ ├── Home │ │ │ └── Index.cshtml │ │ └── _ViewImports.cshtml │ ├── appsettings.Development.json │ └── appsettings.json ├── Authorization.Blazor.WebAssembly │ ├── App.razor │ ├── Authorization.Blazor.WebAssembly.csproj │ ├── Pages │ │ ├── Authentication.razor │ │ ├── Counter.razor │ │ ├── FetchData.razor │ │ └── Index.razor │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Shared │ │ ├── LoginDisplay.razor │ │ ├── MainLayout.razor │ │ ├── MainLayout.razor.css │ │ ├── NavMenu.razor │ │ ├── NavMenu.razor.css │ │ ├── RedirectToLogin.razor │ │ └── SurveyPrompt.razor │ ├── _Imports.razor │ └── wwwroot │ │ ├── appsettings.json │ │ ├── css │ │ ├── app.css │ │ ├── bootstrap │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ └── open-iconic │ │ │ ├── FONT-LICENSE │ │ │ ├── ICON-LICENSE │ │ │ ├── README.md │ │ │ └── font │ │ │ ├── css │ │ │ └── open-iconic-bootstrap.min.css │ │ │ └── fonts │ │ │ ├── open-iconic.eot │ │ │ ├── open-iconic.otf │ │ │ ├── open-iconic.svg │ │ │ ├── open-iconic.ttf │ │ │ └── open-iconic.woff │ │ ├── favicon.ico │ │ ├── index.html │ │ └── sample-data │ │ └── weather.json ├── Authorization.Client.Mvc │ ├── Authorization.Client.Mvc.csproj │ ├── Controllers │ │ └── SiteController.cs │ ├── Infrastructure │ │ └── Auth │ │ │ ├── CustomAuthorizationPolicyProvider.cs │ │ │ ├── OlderThanRequirement.cs │ │ │ └── OlderThanRequirementHandler.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── ViewModels │ │ ├── ClaimViewer.cs │ │ ├── ClaimsManager.cs │ │ └── LoginViewModel.cs │ ├── Views │ │ ├── Shared │ │ │ └── _Menu.cshtml │ │ ├── Site │ │ │ ├── GoodBye.cshtml │ │ │ ├── Index.cshtml │ │ │ └── Secret.cshtml │ │ └── _ViewImports.cshtml │ ├── appsettings.Development.json │ └── appsettings.json ├── Authorization.Database │ ├── Authorization.Database.csproj │ ├── Controllers │ │ ├── AdminController.cs │ │ ├── HomeController.cs │ │ └── LoginViewModel.cs │ ├── Data │ │ ├── ApplicationDbContext.cs │ │ └── Databaseinitializer.cs │ ├── Entities │ │ ├── ApplicationRole.cs │ │ └── ApplicationUser.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── Views │ │ ├── Admin │ │ │ ├── Administrator.cshtml │ │ │ ├── Index.cshtml │ │ │ ├── Login.cshtml │ │ │ └── Manager.cshtml │ │ ├── Home │ │ │ ├── AccessDenied.cshtml │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ ├── _Menu.cshtml │ │ │ └── _UserInfo.cshtml │ │ └── _ViewImports.cshtml │ ├── appsettings.Development.json │ └── appsettings.json ├── Authorization.FacebookDemo │ ├── Authorization.FacebookDemo.csproj │ ├── Controllers │ │ ├── AdminController.cs │ │ ├── ExternalLoginViewModel.cs │ │ ├── HomeController.cs │ │ └── LoginViewModel.cs │ ├── Data │ │ ├── ApplicationDbContext.cs │ │ └── Databaseinitializer.cs │ ├── Entities │ │ ├── ApplicationRole.cs │ │ └── ApplicationUser.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── Views │ │ ├── Admin │ │ │ ├── Administrator.cshtml │ │ │ ├── Index.cshtml │ │ │ ├── Login.cshtml │ │ │ ├── Manager.cshtml │ │ │ └── RegisterExternal.cshtml │ │ ├── Home │ │ │ ├── AccessDenied.cshtml │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ ├── _Menu.cshtml │ │ │ └── _UserInfo.cshtml │ │ └── _ViewImports.cshtml │ ├── appsettings.Development.json │ └── appsettings.json ├── Authorization.IdentityServer │ ├── Account │ │ ├── AccountController.cs │ │ ├── AccountOptions.cs │ │ ├── ExternalController.cs │ │ ├── ExternalProvider.cs │ │ ├── LoggedOutViewModel.cs │ │ ├── LoginInputModel.cs │ │ ├── LoginViewModel.cs │ │ ├── LogoutInputModel.cs │ │ ├── LogoutViewModel.cs │ │ └── RedirectViewModel.cs │ ├── Authorization.IdentityServer.csproj │ ├── Consent │ │ ├── ConsentController.cs │ │ ├── ConsentInputModel.cs │ │ ├── ConsentOptions.cs │ │ ├── ConsentViewModel.cs │ │ ├── ProcessConsentResult.cs │ │ └── ScopeViewModel.cs │ ├── Data │ │ ├── ApplicationDb │ │ │ ├── 20200613075727_Initial.Designer.cs │ │ │ ├── 20200613075727_Initial.cs │ │ │ └── ApplicationDbContextModelSnapshot.cs │ │ ├── ApplicationDbContext.cs │ │ ├── ConfigurationDb │ │ │ ├── 20200613080324_ConfigurationDbMigration.Designer.cs │ │ │ ├── 20200613080324_ConfigurationDbMigration.cs │ │ │ └── ConfigurationDbContextModelSnapshot.cs │ │ ├── Databaseinitializer.cs │ │ ├── PersistedGrantDb │ │ │ ├── 20200613080242_PersistedGrantDbMigration.Designer.cs │ │ │ ├── 20200613080242_PersistedGrantDbMigration.cs │ │ │ └── PersistedGrantDbContextModelSnapshot.cs │ │ └── migrations.txt │ ├── Device │ │ ├── DeviceAuthorizationInputModel.cs │ │ ├── DeviceAuthorizationViewModel.cs │ │ └── DeviceController.cs │ ├── Diagnostics │ │ ├── DiagnosticsController.cs │ │ └── DiagnosticsViewModel.cs │ ├── Extensions.cs │ ├── Grants │ │ ├── GrantsController.cs │ │ └── GrantsViewModel.cs │ ├── Home │ │ ├── ErrorViewModel.cs │ │ └── HomeController.cs │ ├── IdentityServerConfiguration.cs │ ├── Infrastructure │ │ └── ProfileService.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── SecurityHeadersAttribute.cs │ ├── Startup.cs │ ├── ViewModels │ │ └── LoginViewModel.cs │ ├── Views │ │ ├── Account │ │ │ ├── AccessDenied.cshtml │ │ │ ├── LoggedOut.cshtml │ │ │ ├── Login.cshtml │ │ │ └── Logout.cshtml │ │ ├── Consent │ │ │ └── Index.cshtml │ │ ├── Device │ │ │ ├── Success.cshtml │ │ │ ├── UserCodeCapture.cshtml │ │ │ └── UserCodeConfirmation.cshtml │ │ ├── Diagnostics │ │ │ └── Index.cshtml │ │ ├── Grants │ │ │ └── Index.cshtml │ │ ├── Home │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ ├── Error.cshtml │ │ │ ├── Redirect.cshtml │ │ │ ├── _Layout.cshtml │ │ │ ├── _Nav.cshtml │ │ │ ├── _ScopeListItem.cshtml │ │ │ └── _ValidationSummary.cshtml │ │ ├── _ViewImports.cshtml │ │ └── _ViewStart.cshtml │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── tempkey.jwk │ └── wwwroot │ │ ├── css │ │ ├── site.css │ │ ├── site.less │ │ ├── site.min.css │ │ └── site.scss │ │ ├── favicon.ico │ │ ├── icon.jpg │ │ ├── icon.png │ │ ├── js │ │ ├── signin-redirect.js │ │ └── signout-redirect.js │ │ └── lib │ │ ├── bootstrap │ │ ├── LICENSE │ │ ├── README.md │ │ ├── css │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ └── bootstrap.min.css │ │ ├── dist │ │ │ ├── css │ │ │ │ ├── bootstrap-grid.css │ │ │ │ ├── bootstrap-grid.css.map │ │ │ │ ├── bootstrap-grid.min.css │ │ │ │ ├── bootstrap-grid.min.css.map │ │ │ │ ├── bootstrap-reboot.css │ │ │ │ ├── bootstrap-reboot.css.map │ │ │ │ ├── bootstrap-reboot.min.css │ │ │ │ ├── bootstrap-reboot.min.css.map │ │ │ │ ├── bootstrap.css │ │ │ │ ├── bootstrap.css.map │ │ │ │ ├── bootstrap.min.css │ │ │ │ └── bootstrap.min.css.map │ │ │ └── js │ │ │ │ ├── bootstrap.bundle.js │ │ │ │ ├── bootstrap.bundle.js.map │ │ │ │ ├── bootstrap.bundle.min.js │ │ │ │ ├── bootstrap.bundle.min.js.map │ │ │ │ ├── bootstrap.js │ │ │ │ ├── bootstrap.js.map │ │ │ │ ├── bootstrap.min.js │ │ │ │ └── bootstrap.min.js.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 │ │ └── scss │ │ │ ├── _alert.scss │ │ │ ├── _badge.scss │ │ │ ├── _breadcrumb.scss │ │ │ ├── _button-group.scss │ │ │ ├── _buttons.scss │ │ │ ├── _card.scss │ │ │ ├── _carousel.scss │ │ │ ├── _close.scss │ │ │ ├── _code.scss │ │ │ ├── _custom-forms.scss │ │ │ ├── _dropdown.scss │ │ │ ├── _forms.scss │ │ │ ├── _functions.scss │ │ │ ├── _grid.scss │ │ │ ├── _images.scss │ │ │ ├── _input-group.scss │ │ │ ├── _jumbotron.scss │ │ │ ├── _list-group.scss │ │ │ ├── _media.scss │ │ │ ├── _mixins.scss │ │ │ ├── _modal.scss │ │ │ ├── _nav.scss │ │ │ ├── _navbar.scss │ │ │ ├── _pagination.scss │ │ │ ├── _popover.scss │ │ │ ├── _print.scss │ │ │ ├── _progress.scss │ │ │ ├── _reboot.scss │ │ │ ├── _root.scss │ │ │ ├── _spinners.scss │ │ │ ├── _tables.scss │ │ │ ├── _toasts.scss │ │ │ ├── _tooltip.scss │ │ │ ├── _transitions.scss │ │ │ ├── _type.scss │ │ │ ├── _utilities.scss │ │ │ ├── _variables.scss │ │ │ ├── bootstrap-grid.scss │ │ │ ├── bootstrap-reboot.scss │ │ │ ├── bootstrap.scss │ │ │ ├── mixins │ │ │ ├── _alert.scss │ │ │ ├── _background-variant.scss │ │ │ ├── _badge.scss │ │ │ ├── _border-radius.scss │ │ │ ├── _box-shadow.scss │ │ │ ├── _breakpoints.scss │ │ │ ├── _buttons.scss │ │ │ ├── _caret.scss │ │ │ ├── _clearfix.scss │ │ │ ├── _deprecate.scss │ │ │ ├── _float.scss │ │ │ ├── _forms.scss │ │ │ ├── _gradients.scss │ │ │ ├── _grid-framework.scss │ │ │ ├── _grid.scss │ │ │ ├── _hover.scss │ │ │ ├── _image.scss │ │ │ ├── _list-group.scss │ │ │ ├── _lists.scss │ │ │ ├── _nav-divider.scss │ │ │ ├── _pagination.scss │ │ │ ├── _reset-text.scss │ │ │ ├── _resize.scss │ │ │ ├── _screen-reader.scss │ │ │ ├── _size.scss │ │ │ ├── _table-row.scss │ │ │ ├── _text-emphasis.scss │ │ │ ├── _text-hide.scss │ │ │ ├── _text-truncate.scss │ │ │ ├── _transition.scss │ │ │ └── _visibility.scss │ │ │ ├── utilities │ │ │ ├── _align.scss │ │ │ ├── _background.scss │ │ │ ├── _borders.scss │ │ │ ├── _clearfix.scss │ │ │ ├── _display.scss │ │ │ ├── _embed.scss │ │ │ ├── _flex.scss │ │ │ ├── _float.scss │ │ │ ├── _overflow.scss │ │ │ ├── _position.scss │ │ │ ├── _screenreaders.scss │ │ │ ├── _shadows.scss │ │ │ ├── _sizing.scss │ │ │ ├── _spacing.scss │ │ │ ├── _stretched-link.scss │ │ │ ├── _text.scss │ │ │ └── _visibility.scss │ │ │ └── vendor │ │ │ └── _rfs.scss │ │ └── jquery │ │ ├── LICENSE.txt │ │ ├── README.md │ │ ├── dist │ │ ├── jquery.js │ │ ├── jquery.min.js │ │ ├── jquery.min.map │ │ ├── jquery.slim.js │ │ ├── jquery.slim.min.js │ │ └── jquery.slim.min.map │ │ ├── jquery.js │ │ ├── jquery.min.js │ │ └── jquery.min.map ├── Authorization.JavaScript │ ├── Authorization.JavaScript.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── appsettings.Development.json │ ├── appsettings.json │ └── wwwroot │ │ ├── Index.html │ │ ├── callback.html │ │ ├── js │ │ ├── callback.js │ │ ├── index.js │ │ └── refresh.js │ │ └── refresh.html ├── Authorization.JwtBearer │ ├── Authorization.JwtBearer.csproj │ ├── Contants.cs │ ├── Controllers │ │ └── HomeController.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── Views │ │ ├── Home │ │ │ ├── Authenticate.cshtml │ │ │ ├── Index.cshtml │ │ │ └── Secret.cshtml │ │ ├── Shared │ │ │ └── _Links.cshtml │ │ └── _ViewImports.cshtml │ ├── appsettings.Development.json │ └── appsettings.json ├── Authorization.Orders.Api │ ├── Authorization.Orders.Api.csproj │ ├── Controllers │ │ └── SiteController.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── Views │ │ ├── Shared │ │ │ └── _Menu.cshtml │ │ ├── Site │ │ │ └── Index.cshtml │ │ └── _ViewImports.cshtml │ ├── appsettings.Development.json │ └── appsettings.json ├── Authorization.Swagger │ ├── Authorization.Swagger.csproj │ ├── Controllers │ │ └── ApiController.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── appsettings.Development.json │ └── appsettings.json ├── Authorization.Users.Api │ ├── Authorization.Users.Api.csproj │ ├── Controllers │ │ └── SiteController.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── Views │ │ ├── Shared │ │ │ └── _Menu.cshtml │ │ ├── Site │ │ │ ├── GetOrders.cshtml │ │ │ └── Index.cshtml │ │ └── _ViewImports.cshtml │ ├── appsettings.Development.json │ └── appsettings.json ├── Authorization.VKontakte │ ├── Authorization.VKontakte.csproj │ ├── Controllers │ │ ├── AdminController.cs │ │ ├── ExternalLoginViewModel.cs │ │ ├── HomeController.cs │ │ └── LoginViewModel.cs │ ├── Data │ │ ├── ApplicationDbContext.cs │ │ └── Databaseinitializer.cs │ ├── Entities │ │ ├── ApplicationRole.cs │ │ └── ApplicationUser.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── Views │ │ ├── Admin │ │ │ ├── Administrator.cshtml │ │ │ ├── Index.cshtml │ │ │ ├── Login.cshtml │ │ │ ├── Manager.cshtml │ │ │ └── RegisterExternal.cshtml │ │ ├── Home │ │ │ ├── AccessDenied.cshtml │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ ├── _Menu.cshtml │ │ │ └── _UserInfo.cshtml │ │ └── _ViewImports.cshtml │ ├── appsettings.Development.json │ └── appsettings.json ├── Authorization.sln └── NuGet.Config ├── LICENSE ├── README.md └── Whatnot └── Authentication.pptx /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: https://www.calabonga.net/site/thanks 2 | -------------------------------------------------------------------------------- /Exercises/Authentication.Roles/Authorization.Roles.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Exercises/Authentication.Roles/Controllers/AdminController.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Security.Claims; 3 | using System.Threading.Tasks; 4 | using Microsoft.AspNetCore.Authentication; 5 | using Microsoft.AspNetCore.Authorization; 6 | using Microsoft.AspNetCore.Mvc; 7 | 8 | namespace Authorization.Roles.Controllers 9 | { 10 | [Authorize] 11 | public class AdminController : Controller 12 | { 13 | public IActionResult Index() 14 | { 15 | return View(); 16 | } 17 | 18 | [Authorize(Policy = "Administrator")] 19 | public IActionResult Administrator() 20 | { 21 | return View(); 22 | } 23 | 24 | [Authorize(Policy = "Manager")] 25 | public IActionResult Manager() 26 | { 27 | return View(); 28 | } 29 | 30 | [AllowAnonymous] 31 | public IActionResult Login(string returnUrl) 32 | { 33 | return View(); 34 | } 35 | 36 | [HttpPost] 37 | [AllowAnonymous] 38 | public async Task Login(LoginViewModel model) 39 | { 40 | if (!ModelState.IsValid) 41 | { 42 | return View(model); 43 | } 44 | 45 | var claims = new List 46 | { 47 | new Claim(ClaimTypes.Name,model.UserName), 48 | new Claim(ClaimTypes.Role,"Administrator") 49 | }; 50 | var claimIdentity = new ClaimsIdentity(claims, "Cookie"); 51 | var claimPrincipal = new ClaimsPrincipal(claimIdentity); 52 | await HttpContext.SignInAsync("Cookie", claimPrincipal); 53 | 54 | return Redirect(model.ReturnUrl); 55 | } 56 | 57 | public IActionResult LogOff() 58 | { 59 | HttpContext.SignOutAsync("Cookie"); 60 | return Redirect("/Home/Index"); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Exercises/Authentication.Roles/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | 3 | namespace Authorization.Roles.Controllers 4 | { 5 | public class HomeController: Controller 6 | { 7 | 8 | public IActionResult Index() 9 | { 10 | ViewBag.Name = User.Identity.Name; 11 | ViewBag.IsAuthenticated = User.Identity.IsAuthenticated; 12 | return View(); 13 | } 14 | 15 | public IActionResult AccessDenied() 16 | { 17 | return View(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Exercises/Authentication.Roles/Controllers/LoginViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Authorization.Roles.Controllers 4 | { 5 | public class LoginViewModel 6 | { 7 | [Required] 8 | public string UserName { get; set; } 9 | 10 | [Required] 11 | public string Password { get; set; } 12 | 13 | [Required] 14 | public string ReturnUrl { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /Exercises/Authentication.Roles/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Hosting; 3 | 4 | namespace Authorization.Roles 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 | -------------------------------------------------------------------------------- /Exercises/Authentication.Roles/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "profiles": { 4 | "Authentication.Roles": { 5 | "commandName": "Project", 6 | "launchBrowser": true, 7 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 8 | "environmentVariables": { 9 | "ASPNETCORE_ENVIRONMENT": "Development" 10 | } 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Exercises/Authentication.Roles/Startup.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Claims; 2 | using Microsoft.AspNetCore.Builder; 3 | using Microsoft.AspNetCore.Hosting; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Microsoft.Extensions.Hosting; 6 | 7 | namespace Authorization.Roles 8 | { 9 | public class Startup 10 | { 11 | public void ConfigureServices(IServiceCollection services) 12 | { 13 | services.AddAuthentication("Cookie") 14 | .AddCookie("Cookie", config => 15 | { 16 | config.LoginPath = "/Admin/Login"; 17 | config.AccessDeniedPath = "/Home/AccessDenied"; 18 | }); 19 | 20 | services.AddAuthorization(options => 21 | { 22 | options.AddPolicy("Administrator", builder => 23 | { 24 | builder.RequireClaim(ClaimTypes.Role, "Administrator"); 25 | }); 26 | 27 | options.AddPolicy("Manager", builder => 28 | { 29 | builder.RequireAssertion(x => x.User.HasClaim(ClaimTypes.Role, "Manager") 30 | || x.User.HasClaim(ClaimTypes.Role, "Administrator")); 31 | }); 32 | 33 | }); 34 | 35 | services.AddControllersWithViews(); 36 | } 37 | 38 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 39 | { 40 | if (env.IsDevelopment()) 41 | { 42 | app.UseDeveloperExceptionPage(); 43 | } 44 | 45 | app.UseRouting(); 46 | 47 | app.UseAuthentication(); 48 | 49 | app.UseAuthorization(); 50 | 51 | app.UseEndpoints(endpoints => 52 | { 53 | endpoints.MapDefaultControllerRoute(); 54 | }); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Exercises/Authentication.Roles/Views/Admin/Administrator.cshtml: -------------------------------------------------------------------------------- 1 | 

Administrator

2 | 3 | 4 | -------------------------------------------------------------------------------- /Exercises/Authentication.Roles/Views/Admin/Index.cshtml: -------------------------------------------------------------------------------- 1 | 

Secured Zone

2 | 3 | 4 | -------------------------------------------------------------------------------- /Exercises/Authentication.Roles/Views/Admin/Login.cshtml: -------------------------------------------------------------------------------- 1 | @model Authorization.Roles.Controllers.LoginViewModel 2 |

Login

3 | 4 |

5 | [Home] 6 |

7 | 8 |
9 | 10 |
11 | 12 | 13 | 14 |
15 |
16 | 17 | 18 | 19 |
20 | 21 |

22 | 23 |

24 |
-------------------------------------------------------------------------------- /Exercises/Authentication.Roles/Views/Admin/Manager.cshtml: -------------------------------------------------------------------------------- 1 | 

Manager

2 | 3 | 4 | -------------------------------------------------------------------------------- /Exercises/Authentication.Roles/Views/Home/AccessDenied.cshtml: -------------------------------------------------------------------------------- 1 | 

AccessDenied

2 | 3 | 4 | -------------------------------------------------------------------------------- /Exercises/Authentication.Roles/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | 

Home

2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Exercises/Authentication.Roles/Views/Shared/_Menu.cshtml: -------------------------------------------------------------------------------- 1 | [Home] 2 | [Secured Zone] 3 | @if (User.Identity.IsAuthenticated) 4 | { 5 | [Administrator] 6 | [Manager] 7 | [Log Off] 8 | } 9 | -------------------------------------------------------------------------------- /Exercises/Authentication.Roles/Views/Shared/_UserInfo.cshtml: -------------------------------------------------------------------------------- 1 | 

2 | IsAuthenticated : @User.Identity.IsAuthenticated 3 |

4 | 5 |

6 | Name : @User.Identity.Name 7 |

-------------------------------------------------------------------------------- /Exercises/Authentication.Roles/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers -------------------------------------------------------------------------------- /Exercises/Authentication.Roles/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Exercises/Authentication.Roles/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /Exercises/Authorization.Basics/Authorization.Basics.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Exercises/Authorization.Basics/Controllers/AdminController.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Security.Claims; 3 | using System.Threading.Tasks; 4 | using Microsoft.AspNetCore.Authentication; 5 | using Microsoft.AspNetCore.Authorization; 6 | using Microsoft.AspNetCore.Mvc; 7 | 8 | namespace Authorization.Basics.Controllers 9 | { 10 | [Authorize] 11 | public class AdminController : Controller 12 | { 13 | public IActionResult Index() 14 | { 15 | return View(); 16 | } 17 | 18 | [AllowAnonymous] 19 | public IActionResult Login(string returnUrl) 20 | { 21 | return View(); 22 | } 23 | 24 | [HttpPost] 25 | [AllowAnonymous] 26 | public async Task Login(LoginViewModel model) 27 | { 28 | if (!ModelState.IsValid) 29 | { 30 | return View(model); 31 | } 32 | 33 | var claims = new List 34 | { 35 | new Claim("Demo","Value") 36 | }; 37 | var claimIdentity = new ClaimsIdentity(claims, "Cookie"); 38 | var claimPrincipal = new ClaimsPrincipal(claimIdentity); 39 | await HttpContext.SignInAsync("Cookie", claimPrincipal); 40 | 41 | return Redirect(model.ReturnUrl); 42 | } 43 | 44 | public IActionResult LogOff() 45 | { 46 | HttpContext.SignOutAsync("Cookie"); 47 | return Redirect("/Home/Index"); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Exercises/Authorization.Basics/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | 3 | namespace Authorization.Basics.Controllers 4 | { 5 | public class HomeController: Controller 6 | { 7 | public IActionResult Index() 8 | { 9 | return View(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Exercises/Authorization.Basics/Controllers/LoginViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Authorization.Basics.Controllers 4 | { 5 | public class LoginViewModel 6 | { 7 | [Required] 8 | public string UserName { get; set; } 9 | 10 | [Required] 11 | public string Password { get; set; } 12 | 13 | [Required] 14 | public string ReturnUrl { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /Exercises/Authorization.Basics/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace Authorization.Basics 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Exercises/Authorization.Basics/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Authorization.Basics": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "launchUrl": "home/index", 7 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 8 | "environmentVariables": { 9 | "ASPNETCORE_ENVIRONMENT": "Development" 10 | } 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Exercises/Authorization.Basics/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 Authorization.Basics 7 | { 8 | public class Startup 9 | { 10 | public void ConfigureServices(IServiceCollection services) 11 | { 12 | services.AddAuthentication("Cookie") 13 | .AddCookie("Cookie", config => 14 | { 15 | config.LoginPath = "/Admin/Login"; 16 | }); 17 | 18 | services.AddAuthorization(); 19 | 20 | services.AddControllersWithViews(); 21 | } 22 | 23 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 24 | { 25 | if (env.IsDevelopment()) 26 | { 27 | app.UseDeveloperExceptionPage(); 28 | } 29 | 30 | app.UseRouting(); 31 | 32 | app.UseAuthentication(); 33 | 34 | app.UseAuthorization(); 35 | 36 | app.UseEndpoints(endpoints => 37 | { 38 | endpoints.MapDefaultControllerRoute(); 39 | 40 | }); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Exercises/Authorization.Basics/Views/Admin/Index.cshtml: -------------------------------------------------------------------------------- 1 | 

Admin

2 | 3 | Home 4 | Log Off -------------------------------------------------------------------------------- /Exercises/Authorization.Basics/Views/Admin/Login.cshtml: -------------------------------------------------------------------------------- 1 | @model LoginViewModel 2 |

Login

3 | 4 | Home 5 | 6 |
7 | 8 |
9 | 10 | 11 | 12 |
13 |
14 | 15 | 16 | 17 |
18 | 19 |

20 | 21 |

22 |
-------------------------------------------------------------------------------- /Exercises/Authorization.Basics/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | 

Home

2 | 3 | Admin -------------------------------------------------------------------------------- /Exercises/Authorization.Basics/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using Authorization.Basics.Controllers 2 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers -------------------------------------------------------------------------------- /Exercises/Authorization.Basics/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Exercises/Authorization.Basics/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/App.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | @if (!context.User.Identity.IsAuthenticated) 7 | { 8 | 9 | } 10 | else 11 | { 12 |

You are not authorized to access this resource.

13 | } 14 |
15 |
16 |
17 | 18 | 19 |

Sorry, there's nothing at this address.

20 |
21 |
22 |
23 |
24 | -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/Authorization.Blazor.WebAssembly.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/Pages/Authentication.razor: -------------------------------------------------------------------------------- 1 | @page "/authentication/{action}" 2 | @using Microsoft.AspNetCore.Components.WebAssembly.Authentication 3 | 4 | 5 | @code{ 6 | [Parameter] public string Action { get; set; } 7 | } 8 | -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | @using Microsoft.AspNetCore.Authorization 3 | @attribute [Authorize] 4 | 5 |

Counter (Secured)

6 | 7 |

Current count: @currentCount

8 | 9 | 10 | 11 | 12 | @code { 13 | private int currentCount = 0; 14 | 15 | private void IncrementCount() 16 | { 17 | currentCount++; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/Pages/FetchData.razor: -------------------------------------------------------------------------------- 1 | @page "/fetchdata" 2 | @inject HttpClient Http 3 | 4 |

Weather forecast

5 | 6 |

This component demonstrates fetching data from the server.

7 | 8 | @if (forecasts == null) 9 | { 10 |

Loading...

11 | } 12 | else 13 | { 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | @foreach (var forecast in forecasts) 25 | { 26 | 27 | 28 | 29 | 30 | 31 | 32 | } 33 | 34 |
DateTemp. (C)Temp. (F)Summary
@forecast.Date.ToShortDateString()@forecast.TemperatureC@forecast.TemperatureF@forecast.Summary
35 | } 36 | 37 | @code { 38 | private WeatherForecast[] forecasts; 39 | 40 | protected override async Task OnInitializedAsync() 41 | { 42 | forecasts = await Http.GetFromJsonAsync("sample-data/weather.json"); 43 | } 44 | 45 | public class WeatherForecast 46 | { 47 | public DateTime Date { get; set; } 48 | 49 | public int TemperatureC { get; set; } 50 | 51 | public string Summary { get; set; } 52 | 53 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/Pages/Index.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 |

Hello, world!

4 | 5 | 8 | 9 | Welcome to your new app. 10 | 11 | 12 | -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using System; 5 | using System.Net.Http; 6 | using System.Threading.Tasks; 7 | 8 | namespace Authorization.Blazor.WebAssembly 9 | { 10 | public class Program 11 | { 12 | public static async Task Main(string[] args) 13 | { 14 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 15 | builder.RootComponents.Add("#app"); 16 | 17 | builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); 18 | 19 | builder.Services.AddOidcAuthentication(options => 20 | { 21 | // Configure your authentication provider options here. 22 | // For more information, see https://aka.ms/blazor-standalone-auth 23 | options.ProviderOptions.RedirectUri = "https://localhost:8001/authentication/login-callback"; 24 | options.ProviderOptions.DefaultScopes.Add("openid"); 25 | options.ProviderOptions.DefaultScopes.Add("profile"); 26 | options.ProviderOptions.DefaultScopes.Add("OrdersAPI"); 27 | options.ProviderOptions.DefaultScopes.Add("blazor"); 28 | options.ProviderOptions.ResponseMode = "query"; 29 | options.ProviderOptions.ResponseType = "code"; 30 | 31 | 32 | builder.Configuration.Bind("oidc", options.ProviderOptions); 33 | 34 | }); 35 | 36 | await builder.Build().RunAsync(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Blazor.WebAssembly": { 4 | "commandName": "Project", 5 | "dotnetRunMessages": "true", 6 | "launchBrowser": true, 7 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 8 | "applicationUrl": "https://localhost:8001;http://localhost:8000", 9 | "environmentVariables": { 10 | "ASPNETCORE_ENVIRONMENT": "Development" 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/Shared/LoginDisplay.razor: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Components.Authorization 2 | @using Microsoft.AspNetCore.Components.WebAssembly.Authentication 3 | 4 | @inject NavigationManager Navigation 5 | @inject SignOutSessionStateManager SignOutManager 6 | 7 | 8 | 9 | Hello, @context?.User?.Identity?.Name! 10 | 11 | 12 | 13 | Log in 14 | 15 | 16 | 17 | @code{ 18 | private async Task BeginSignOut(MouseEventArgs args) 19 | { 20 | await SignOutManager.SetSignOutState(); 21 | Navigation.NavigateTo("authentication/logout"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 |
4 | 7 | 8 |
9 |
10 | 11 | About 12 |
13 | 14 |
15 | @Body 16 |
17 |
18 |
19 | -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/Shared/MainLayout.razor.css: -------------------------------------------------------------------------------- 1 | .page { 2 | position: relative; 3 | display: flex; 4 | flex-direction: column; 5 | } 6 | 7 | .main { 8 | flex: 1; 9 | } 10 | 11 | .sidebar { 12 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); 13 | } 14 | 15 | .top-row { 16 | background-color: #f7f7f7; 17 | border-bottom: 1px solid #d6d5d5; 18 | justify-content: flex-end; 19 | height: 3.5rem; 20 | display: flex; 21 | align-items: center; 22 | } 23 | 24 | .top-row ::deep a, .top-row .btn-link { 25 | white-space: nowrap; 26 | margin-left: 1.5rem; 27 | } 28 | 29 | .top-row a:first-child { 30 | overflow: hidden; 31 | text-overflow: ellipsis; 32 | } 33 | 34 | @media (max-width: 640.98px) { 35 | .top-row:not(.auth) { 36 | display: none; 37 | } 38 | 39 | .top-row.auth { 40 | justify-content: space-between; 41 | } 42 | 43 | .top-row a, .top-row .btn-link { 44 | margin-left: 0; 45 | } 46 | } 47 | 48 | @media (min-width: 641px) { 49 | .page { 50 | flex-direction: row; 51 | } 52 | 53 | .sidebar { 54 | width: 250px; 55 | height: 100vh; 56 | position: sticky; 57 | top: 0; 58 | } 59 | 60 | .top-row { 61 | position: sticky; 62 | top: 0; 63 | z-index: 1; 64 | } 65 | 66 | .main > div { 67 | padding-left: 2rem !important; 68 | padding-right: 1.5rem !important; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/Shared/NavMenu.razor: -------------------------------------------------------------------------------- 1 |  7 | 8 |
9 | 26 |
27 | 28 | @code { 29 | private bool collapseNavMenu = true; 30 | 31 | private string NavMenuCssClass => collapseNavMenu ? "collapse" : null; 32 | 33 | private void ToggleNavMenu() 34 | { 35 | collapseNavMenu = !collapseNavMenu; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/Shared/NavMenu.razor.css: -------------------------------------------------------------------------------- 1 | .navbar-toggler { 2 | background-color: rgba(255, 255, 255, 0.1); 3 | } 4 | 5 | .top-row { 6 | height: 3.5rem; 7 | background-color: rgba(0,0,0,0.4); 8 | } 9 | 10 | .navbar-brand { 11 | font-size: 1.1rem; 12 | } 13 | 14 | .oi { 15 | width: 2rem; 16 | font-size: 1.1rem; 17 | vertical-align: text-top; 18 | top: -2px; 19 | } 20 | 21 | .nav-item { 22 | font-size: 0.9rem; 23 | padding-bottom: 0.5rem; 24 | } 25 | 26 | .nav-item:first-of-type { 27 | padding-top: 1rem; 28 | } 29 | 30 | .nav-item:last-of-type { 31 | padding-bottom: 1rem; 32 | } 33 | 34 | .nav-item ::deep a { 35 | color: #d7d7d7; 36 | border-radius: 4px; 37 | height: 3rem; 38 | display: flex; 39 | align-items: center; 40 | line-height: 3rem; 41 | } 42 | 43 | .nav-item ::deep a.active { 44 | background-color: rgba(255,255,255,0.25); 45 | color: white; 46 | } 47 | 48 | .nav-item ::deep a:hover { 49 | background-color: rgba(255,255,255,0.1); 50 | color: white; 51 | } 52 | 53 | @media (min-width: 641px) { 54 | .navbar-toggler { 55 | display: none; 56 | } 57 | 58 | .collapse { 59 | /* Never collapse the sidebar for wide screens */ 60 | display: block; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/Shared/RedirectToLogin.razor: -------------------------------------------------------------------------------- 1 | @inject NavigationManager Navigation 2 | @using Microsoft.AspNetCore.Components.WebAssembly.Authentication 3 | @code { 4 | protected override void OnInitialized() 5 | { 6 | Navigation.NavigateTo($"authentication/login?returnUrl={Uri.EscapeDataString(Navigation.Uri)}"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/Shared/SurveyPrompt.razor: -------------------------------------------------------------------------------- 1 |  11 | 12 | @code { 13 | // Demonstrates how a parent component can supply parameters 14 | [Parameter] 15 | public string Title { get; set; } 16 | } 17 | -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Authorization 4 | @using Microsoft.AspNetCore.Components.Forms 5 | @using Microsoft.AspNetCore.Components.Routing 6 | @using Microsoft.AspNetCore.Components.Web 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.AspNetCore.Components.WebAssembly.Http 9 | @using Microsoft.JSInterop 10 | @using Authorization.Blazor.WebAssembly 11 | @using Authorization.Blazor.WebAssembly.Shared 12 | -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/wwwroot/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "oidc": { 3 | "Authority": "https://localhost:10001", 4 | "ClientId": "client_blazor_web_assembly" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/wwwroot/css/app.css: -------------------------------------------------------------------------------- 1 | @import url('open-iconic/font/css/open-iconic-bootstrap.min.css'); 2 | 3 | html, body { 4 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 5 | } 6 | 7 | a, .btn-link { 8 | color: #0366d6; 9 | } 10 | 11 | .btn-primary { 12 | color: #fff; 13 | background-color: #1b6ec2; 14 | border-color: #1861ac; 15 | } 16 | 17 | .content { 18 | padding-top: 1.1rem; 19 | } 20 | 21 | .valid.modified:not([type=checkbox]) { 22 | outline: 1px solid #26b050; 23 | } 24 | 25 | .invalid { 26 | outline: 1px solid red; 27 | } 28 | 29 | .validation-message { 30 | color: red; 31 | } 32 | 33 | #blazor-error-ui { 34 | background: lightyellow; 35 | bottom: 0; 36 | box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); 37 | display: none; 38 | left: 0; 39 | padding: 0.6rem 1.25rem 0.7rem 1.25rem; 40 | position: fixed; 41 | width: 100%; 42 | z-index: 1000; 43 | } 44 | 45 | #blazor-error-ui .dismiss { 46 | cursor: pointer; 47 | position: absolute; 48 | right: 0.75rem; 49 | top: 0.5rem; 50 | } 51 | -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/wwwroot/css/open-iconic/ICON-LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Waybury 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. -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Calabonga/Authorization-Exercises/84e59137ce28af565768a364267dbc1f0c3782dd/Exercises/Authorization.Blazor.WebAssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Calabonga/Authorization-Exercises/84e59137ce28af565768a364267dbc1f0c3782dd/Exercises/Authorization.Blazor.WebAssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Calabonga/Authorization-Exercises/84e59137ce28af565768a364267dbc1f0c3782dd/Exercises/Authorization.Blazor.WebAssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Calabonga/Authorization-Exercises/84e59137ce28af565768a364267dbc1f0c3782dd/Exercises/Authorization.Blazor.WebAssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Calabonga/Authorization-Exercises/84e59137ce28af565768a364267dbc1f0c3782dd/Exercises/Authorization.Blazor.WebAssembly/wwwroot/favicon.ico -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Authorization.Blazor.WebAssembly 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
Loading...
16 | 17 |
18 | An unhandled error has occurred. 19 | Reload 20 | 🗙 21 |
22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Exercises/Authorization.Blazor.WebAssembly/wwwroot/sample-data/weather.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "date": "2018-05-06", 4 | "temperatureC": 1, 5 | "summary": "Freezing" 6 | }, 7 | { 8 | "date": "2018-05-07", 9 | "temperatureC": 14, 10 | "summary": "Bracing" 11 | }, 12 | { 13 | "date": "2018-05-08", 14 | "temperatureC": -13, 15 | "summary": "Freezing" 16 | }, 17 | { 18 | "date": "2018-05-09", 19 | "temperatureC": -16, 20 | "summary": "Balmy" 21 | }, 22 | { 23 | "date": "2018-05-10", 24 | "temperatureC": -2, 25 | "summary": "Chilly" 26 | } 27 | ] 28 | -------------------------------------------------------------------------------- /Exercises/Authorization.Client.Mvc/Authorization.Client.Mvc.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Exercises/Authorization.Client.Mvc/Infrastructure/Auth/CustomAuthorizationPolicyProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.AspNetCore.Authorization; 3 | using Microsoft.Extensions.Options; 4 | 5 | namespace Authorization.Client.Mvc.Infrastructure.Auth 6 | { 7 | public class CustomAuthorizationPolicyProvider : DefaultAuthorizationPolicyProvider 8 | { 9 | private readonly AuthorizationOptions _options; 10 | 11 | /// 12 | /// Creates a new instance of . 13 | /// 14 | /// The options used to configure this instance. 15 | public CustomAuthorizationPolicyProvider(IOptions options) : base(options) 16 | { 17 | _options = options.Value; 18 | } 19 | 20 | /// 21 | /// Gets a from the given 22 | /// 23 | /// The policy name to retrieve. 24 | /// The named . 25 | public override async Task GetPolicyAsync(string policyName) 26 | { 27 | var policyExists = await base.GetPolicyAsync(policyName); 28 | if (policyExists == null) 29 | { 30 | policyExists = new AuthorizationPolicyBuilder().AddRequirements(new OlderThanRequirement(10)).Build(); 31 | _options.AddPolicy(policyName, policyExists); 32 | } 33 | 34 | return policyExists; 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Exercises/Authorization.Client.Mvc/Infrastructure/Auth/OlderThanRequirement.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | 3 | namespace Authorization.Client.Mvc.Infrastructure.Auth 4 | { 5 | public class OlderThanRequirement : IAuthorizationRequirement 6 | { 7 | public OlderThanRequirement(int years) 8 | { 9 | Years = years; 10 | } 11 | 12 | public int Years { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /Exercises/Authorization.Client.Mvc/Infrastructure/Auth/OlderThanRequirementHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Security.Claims; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Authorization; 6 | 7 | namespace Authorization.Client.Mvc.Infrastructure.Auth 8 | { 9 | public class OlderThanRequirementHandler : AuthorizationHandler 10 | { 11 | /// 12 | /// Makes a decision if authorization is allowed based on a specific requirement. 13 | /// 14 | /// The authorization context. 15 | /// The requirement to evaluate. 16 | protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, OlderThanRequirement requirement) 17 | { 18 | var hasClaim = context.User.HasClaim(x => x.Type == ClaimTypes.DateOfBirth); 19 | if (!hasClaim) 20 | { 21 | return Task.CompletedTask; 22 | } 23 | 24 | var dateOfBirth = context.User.FindFirst(x => x.Type == ClaimTypes.DateOfBirth).Value; 25 | var date = DateTime.Parse(dateOfBirth, new CultureInfo("ru-RU")); 26 | var canEnterDiff = DateTime.Now.Year - date.Year; 27 | if (canEnterDiff >= requirement.Years) 28 | { 29 | context.Succeed(requirement); 30 | 31 | } 32 | return Task.CompletedTask; 33 | 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /Exercises/Authorization.Client.Mvc/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace Authorization.Client.Mvc 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Exercises/Authorization.Client.Mvc/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Authorization.Client.Mvc": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "applicationUrl": "https://localhost:2001;http://localhost:2000", 7 | "environmentVariables": { 8 | "ASPNETCORE_ENVIRONMENT": "Development" 9 | } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Exercises/Authorization.Client.Mvc/ViewModels/ClaimViewer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IdentityModel.Tokens.Jwt; 4 | using System.Linq; 5 | using System.Security.Claims; 6 | 7 | namespace Authorization.Client.Mvc.ViewModels 8 | { 9 | /// 10 | /// Claim information extractor 11 | /// 12 | public class ClaimViewer 13 | { 14 | public ClaimViewer(string name, IEnumerable claims) 15 | { 16 | if (claims == null) throw new ArgumentNullException(nameof(claims)); 17 | Name = name ?? throw new ArgumentNullException(nameof(name)); 18 | Claims = claims.ToList(); 19 | Token = "N/A"; 20 | } 21 | 22 | public ClaimViewer(string name, string tokenJson, bool skipParsing = false) 23 | { 24 | Name = name ?? throw new ArgumentNullException(nameof(name)); 25 | if (!skipParsing) 26 | { 27 | Claims = ((JwtSecurityToken)new JwtSecurityTokenHandler().ReadToken(tokenJson)).Claims?.ToList(); 28 | } 29 | Token = tokenJson; 30 | } 31 | 32 | public List Claims { get; } 33 | 34 | public string Name { get; } 35 | 36 | public string Token { get; } 37 | } 38 | } -------------------------------------------------------------------------------- /Exercises/Authorization.Client.Mvc/ViewModels/LoginViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.DataAnnotations; 3 | using Microsoft.AspNetCore.Authentication; 4 | 5 | namespace Authorization.Client.Mvc.ViewModels 6 | { 7 | public class LoginViewModel 8 | { 9 | [Required] 10 | public string UserName { get; set; } 11 | 12 | [Required] 13 | public string Password { get; set; } 14 | 15 | [Required] 16 | public string ReturnUrl { get; set; } 17 | 18 | public IEnumerable ExternalProviders { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /Exercises/Authorization.Client.Mvc/Views/Shared/_Menu.cshtml: -------------------------------------------------------------------------------- 1 | [Index] 2 | [Secret] 3 | [Secret1] 4 | [Secret2] 5 | @if (User.Identity.IsAuthenticated) 6 | { 7 | 8 | [Log out] 9 | 10 | } 11 | -------------------------------------------------------------------------------- /Exercises/Authorization.Client.Mvc/Views/Site/GoodBye.cshtml: -------------------------------------------------------------------------------- 1 | 

GoodBye

2 | 3 | 4 | 5 |

6 | We're gonna missing you! 7 |

-------------------------------------------------------------------------------- /Exercises/Authorization.Client.Mvc/Views/Site/Index.cshtml: -------------------------------------------------------------------------------- 1 | 

Index

2 | 3 | -------------------------------------------------------------------------------- /Exercises/Authorization.Client.Mvc/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @addTagHelper "*, Microsoft.AspNetCore.Mvc.TagHelpers" -------------------------------------------------------------------------------- /Exercises/Authorization.Client.Mvc/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Exercises/Authorization.Client.Mvc/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /Exercises/Authorization.Database/Authorization.Database.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Exercises/Authorization.Database/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | 3 | namespace Authorization.Database.Controllers 4 | { 5 | public class HomeController: Controller 6 | { 7 | 8 | public IActionResult Index() 9 | { 10 | ViewBag.Name = User.Identity.Name; 11 | ViewBag.IsAuthenticated = User.Identity.IsAuthenticated; 12 | return View(); 13 | } 14 | 15 | public IActionResult AccessDenied() 16 | { 17 | return View(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Exercises/Authorization.Database/Controllers/LoginViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Authorization.Database.Controllers 4 | { 5 | public class LoginViewModel 6 | { 7 | [Required] 8 | public string UserName { get; set; } 9 | 10 | [Required] 11 | public string Password { get; set; } 12 | 13 | [Required] 14 | public string ReturnUrl { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /Exercises/Authorization.Database/Data/ApplicationDbContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Authorization.Database.Entities; 3 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore; 5 | 6 | namespace Authorization.Database.Data 7 | { 8 | /// 9 | /// // Calabonga: update summary (2020-04-28 04:56 ApplicationDbContext) 10 | /// 11 | public class ApplicationDbContext: IdentityDbContext 12 | { 13 | public ApplicationDbContext(DbContextOptions options) 14 | : base(options) 15 | { 16 | 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Exercises/Authorization.Database/Data/Databaseinitializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Security.Claims; 3 | using Authorization.Database.Entities; 4 | using Microsoft.AspNetCore.Identity; 5 | using Microsoft.Extensions.DependencyInjection; 6 | 7 | namespace Authorization.Database.Data 8 | { 9 | public static class Databaseinitializer 10 | { 11 | public static void Init(IServiceProvider scopeServiceProvider) 12 | { 13 | var userManager = scopeServiceProvider.GetService>(); 14 | 15 | 16 | var user = new ApplicationUser 17 | { 18 | UserName = "User", 19 | LastName = "LastName", 20 | FirstName = "FirstName" 21 | }; 22 | 23 | var result = userManager.CreateAsync(user, "123qwe").GetAwaiter().GetResult(); 24 | if (result.Succeeded) 25 | { 26 | userManager.AddClaimAsync(user, new Claim(ClaimTypes.Role, "Administrator")).GetAwaiter().GetResult(); 27 | } 28 | 29 | 30 | //context.Users.Add(user); 31 | //context.SaveChanges(); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Exercises/Authorization.Database/Entities/ApplicationRole.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.AspNetCore.Identity; 3 | 4 | namespace Authorization.Database.Entities 5 | { 6 | public class ApplicationRole: IdentityRole 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /Exercises/Authorization.Database/Entities/ApplicationUser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.AspNetCore.Identity; 3 | 4 | namespace Authorization.Database.Entities 5 | { 6 | /// 7 | /// // Calabonga: update summary (2020-04-28 04:54 ApplicationUser) 8 | /// 9 | public class ApplicationUser: IdentityUser 10 | { 11 | public string FirstName { get; set; } 12 | 13 | public string LastName { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Exercises/Authorization.Database/Program.cs: -------------------------------------------------------------------------------- 1 | using Authorization.Database.Data; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Microsoft.Extensions.Hosting; 5 | 6 | namespace Authorization.Database 7 | { 8 | public class Program 9 | { 10 | public static void Main(string[] args) 11 | { 12 | var host = CreateHostBuilder(args).Build(); 13 | using (var scope = host.Services.CreateScope()) 14 | { 15 | Databaseinitializer.Init(scope.ServiceProvider); 16 | } 17 | host.Run(); 18 | } 19 | 20 | public static IHostBuilder CreateHostBuilder(string[] args) => 21 | Host.CreateDefaultBuilder(args) 22 | .ConfigureWebHostDefaults(webBuilder => 23 | { 24 | webBuilder.UseStartup(); 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Exercises/Authorization.Database/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Authorization.Database": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "launchUrl": "home/index", 7 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 8 | "environmentVariables": { 9 | "ASPNETCORE_ENVIRONMENT": "Development" 10 | } 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Exercises/Authorization.Database/Views/Admin/Administrator.cshtml: -------------------------------------------------------------------------------- 1 | 

Administrator

2 | 3 | 4 | -------------------------------------------------------------------------------- /Exercises/Authorization.Database/Views/Admin/Index.cshtml: -------------------------------------------------------------------------------- 1 | 

Secured Zone

2 | 3 | 4 | -------------------------------------------------------------------------------- /Exercises/Authorization.Database/Views/Admin/Login.cshtml: -------------------------------------------------------------------------------- 1 | @model Authorization.Database.Controllers.LoginViewModel 2 |

Login

3 | 4 |

5 | [Home] 6 |

7 | 8 |
9 |
10 | 11 | 12 |
13 | 14 | 15 | 16 |
17 |
18 | 19 | 20 | 21 |
22 | 23 |

24 | 25 |

26 |
-------------------------------------------------------------------------------- /Exercises/Authorization.Database/Views/Admin/Manager.cshtml: -------------------------------------------------------------------------------- 1 | 

Manager

2 | 3 | 4 | -------------------------------------------------------------------------------- /Exercises/Authorization.Database/Views/Home/AccessDenied.cshtml: -------------------------------------------------------------------------------- 1 | 

AccessDenied

2 | 3 | 4 | -------------------------------------------------------------------------------- /Exercises/Authorization.Database/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | 

Home

2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Exercises/Authorization.Database/Views/Shared/_Menu.cshtml: -------------------------------------------------------------------------------- 1 | [Home] 2 | [Secured Zone] 3 | @if (User.Identity.IsAuthenticated) 4 | { 5 | [Administrator] 6 | [Manager] 7 | [Log Off] 8 | } 9 | -------------------------------------------------------------------------------- /Exercises/Authorization.Database/Views/Shared/_UserInfo.cshtml: -------------------------------------------------------------------------------- 1 | 

2 | IsAuthenticated : @User.Identity.IsAuthenticated 3 |

4 | 5 |

6 | Name : @User.Identity.Name 7 |

-------------------------------------------------------------------------------- /Exercises/Authorization.Database/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers -------------------------------------------------------------------------------- /Exercises/Authorization.Database/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Exercises/Authorization.Database/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/Authorization.FacebookDemo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/Controllers/ExternalLoginViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Authorization.FacebookDemo.Controllers 4 | { 5 | public class ExternalLoginViewModel 6 | { 7 | [Required] 8 | public string UserName { get; set; } 9 | 10 | [Required] 11 | public string ReturnUrl { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | 3 | namespace Authorization.FacebookDemo.Controllers 4 | { 5 | public class HomeController: Controller 6 | { 7 | 8 | public IActionResult Index() 9 | { 10 | ViewBag.Name = User.Identity.Name; 11 | ViewBag.IsAuthenticated = User.Identity.IsAuthenticated; 12 | return View(); 13 | } 14 | 15 | public IActionResult AccessDenied() 16 | { 17 | return View(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/Controllers/LoginViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.DataAnnotations; 3 | using Microsoft.AspNetCore.Authentication; 4 | 5 | namespace Authorization.FacebookDemo.Controllers 6 | { 7 | public class LoginViewModel 8 | { 9 | [Required] 10 | public string UserName { get; set; } 11 | 12 | [Required] 13 | public string Password { get; set; } 14 | 15 | [Required] 16 | public string ReturnUrl { get; set; } 17 | 18 | public IEnumerable ExternalProviders { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/Data/ApplicationDbContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Authorization.FacebookDemo.Entities; 3 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore; 5 | 6 | namespace Authorization.FacebookDemo.Data 7 | { 8 | /// 9 | /// // Calabonga: update summary (2020-04-28 04:56 ApplicationDbContext) 10 | /// 11 | public class ApplicationDbContext: IdentityDbContext 12 | { 13 | public ApplicationDbContext(DbContextOptions options) 14 | : base(options) 15 | { 16 | 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/Data/Databaseinitializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Security.Claims; 3 | using Authorization.FacebookDemo.Entities; 4 | using Microsoft.AspNetCore.Identity; 5 | using Microsoft.Extensions.DependencyInjection; 6 | 7 | namespace Authorization.FacebookDemo.Data 8 | { 9 | public static class Databaseinitializer 10 | { 11 | public static void Init(IServiceProvider scopeServiceProvider) 12 | { 13 | var userManager = scopeServiceProvider.GetService>(); 14 | 15 | 16 | var user = new ApplicationUser 17 | { 18 | UserName = "User", 19 | LastName = "LastName", 20 | FirstName = "FirstName" 21 | }; 22 | 23 | var result = userManager.CreateAsync(user, "123qwe").GetAwaiter().GetResult(); 24 | if (result.Succeeded) 25 | { 26 | userManager.AddClaimAsync(user, new Claim(ClaimTypes.Role, "Administrator")).GetAwaiter().GetResult(); 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/Entities/ApplicationRole.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.AspNetCore.Identity; 3 | 4 | namespace Authorization.FacebookDemo.Entities 5 | { 6 | public class ApplicationRole: IdentityRole 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/Entities/ApplicationUser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.AspNetCore.Identity; 3 | 4 | namespace Authorization.FacebookDemo.Entities 5 | { 6 | /// 7 | /// // Calabonga: update summary (2020-04-28 04:54 ApplicationUser) 8 | /// 9 | public class ApplicationUser: IdentityUser 10 | { 11 | public ApplicationUser() 12 | { 13 | 14 | } 15 | 16 | public ApplicationUser(string username):base(username) 17 | { 18 | 19 | } 20 | public string FirstName { get; set; } 21 | 22 | public string LastName { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/Program.cs: -------------------------------------------------------------------------------- 1 | using Authorization.FacebookDemo.Data; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Microsoft.Extensions.Hosting; 5 | 6 | namespace Authorization.FacebookDemo 7 | { 8 | public class Program 9 | { 10 | public static void Main(string[] args) 11 | { 12 | var host = CreateHostBuilder(args).Build(); 13 | using (var scope = host.Services.CreateScope()) 14 | { 15 | Databaseinitializer.Init(scope.ServiceProvider); 16 | } 17 | host.Run(); 18 | } 19 | 20 | public static IHostBuilder CreateHostBuilder(string[] args) => 21 | Host.CreateDefaultBuilder(args) 22 | .ConfigureWebHostDefaults(webBuilder => 23 | { 24 | webBuilder.UseStartup(); 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Authorization.FacebookDemo": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "launchUrl": "home/index", 7 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 8 | "environmentVariables": { 9 | "ASPNETCORE_ENVIRONMENT": "Development" 10 | } 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/Views/Admin/Administrator.cshtml: -------------------------------------------------------------------------------- 1 | 

Administrator

2 | 3 | 4 | -------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/Views/Admin/Index.cshtml: -------------------------------------------------------------------------------- 1 | 

Secured Zone

2 | 3 | 4 | -------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/Views/Admin/Login.cshtml: -------------------------------------------------------------------------------- 1 | @model Authorization.FacebookDemo.Controllers.LoginViewModel 2 |

Login

3 | 4 |

5 | [Home] 6 |

7 | 8 | 9 |

10 | Login with external provider 11 |

12 |
13 | @foreach (var provider in Model.ExternalProviders) 14 | { 15 | 20 | } 21 |
22 | 23 |
24 |

25 | You can use: User
26 | and password: 123qwe 27 |

28 |
29 |
30 |
31 | 32 | 33 |
34 | 35 | 36 | 37 |
38 |
39 | 40 | 41 | 42 |
43 | 44 |

45 | 46 |

47 |
-------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/Views/Admin/Manager.cshtml: -------------------------------------------------------------------------------- 1 | 

Manager

2 | 3 | 4 | -------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/Views/Admin/RegisterExternal.cshtml: -------------------------------------------------------------------------------- 1 | @model Authorization.FacebookDemo.Controllers.ExternalLoginViewModel 2 | 3 |

External registration

4 |
5 |
6 | 7 | 8 |
9 | 10 | 11 | 12 |
13 | 14 |

15 | 16 |

17 |
-------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/Views/Home/AccessDenied.cshtml: -------------------------------------------------------------------------------- 1 | 

AccessDenied

2 | 3 | 4 | -------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | 

Home

2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/Views/Shared/_Menu.cshtml: -------------------------------------------------------------------------------- 1 | [Home] 2 | [Secured Zone] 3 | @if (User.Identity.IsAuthenticated) 4 | { 5 | [Administrator] 6 | [Manager] 7 | [Log Off] 8 | } 9 | -------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/Views/Shared/_UserInfo.cshtml: -------------------------------------------------------------------------------- 1 | 

2 | IsAuthenticated : @User.Identity.IsAuthenticated 3 |

4 | 5 |

6 | Name : @User.Identity.Name 7 |

-------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers -------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Exercises/Authorization.FacebookDemo/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*", 10 | "Authentication": { 11 | "Facebook": { 12 | "AppId": "xxxxxxxxxxxxxxxxxxxx", 13 | "AppSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 14 | } 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/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 Authorization.IdentityServer.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 | public static string InvalidCredentialsErrorMessage = "Invalid username or password"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/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 Authorization.IdentityServer.Account 6 | { 7 | public class ExternalProvider 8 | { 9 | public string DisplayName { get; set; } 10 | public string AuthenticationScheme { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/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 Authorization.IdentityServer.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; } 14 | 15 | public string LogoutId { get; set; } 16 | public bool TriggerExternalSignout => ExternalAuthenticationScheme != null; 17 | public string ExternalAuthenticationScheme { get; set; } 18 | } 19 | } -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/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 Authorization.IdentityServer.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 | } -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/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 Authorization.IdentityServer.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; } = Enumerable.Empty(); 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 | } -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/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 Authorization.IdentityServer.Account 6 | { 7 | public class LogoutInputModel 8 | { 9 | public string LogoutId { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/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 Authorization.IdentityServer.Account 6 | { 7 | public class LogoutViewModel : LogoutInputModel 8 | { 9 | public bool ShowLogoutPrompt { get; set; } = true; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/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 Authorization.IdentityServer.Account 7 | { 8 | public class RedirectViewModel 9 | { 10 | public string RedirectUrl { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Authorization.IdentityServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | all 20 | runtime; build; native; contentfiles; analyzers; buildtransitive 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/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 Authorization.IdentityServer.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 | public string Description { get; set; } 16 | } 17 | } -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/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 Authorization.IdentityServer.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 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/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 Authorization.IdentityServer.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 ApiScopes { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/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 | using IdentityServer4.Models; 6 | 7 | namespace Authorization.IdentityServer.Consent 8 | { 9 | public class ProcessConsentResult 10 | { 11 | public bool IsRedirect => RedirectUri != null; 12 | public string RedirectUri { get; set; } 13 | public Client Client { get; set; } 14 | 15 | public bool ShowView => ViewModel != null; 16 | public ConsentViewModel ViewModel { get; set; } 17 | 18 | public bool HasValidationError => ValidationError != null; 19 | public string ValidationError { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/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 Authorization.IdentityServer.Consent 6 | { 7 | public class ScopeViewModel 8 | { 9 | public string Value { 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 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Data/ApplicationDbContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace Authorization.IdentityServer.Data 5 | { 6 | /// 7 | /// // Calabonga: update summary (2020-04-28 04:56 ApplicationDbContext) 8 | /// 9 | public class ApplicationDbContext: IdentityDbContext 10 | { 11 | public ApplicationDbContext(DbContextOptions options) 12 | : base(options) 13 | { 14 | 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Data/migrations.txt: -------------------------------------------------------------------------------- 1 | dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb 2 | dotnet ef migrations add InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb 3 | 4 | Add-Migration Initial -Context ApplicationDbContext -OutputDir Data/ApplicationDb 5 | Update-Database -Context ApplicationDbContext 6 | 7 | Add-Migration PersistedGrantDbMigration -Context PersistedGrantDbContext -OutputDir Data/PersistedGrantDb 8 | Update-Database -Context PersistedGrantDbContext 9 | 10 | Add-Migration ConfigurationDbMigration -Context ConfigurationDbContext -OutputDir Data/ConfigurationDb 11 | Update-Database -Context ConfigurationDbContext -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Device/DeviceAuthorizationInputModel.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 Authorization.IdentityServer.Consent; 6 | 7 | namespace Authorization.IdentityServer.Device 8 | { 9 | public class DeviceAuthorizationInputModel : ConsentInputModel 10 | { 11 | public string UserCode { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Device/DeviceAuthorizationViewModel.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 Authorization.IdentityServer.Consent; 6 | 7 | namespace Authorization.IdentityServer.Device 8 | { 9 | public class DeviceAuthorizationViewModel : ConsentViewModel 10 | { 11 | public string UserCode { get; set; } 12 | public bool ConfirmUserCode { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/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 Authorization.IdentityServer.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 | } -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/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 Authorization.IdentityServer.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 | } -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Authorization.IdentityServer.Account; 3 | using IdentityServer4.Models; 4 | using Microsoft.AspNetCore.Mvc; 5 | 6 | namespace Authorization.IdentityServer 7 | { 8 | public static class Extensions 9 | { 10 | /// 11 | /// Checks if the redirect URI is for a native client. 12 | /// 13 | /// 14 | public static bool IsNativeClient(this AuthorizationRequest context) 15 | { 16 | return !context.RedirectUri.StartsWith("https", StringComparison.Ordinal) 17 | && !context.RedirectUri.StartsWith("http", StringComparison.Ordinal); 18 | } 19 | 20 | public static IActionResult LoadingPage(this Controller controller, string viewName, string redirectUri) 21 | { 22 | controller.HttpContext.Response.StatusCode = 200; 23 | controller.HttpContext.Response.Headers["Location"] = ""; 24 | 25 | return controller.View(viewName, new RedirectViewModel { RedirectUrl = redirectUri }); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/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 Authorization.IdentityServer.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 string Description { get; set; } 22 | public DateTime Created { get; set; } 23 | public DateTime? Expires { get; set; } 24 | public IEnumerable IdentityGrantNames { get; set; } 25 | public IEnumerable ApiGrantNames { get; set; } 26 | } 27 | } -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/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 Authorization.IdentityServer.Home 8 | { 9 | public class ErrorViewModel 10 | { 11 | public ErrorViewModel() 12 | { 13 | } 14 | 15 | public ErrorViewModel(string error) 16 | { 17 | Error = new ErrorMessage { Error = error }; 18 | } 19 | 20 | public ErrorMessage Error { get; set; } 21 | } 22 | } -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Infrastructure/ProfileService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Security.Claims; 3 | using System.Threading.Tasks; 4 | using IdentityModel; 5 | using IdentityServer4.Models; 6 | using IdentityServer4.Services; 7 | 8 | namespace Authorization.IdentityServer.Infrastructure 9 | { 10 | public class ProfileService : IProfileService 11 | { 12 | /// 13 | /// This method is called whenever claims about the user are requested (e.g. during token creation or via the userinfo endpoint) 14 | /// 15 | /// The context. 16 | /// 17 | public Task GetProfileDataAsync(ProfileDataRequestContext context) 18 | { 19 | 20 | var claims = new List 21 | { 22 | new Claim(ClaimTypes.DateOfBirth, "01.01.2010") 23 | }; 24 | 25 | context.IssuedClaims.AddRange(claims); 26 | 27 | 28 | return Task.CompletedTask; 29 | } 30 | 31 | /// 32 | /// This method gets called whenever identity server needs to determine if the user is valid or active (e.g. if the user's account has been deactivated since they logged in). 33 | /// (e.g. during token issuance or validation). 34 | /// 35 | /// The context. 36 | /// 37 | public Task IsActiveAsync(IsActiveContext context) 38 | { 39 | context.IsActive = true; 40 | return Task.CompletedTask; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Program.cs: -------------------------------------------------------------------------------- 1 | using Authorization.IdentityServer.Data; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Microsoft.Extensions.Hosting; 5 | 6 | namespace Authorization.IdentityServer 7 | { 8 | public class Program 9 | { 10 | public static void Main(string[] args) 11 | { 12 | var host = CreateHostBuilder(args).Build(); 13 | using (var scope = host.Services.CreateScope()) 14 | { 15 | DatabaseInitializer.Init(scope.ServiceProvider); 16 | } 17 | host.Run(); 18 | } 19 | 20 | public static IHostBuilder CreateHostBuilder(string[] args) => 21 | Host.CreateDefaultBuilder(args) 22 | .ConfigureWebHostDefaults(webBuilder => 23 | { 24 | webBuilder.UseStartup(); 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Authorization.IdentityServer": { 4 | "commandName": "Project", 5 | "launchBrowser": false, 6 | "applicationUrl": "https://localhost:10001;http://localhost:10000", 7 | "environmentVariables": { 8 | "ASPNETCORE_ENVIRONMENT": "Development" 9 | } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/ViewModels/LoginViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Authorization.IdentityServer.ViewModels 4 | { 5 | public class LoginViewModel 6 | { 7 | [Required] 8 | public string UserName { get; set; } = "User"; 9 | 10 | [Required] 11 | public string Password { get; set; } = "123qwe"; 12 | 13 | [Required] 14 | public string ReturnUrl { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Views/Account/AccessDenied.cshtml: -------------------------------------------------------------------------------- 1 |  2 |
3 |
4 |

Access Denied

5 |

You do not have access to that resource.

6 |
7 |
-------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Views/Account/LoggedOut.cshtml: -------------------------------------------------------------------------------- 1 | @model Authorization.IdentityServer.Account.LoggedOutViewModel 2 | 3 | @{ 4 | // set this so the layout rendering sees an anonymous user 5 | ViewData["signed-out"] = true; 6 | } 7 | 8 |
9 |

10 | Logout 11 | You are now logged out 12 |

13 | 14 | @if (Model.PostLogoutRedirectUri != null) 15 | { 16 |
17 | Click here to return to the 18 | @Model.ClientName application. 19 |
20 | } 21 | 22 | @if (Model.SignOutIframeUrl != null) 23 | { 24 | 25 | } 26 |
27 | 28 | @section scripts 29 | { 30 | @if (Model.AutomaticRedirectAfterSignOut) 31 | { 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Views/Account/Logout.cshtml: -------------------------------------------------------------------------------- 1 | @model Authorization.IdentityServer.Account.LogoutViewModel 2 | 3 |
4 |
5 |

Logout

6 |

Would you like to logut of IdentityServer?

7 |
8 | 9 |
10 | 11 |
12 | 13 |
14 |
15 |
16 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Views/Device/Success.cshtml: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

Success

5 |

You have successfully authorized the device

6 |
7 |
8 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Views/Device/UserCodeCapture.cshtml: -------------------------------------------------------------------------------- 1 | @model string 2 | 3 |
4 |
5 |

User Code

6 |

Please enter the code displayed on your device.

7 |
8 | 9 | 10 | 11 |
12 |
13 |
14 |
15 | 16 | 17 |
18 | 19 | 20 |
21 |
22 |
23 |
24 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @using System.Diagnostics 2 | 3 | @{ 4 | var version = FileVersionInfo.GetVersionInfo(typeof(IdentityServer4.Hosting.IdentityServerMiddleware).Assembly.Location).ProductVersion.Split('+').First(); 5 | } 6 | 7 |
8 |

9 | 10 | Welcome to IdentityServer4 11 | (version @version) 12 |

13 | 14 |
    15 |
  • 16 | IdentityServer publishes a 17 | discovery document 18 | where you can find metadata and links to all the endpoints, key material, etc. 19 |
  • 20 |
  • 21 | Click here to see the claims for your current session. 22 |
  • 23 |
  • 24 | Click here to manage your stored grants. 25 |
  • 26 |
  • 27 | Here are links to the 28 | source code repository, 29 | and ready to use samples. 30 |
  • 31 |
32 |
33 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model Authorization.IdentityServer.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 |
11 |

Error

12 |
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 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Views/Shared/Redirect.cshtml: -------------------------------------------------------------------------------- 1 | @model Authorization.IdentityServer.Account.RedirectViewModel 2 | 3 |
4 |
5 |

You are now being returned to the application

6 |

Once complete, you may close this tab.

7 |
8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | IdentityServer4 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | @RenderBody() 21 |
22 | 23 | 24 | 25 | 26 | @RenderSection("scripts", required: false) 27 | 28 | 29 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Views/Shared/_Nav.cshtml: -------------------------------------------------------------------------------- 1 | @using IdentityServer4.Extensions 2 | 3 | @{ 4 | string name = null; 5 | if (!true.Equals(ViewData["signed-out"])) 6 | { 7 | name = Context.User?.GetDisplayName(); 8 | } 9 | } 10 | 11 | 34 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Views/Shared/_ScopeListItem.cshtml: -------------------------------------------------------------------------------- 1 | @model Authorization.IdentityServer.Consent.ScopeViewModel 2 | 3 |
  • 4 | 24 | @if (Model.Required) 25 | { 26 | (required) 27 | } 28 | @if (Model.Description != null) 29 | { 30 | 33 | } 34 |
  • -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Views/Shared/_ValidationSummary.cshtml: -------------------------------------------------------------------------------- 1 | @if (ViewContext.ModelState.IsValid == false) 2 | { 3 |
    4 | Error 5 |
    6 |
    7 | } -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 2 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "ApplicationDbContext": "Server=localhost;Database=IdentityServerUsers;User ID=sa;Password=8jkGh47hnDw89Haq8LN2;MultipleActiveResultSets=true" 4 | }, 5 | "Logging": { 6 | "LogLevel": { 7 | "Default": "Information", 8 | "Microsoft": "Warning", 9 | "Microsoft.Hosting.Lifetime": "Information" 10 | } 11 | }, 12 | "AllowedHosts": "*" 13 | } 14 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/tempkey.jwk: -------------------------------------------------------------------------------- 1 | {"alg":"RS256","d":"Hy7ErCIPLFmOJ1vcPvD7cifaAU7Fd2Hsk6G32QZqm0PDa0mdBKEhVK4D4czb_XSzXnRIO4cWug-ycwohhDk_svypqH1dc_42AKGzrWfBcbOcnaRLiCrbBgCPUdLMtn6w5EBIH3xOekCtLiT4q8V7w9-xK4odEWf94UU5KS8TQ4G2Svy-4hS7Wezry7Yj7Z8Ggw7wYxgN7F61jPiS_AexRXsngemP6Cmet4tYNsF02dCTZDAdFCewRkPp3qhxslFkLCW1C3PNm6pAOmCqVRcjOfBJ6zffAMeHIXT4ZrNYu0BqePywJwvHveAdGLgshpt-chQifNOv57R9MeluaZiFJQ","dp":"LMNkfk4KSSxx97qjr6Rt9Rhlb-GdjOOibmpo3euQc66WUe-WPHmIaopufG_2EFJAwqKqx8qR344zWE5MBxq68tsbvgmxDd44jzMo9ifmxAaBxt5iMUecFXuDN7V7qZUtiWDwR2cEvBwuBNDPcn35_JAXIS-CpdVH89T5DrlmU5M","dq":"ugWiAiBb4b4kYSbHBXBGY0YeUJsSxnK42Yr9lziGBIBIl_2FPOpuOorUUzjOu34Iqg8L0BVtW6TkfrbgTjQmbX7uppL1d8AwKElN137TgSxc1PILo118gmES2QuEDho1azwh_RBUDAknGIOl7-6r677-mhX8NR5RYt_I2SzfGQs","e":"AQAB","kid":"A915390BC608EEC9B2455F9345CF91D8","kty":"RSA","n":"0V2m9RUlmADnqMUcRG6HrMpD9TcEl_6imDprcc4bX1gdI6tZC-J3sbjVy9P8Y5M7l2X2L6mdkx4LCNqJVTsjs21bRflI0Kba29NRTlMb3WiFr0w4PhAVAQMM_gk-87yHTXqD6jDH6l3t-jvsZt2av2OcUWOm0PNdvdUarvBoIsHJ78cwXnGDcQVqL54FwtaosJGtY4Wpw5KEj2TaXTduXbDFI5QdH0TczqLbFK5T5-4BcMuY7SSMGHHRvSXJAbjr-aXjg-9Xr5c4A9W0uiMJ1u27WqOzi1y5WwiDxaJ_fq5NykFZPW5FYmykD3_3IOHOEqeYUhRZXpYmdY8GQEQtUQ","p":"-Xsu89eFBdQiqZsaPVoZgTdJe09BFUuuctYTeFXT4F5EPYWFyAttWukZE6smNqanyIQic3T3RdHds1weVcrhiLLWHdtcthK7Y2uHPt7R6P6UosKbvT9F7dWmVPbHAZBii7C0RIS3YE-jtumak9pkEbkQmF1C7h_0Wu8aiB6Wt48","q":"1tYhlvYwJQBbYHE3FC9G8kiX3GvoBmmozHedzx3Y9tkYa68guNn_dDpoFXXrXexXNkFpnjXvGw4beMST8BYbpLLKY_xRqncRztxrmyGlGSidZPqzsIROMDt_-vCk5w74fsqNPBGZUQgxaiz4XpzbBe1qS2K65alCirVOUvzbXR8","qi":"7MiFWqYJa9n5ZpmijNT8g1HRkTFC1ovjPZ29cyaq5JKjyT_ZCD7e4YVmZMWNrhC_lb14ImBQRghucKcuEqzgrcpeyOkR2CZBoHFiicoBu0S3Vy2aDtZiuU5CgUHAmK4Jmng2jKUeXI0Xv-EBiFUhGc0QLWzk1GkF9db-b5rJ6zw"} -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | .body-container { 2 | margin-top: 60px; 3 | padding-bottom: 40px; } 4 | 5 | .welcome-page li { 6 | list-style: none; 7 | padding: 4px; } 8 | 9 | .logged-out-page iframe { 10 | display: none; 11 | width: 0; 12 | height: 0; } 13 | 14 | .grants-page .card { 15 | margin-top: 20px; 16 | border-bottom: 1px solid lightgray; } 17 | .grants-page .card .card-title { 18 | font-size: 120%; 19 | font-weight: bold; } 20 | .grants-page .card .card-title img { 21 | width: 100px; 22 | height: 100px; } 23 | .grants-page .card label { 24 | font-weight: bold; } 25 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/wwwroot/css/site.min.css: -------------------------------------------------------------------------------- 1 | .body-container{margin-top:60px;padding-bottom:40px;}.welcome-page li{list-style:none;padding:4px;}.logged-out-page iframe{display:none;width:0;height:0;}.grants-page .card{margin-top:20px;border-bottom:1px solid #d3d3d3;}.grants-page .card .card-title{font-size:120%;font-weight:bold;}.grants-page .card .card-title img{width:100px;height:100px;}.grants-page .card label{font-weight:bold;} -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/wwwroot/css/site.scss: -------------------------------------------------------------------------------- 1 | .body-container { 2 | margin-top: 60px; 3 | padding-bottom:40px; 4 | } 5 | 6 | .welcome-page { 7 | li { 8 | list-style: none; 9 | padding: 4px; 10 | } 11 | } 12 | 13 | .logged-out-page { 14 | iframe { 15 | display: none; 16 | width: 0; 17 | height: 0; 18 | } 19 | } 20 | 21 | .grants-page { 22 | .card { 23 | margin-top: 20px; 24 | border-bottom: 1px solid lightgray; 25 | 26 | .card-title { 27 | img { 28 | width: 100px; 29 | height: 100px; 30 | } 31 | 32 | font-size: 120%; 33 | font-weight: bold; 34 | } 35 | 36 | label { 37 | font-weight: bold; 38 | } 39 | } 40 | } 41 | 42 | 43 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Calabonga/Authorization-Exercises/84e59137ce28af565768a364267dbc1f0c3782dd/Exercises/Authorization.IdentityServer/wwwroot/favicon.ico -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/wwwroot/icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Calabonga/Authorization-Exercises/84e59137ce28af565768a364267dbc1f0c3782dd/Exercises/Authorization.IdentityServer/wwwroot/icon.jpg -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/wwwroot/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Calabonga/Authorization-Exercises/84e59137ce28af565768a364267dbc1f0c3782dd/Exercises/Authorization.IdentityServer/wwwroot/icon.png -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/wwwroot/js/signin-redirect.js: -------------------------------------------------------------------------------- 1 | window.location.href = document.querySelector("meta[http-equiv=refresh]").getAttribute("data-url"); 2 | -------------------------------------------------------------------------------- /Exercises/Authorization.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 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/wwwroot/lib/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2019 Twitter, Inc. 4 | Copyright (c) 2011-2019 The Bootstrap Authors 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 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Calabonga/Authorization-Exercises/84e59137ce28af565768a364267dbc1f0c3782dd/Exercises/Authorization.IdentityServer/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Calabonga/Authorization-Exercises/84e59137ce28af565768a364267dbc1f0c3782dd/Exercises/Authorization.IdentityServer/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Calabonga/Authorization-Exercises/84e59137ce28af565768a364267dbc1f0c3782dd/Exercises/Authorization.IdentityServer/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Calabonga/Authorization-Exercises/84e59137ce28af565768a364267dbc1f0c3782dd/Exercises/Authorization.IdentityServer/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/wwwroot/lib/bootstrap/scss/_alert.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Base styles 3 | // 4 | 5 | .alert { 6 | position: relative; 7 | padding: $alert-padding-y $alert-padding-x; 8 | margin-bottom: $alert-margin-bottom; 9 | border: $alert-border-width solid transparent; 10 | @include border-radius($alert-border-radius); 11 | } 12 | 13 | // Headings for larger alerts 14 | .alert-heading { 15 | // Specified to prevent conflicts of changing $headings-color 16 | color: inherit; 17 | } 18 | 19 | // Provide class for links that match alerts 20 | .alert-link { 21 | font-weight: $alert-link-font-weight; 22 | } 23 | 24 | 25 | // Dismissible alerts 26 | // 27 | // Expand the right padding and account for the close button's positioning. 28 | 29 | .alert-dismissible { 30 | padding-right: $close-font-size + $alert-padding-x * 2; 31 | 32 | // Adjust close link position 33 | .close { 34 | position: absolute; 35 | top: 0; 36 | right: 0; 37 | padding: $alert-padding-y $alert-padding-x; 38 | color: inherit; 39 | } 40 | } 41 | 42 | 43 | // Alternate styles 44 | // 45 | // Generate contextual modifier classes for colorizing the alert. 46 | 47 | @each $color, $value in $theme-colors { 48 | .alert-#{$color} { 49 | @include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level)); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/wwwroot/lib/bootstrap/scss/_badge.scss: -------------------------------------------------------------------------------- 1 | // Base class 2 | // 3 | // Requires one of the contextual, color modifier classes for `color` and 4 | // `background-color`. 5 | 6 | .badge { 7 | display: inline-block; 8 | padding: $badge-padding-y $badge-padding-x; 9 | @include font-size($badge-font-size); 10 | font-weight: $badge-font-weight; 11 | line-height: 1; 12 | text-align: center; 13 | white-space: nowrap; 14 | vertical-align: baseline; 15 | @include border-radius($badge-border-radius); 16 | @include transition($badge-transition); 17 | 18 | @at-root a#{&} { 19 | @include hover-focus() { 20 | text-decoration: none; 21 | } 22 | } 23 | 24 | // Empty badges collapse automatically 25 | &:empty { 26 | display: none; 27 | } 28 | } 29 | 30 | // Quick fix for badges in buttons 31 | .btn .badge { 32 | position: relative; 33 | top: -1px; 34 | } 35 | 36 | // Pill badges 37 | // 38 | // Make them extra rounded with a modifier to replace v3's badges. 39 | 40 | .badge-pill { 41 | padding-right: $badge-pill-padding-x; 42 | padding-left: $badge-pill-padding-x; 43 | @include border-radius($badge-pill-border-radius); 44 | } 45 | 46 | // Colors 47 | // 48 | // Contextual variations (linked badges get darker on :hover). 49 | 50 | @each $color, $value in $theme-colors { 51 | .badge-#{$color} { 52 | @include badge-variant($value); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Exercises/Authorization.IdentityServer/wwwroot/lib/bootstrap/scss/_breadcrumb.scss: -------------------------------------------------------------------------------- 1 | .breadcrumb { 2 | display: flex; 3 | flex-wrap: wrap; 4 | padding: $breadcrumb-padding-y $breadcrumb-padding-x; 5 | margin-bottom: $breadcrumb-margin-bottom; 6 | @include font-size($breadcrumb-font-size); 7 | list-style: none; 8 | background-color: $breadcrumb-bg; 9 | @include border-radius($breadcrumb-border-radius); 10 | } 11 | 12 | .breadcrumb-item { 13 | // The separator between breadcrumbs (by default, a forward-slash: "/") 14 | + .breadcrumb-item { 15 | padding-left: $breadcrumb-item-padding; 16 | 17 | &::before { 18 | display: inline-block; // Suppress underlining of the separator in modern browsers 19 | padding-right: $breadcrumb-item-padding; 20 | color: $breadcrumb-divider-color; 21 | content: escape-svg($breadcrumb-divider); 22 | } 23 | } 24 | 25 | // IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built 26 | // without `