Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public class Constants
public const string COOKIE_NAME = "multifactor";
public const string SESSION_EXPIRED_PASSWORD_USER_KEY = "multifactor:expired-password:user";
public const string SESSION_EXPIRED_PASSWORD_CIPHER_KEY = "multifactor:expired-password:cipher";
public const string PREAUTHENTICATION_AUTHN_SUCCEED_KEY = "multifactor:preauthentication-authn-succesd:user";
public const string CAPTCHA_TOKEN = "responseToken";
public const string PWD_RECOVERY_COOKIE = "PSession";

Expand Down
17 changes: 17 additions & 0 deletions Controllers/AccountController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ public async Task<ActionResult> Login(LoginModel model, SingleSignOnDto sso)
if (adValidationResult.IsAuthenticated)
{
var identity = adValidationResult.GetIdentity(model.UserName);

if (Configuration.Current.PreAuthnMode)
{
_applicationCache.SetPreauthenticationAuthn(
ApplicationCacheKeyFactory.CreatePreAuthenticationAuthnSucceedKey(identity),
true);
}

if (sso.HasSamlSession() && adValidationResult.IsBypass)
{
return ByPassSamlSession(identity, sso.SamlSessionId);
Expand Down Expand Up @@ -392,6 +400,15 @@ private ActionResult RedirectToCredValidationAfter2FA(string accessToken)
{
var handler = new JwtSecurityTokenHandler();
var token = handler.ReadJwtToken(accessToken);

var authCacheResult = _applicationCache.GetPreauthenticationAuthn(ApplicationCacheKeyFactory.CreatePreAuthenticationAuthnSucceedKey(token.Subject));
if (!authCacheResult.IsEmpty && authCacheResult.Value)
{
_applicationCache.Remove(ApplicationCacheKeyFactory.CreatePreAuthenticationAuthnSucceedKey(token.Subject));
_authService.SignIn(accessToken);
return RedirectToAction("Index", "Home");
}

var usernameClaims = token.Claims.FirstOrDefault(claim => claim.Type == MultiFactorClaims.RawUserName);

// for the password entry step
Expand Down
5 changes: 5 additions & 0 deletions Core/ApplicationCacheKeyFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,10 @@ public static string CreateExpiredPwdCipherKey(string identity)
{
return $"{Constants.SESSION_EXPIRED_PASSWORD_CIPHER_KEY}:{identity}";
}

public static string CreatePreAuthenticationAuthnSucceedKey(string identity)
{
return $"{Constants.PREAUTHENTICATION_AUTHN_SUCCEED_KEY}:{identity}";
}
}
}
9 changes: 5 additions & 4 deletions Services/API/DTO/UserProfileAuthenticatorsDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ public class UserProfileAuthenticatorsDto

public UserProfileAuthenticatorDto[] GetAuthenticators()
{
return TotpAuthenticators
.Concat(TelegramAuthenticators)
.Concat(MobileAppAuthenticators)
.Concat(PhoneAuthenticators)
return Enumerable.Empty<UserProfileAuthenticatorDto>()
.Concat(TotpAuthenticators ?? Enumerable.Empty<UserProfileAuthenticatorDto>())
.Concat(TelegramAuthenticators ?? Enumerable.Empty<UserProfileAuthenticatorDto>())
.Concat(MobileAppAuthenticators ?? Enumerable.Empty<UserProfileAuthenticatorDto>())
.Concat(PhoneAuthenticators ?? Enumerable.Empty<UserProfileAuthenticatorDto>())
.ToArray();
}
}
Expand Down
18 changes: 17 additions & 1 deletion Services/Caching/ApplicationCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,23 @@ public CachedItem<IdentityModel> GetIdentity(string key)
? new CachedItem<IdentityModel>(value)
: CachedItem<IdentityModel>.Empty;
}

public void SetPreauthenticationAuthn(string key, bool value)
{
var options = new MemoryCacheEntryOptions()
.SetAbsoluteExpiration(_config.PreauthenticationAuthnExpiration)
.SetSize(1);
_cache.Set(key, value, options);
}

public CachedItem<bool> GetPreauthenticationAuthn(string key)
{
if (string.IsNullOrWhiteSpace(key))
return CachedItem<bool>.Empty;
return _cache.TryGetValue(key, out bool value)
? new CachedItem<bool>(value)
: CachedItem<bool>.Empty;
}

public CachedItem<string> Get(string key)
{
return _cache.TryGetValue(key, out string value)
Expand Down
1 change: 1 addition & 0 deletions Services/Caching/ApplicationCacheConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ public class ApplicationCacheConfig
public TimeSpan AbsoluteExpiration { get; set; } = TimeSpan.FromMinutes(2);
public TimeSpan SupportInfoExpiration { get; set; } = TimeSpan.FromMinutes(60);
public TimeSpan SupportInfoEmptyExpiration { get; set; } = TimeSpan.FromMinutes(5);
public TimeSpan PreauthenticationAuthnExpiration { get; set; } = TimeSpan.FromMinutes(10);
}
}