-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3f4b37d
commit 1f6d439
Showing
475 changed files
with
33,885 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<PackageType>Template</PackageType> | ||
<PackageVersion>1.0</PackageVersion> | ||
<PackageId>TheIdServer.Duende.Template</PackageId> | ||
<Title>TheIdServer Duende IdentityServer Template</Title> | ||
<Authors>Olivier Lefebvre</Authors> | ||
<Description>Template to create a TheIdServer for Duende IdentityServer solution.</Description> | ||
<PackageTags>dotnet-new;templates;theidserver;duende-identityserver;oidc;ws-federation;oauth;identity;authentication;security;iam</PackageTags> | ||
<TargetFramework>net5.0</TargetFramework> | ||
|
||
<IncludeContentInPack>true</IncludeContentInPack> | ||
<IncludeBuildOutput>false</IncludeBuildOutput> | ||
<ContentTargetFolders>content</ContentTargetFolders> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<Content Include="TheIdServer.Duende\**\*" Exclude="TheIdServer.Duende\**\bin\**;TheIdServer\**\obj\**;TheIdServer.Duende\**\*.csproj.user;TheIdServer.Duende\**\.vs\**;TheIdServer.Duende\**\TIS.db;TheIdServer\**\update-dependencies.ps1;TheIdServer\**\update-dependencies.cmd;TheIdServer.Duende\TheIdServer.sln.licenseheader" /> | ||
<Compile Remove="**\*" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
{ | ||
"$schema": "http://json.schemastore.org/TIS.Duende", | ||
"author": "Olivier Lefebvre", | ||
"classifications": ["TheIdServer"], | ||
"name": "TheIdServer.Duende", | ||
"identity": "TheIdServer.Duende", | ||
"shortName": "tisduende", | ||
"tags": { | ||
"language": "C#" | ||
}, | ||
"sourceName": "TIS", | ||
"preferNameDirectory": true, | ||
"symbols": { | ||
"skipRestore": { | ||
"type": "parameter", | ||
"datatype": "bool", | ||
"description": "Skip restore packages", | ||
"defaultValue": "false" | ||
} | ||
}, | ||
"sources": [ | ||
{ | ||
"modifiers": [ | ||
{ | ||
"exclude": [ | ||
".vs/**", | ||
".git/**", | ||
"doc/**", | ||
"coverage/**", | ||
"ReportGenerator/**", | ||
"**/TestResults/**" | ||
] | ||
} | ||
] | ||
} | ||
], | ||
"primaryOutputs": [ | ||
{ | ||
"path": "TIS.sln" | ||
} | ||
], | ||
"postActions": [{ | ||
"condition": "(!skipRestore)", | ||
"description": "Restore NuGet packages required by this project.", | ||
"manualInstructions": [ | ||
{ "text": "Run 'dotnet restore'" } | ||
], | ||
"actionId": "210D431B-A78B-4D2F-B762-4ED3E3EA9025", | ||
"continueOnError": true | ||
}] | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
159 changes: 159 additions & 0 deletions
159
TheIdServer.Duende/src/TIS/Areas/Identity/Pages/Account/LoginWith2fa.cshtml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
// Copyright (c) 2021 @Olivier Lefebvre. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. | ||
using Aguacongas.TheIdServer.Models; | ||
using Duende.IdentityServer.Events; | ||
using Duende.IdentityServer.Services; | ||
using Duende.IdentityServer.Stores; | ||
using IdentityServerHost.Quickstart.UI; | ||
using Microsoft.AspNetCore.Authorization; | ||
using Microsoft.AspNetCore.Identity; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.RazorPages; | ||
using Microsoft.Extensions.Localization; | ||
using Microsoft.Extensions.Logging; | ||
using System; | ||
using System.ComponentModel.DataAnnotations; | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Threading.Tasks; | ||
using TIS.Quickstart.Account; | ||
|
||
namespace TIS.Areas.Identity.Pages.Account | ||
{ | ||
[AllowAnonymous] | ||
[SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Scafolded code")] | ||
public class LoginWith2faModel : PageModel | ||
{ | ||
private readonly SignInManager<ApplicationUser> _signInManager; | ||
private readonly IIdentityServerInteractionService _interaction; | ||
private readonly IEventService _events; | ||
private readonly IClientStore _clientStore; | ||
private readonly ILogger<LoginWith2faModel> _logger; | ||
private readonly IStringLocalizer _localizer; | ||
|
||
public LoginWith2faModel(SignInManager<ApplicationUser> signInManager, | ||
IIdentityServerInteractionService interaction, | ||
IEventService events, | ||
IClientStore clientStore, | ||
ILogger<LoginWith2faModel> logger, | ||
IStringLocalizer<LoginWith2faModel> localizer) | ||
{ | ||
_signInManager = signInManager; | ||
_interaction = interaction; | ||
_events = events; | ||
_clientStore = clientStore; | ||
_logger = logger; | ||
_localizer = localizer; | ||
} | ||
|
||
[BindProperty] | ||
public InputModel Input { get; set; } | ||
|
||
public bool RememberMe { get; set; } | ||
|
||
public string ReturnUrl { get; set; } | ||
|
||
public bool RedirectToReturnUrl { get; set; } | ||
|
||
public class InputModel | ||
{ | ||
[Required] | ||
[StringLength(7, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] | ||
[DataType(DataType.Text)] | ||
[Display(Name = "Authenticator code")] | ||
public string TwoFactorCode { get; set; } | ||
|
||
[Display(Name = "Remember this machine")] | ||
public bool RememberMachine { get; set; } | ||
} | ||
|
||
public async Task<IActionResult> OnGetAsync(bool rememberMe, string returnUrl = null) | ||
{ | ||
// Ensure the user has gone through the username & password screen first | ||
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); | ||
|
||
if (user == null) | ||
{ | ||
throw new InvalidOperationException($"Unable to load two-factor authentication user."); | ||
} | ||
|
||
ReturnUrl = returnUrl; | ||
RememberMe = rememberMe; | ||
|
||
return Page(); | ||
} | ||
|
||
public async Task<IActionResult> OnPostAsync(string userName, bool rememberMe, string returnUrl = null) | ||
{ | ||
if (!ModelState.IsValid) | ||
{ | ||
return Page(); | ||
} | ||
|
||
returnUrl = returnUrl ?? Url.Content("~/"); | ||
|
||
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); | ||
if (user == null) | ||
{ | ||
throw new InvalidOperationException($"Unable to load two-factor authentication user."); | ||
} | ||
|
||
var authenticatorCode = Input.TwoFactorCode.Replace(" ", string.Empty).Replace("-", string.Empty); | ||
|
||
var result = await _signInManager.TwoFactorAuthenticatorSignInAsync(authenticatorCode, rememberMe, Input.RememberMachine); | ||
|
||
if (result.Succeeded) | ||
{ | ||
_logger.LogInformation("User with ID '{UserId}' logged in with 2fa.", user.Id); | ||
|
||
return await OnSiginSuccesss(user, returnUrl); | ||
} | ||
else if (result.IsLockedOut) | ||
{ | ||
_logger.LogWarning("User with ID '{UserId}' account locked out.", user.Id); | ||
return RedirectToPage("./Lockout"); | ||
} | ||
else | ||
{ | ||
_logger.LogWarning("Invalid authenticator code entered for user with ID '{UserId}'.", user.Id); | ||
ModelState.AddModelError(string.Empty, _localizer["Invalid authenticator code."]); | ||
return Page(); | ||
} | ||
} | ||
|
||
private async Task<IActionResult> OnSiginSuccesss(ApplicationUser user, string returnUrl) | ||
{ | ||
var context = await _interaction.GetAuthorizationContextAsync(returnUrl).ConfigureAwait(false); | ||
|
||
await _events.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id, user.UserName, clientId: context?.Client?.ClientId)); | ||
|
||
if (context != null) | ||
{ | ||
if (context.IsNativeClient()) | ||
{ | ||
// if the client is PKCE then we assume it's native, so this change in how to | ||
// return the response is for better UX for the end user. | ||
RedirectToReturnUrl = true; | ||
ReturnUrl = returnUrl; | ||
|
||
return Page(); | ||
} | ||
|
||
// we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null | ||
return Redirect(returnUrl); | ||
} | ||
|
||
// request for a local page | ||
if (Url.IsLocalUrl(returnUrl)) | ||
{ | ||
return Redirect(returnUrl); | ||
} | ||
else if (string.IsNullOrEmpty(returnUrl)) | ||
{ | ||
return Redirect("~/"); | ||
} | ||
|
||
// user might have clicked on a malicious link - should be logged | ||
throw new InvalidReturnUrlException(); | ||
} | ||
} | ||
} |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Oops, something went wrong.