1
0
mirror of https://git.teknik.io/Teknikode/Teknik.git synced 2023-08-02 14:16:22 +02:00

Fixed redirect due to unauthorized request.

This commit is contained in:
Uncled1023 2019-01-17 19:26:49 -08:00
parent 0073e99c6d
commit 2c07ba868f
3 changed files with 26 additions and 97 deletions

View File

@ -49,7 +49,7 @@ namespace Teknik.Areas.Users.Controllers
private readonly IHttpContextAccessor _httpContextAccessor;
private ISession _session => _httpContextAccessor.HttpContext.Session;
public LogoutSessionManager _logoutSessions { get; }
private readonly LogoutSessionManager _logoutSessions;
public UserController(ILogger<Logger> logger, Config config, TeknikEntities dbContext, LogoutSessionManager logoutSessions, IHttpContextAccessor httpContextAccessor) : base(logger, config, dbContext)
{
@ -83,87 +83,14 @@ namespace Teknik.Areas.Users.Controllers
[HttpGet]
public async Task Logout()
{
// these are the sub & sid to signout
//var sub = User.FindFirst("sub")?.Value;
//var sid = User.FindFirst("sid")?.Value;
await HttpContext.SignOutAsync("Cookies");
await HttpContext.SignOutAsync("oidc");
}
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> Logout(string logout_token)
{
Response.Headers.Add("Cache-Control", "no-cache, no-store");
Response.Headers.Add("Pragma", "no-cache");
try
{
var user = await ValidateLogoutToken(logout_token);
// these are the sub & sid to signout
var sub = user.FindFirst("sub")?.Value;
var sid = user.FindFirst("sid")?.Value;
_logoutSessions.Add(sub, sid);
return Ok();
}
catch { }
return BadRequest();
}
private async Task<ClaimsPrincipal> ValidateLogoutToken(string logoutToken)
{
var claims = await ValidateJwt(logoutToken);
if (claims.FindFirst("sub") == null && claims.FindFirst("sid") == null) throw new Exception("Invalid logout token");
var nonce = claims.FindFirstValue("nonce");
if (!String.IsNullOrWhiteSpace(nonce)) throw new Exception("Invalid logout token");
var eventsJson = claims.FindFirst("events")?.Value;
if (String.IsNullOrWhiteSpace(eventsJson)) throw new Exception("Invalid logout token");
var events = JObject.Parse(eventsJson);
var logoutEvent = events.TryGetValue("http://schemas.openid.net/event/backchannel-logout");
if (logoutEvent == null) throw new Exception("Invalid logout token");
return claims;
}
private async Task<ClaimsPrincipal> ValidateJwt(string jwt)
{
// read discovery document to find issuer and key material
var disco = await DiscoveryClient.GetAsync(_config.UserConfig.IdentityServerConfig.Authority);
var keys = new List<SecurityKey>();
foreach (var webKey in disco.KeySet.Keys)
{
var e = Base64Url.Decode(webKey.E);
var n = Base64Url.Decode(webKey.N);
var key = new RsaSecurityKey(new RSAParameters { Exponent = e, Modulus = n })
{
KeyId = webKey.Kid
};
keys.Add(key);
}
var parameters = new TokenValidationParameters
{
ValidIssuer = disco.Issuer,
ValidAudience = _config.UserConfig.IdentityServerConfig.ClientId,
IssuerSigningKeys = keys,
NameClaimType = JwtClaimTypes.Name,
RoleClaimType = JwtClaimTypes.Role
};
var handler = new JwtSecurityTokenHandler();
handler.InboundClaimTypeMap.Clear();
var user = handler.ValidateToken(jwt, parameters, out var _);
return user;
//_logoutSessions.Add(sub, sid);
}
[AllowAnonymous]

View File

@ -15,26 +15,29 @@ namespace Teknik.Security
{
public CookieEventHandler(LogoutSessionManager logoutSessions)
{
LogoutSessions = logoutSessions;
_LogoutSessions = logoutSessions;
}
public LogoutSessionManager LogoutSessions { get; }
private static LogoutSessionManager _LogoutSessions;
public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
public override async Task RedirectToAccessDenied(RedirectContext<CookieAuthenticationOptions> context)
{
if (context.Principal.Identity.IsAuthenticated)
{
var sub = context.Principal.FindFirst("sub")?.Value;
var sid = context.Principal.FindFirst("sid")?.Value;
if (LogoutSessions.IsLoggedOut(sub, sid))
{
context.RejectPrincipal();
await context.HttpContext.SignOutAsync();
// todo: if we have a refresh token, it should be revoked here.
}
}
context.Response.StatusCode = 403;
}
//public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
//{
// if (context.Principal.Identity.IsAuthenticated)
// {
// var sub = context.Principal.FindFirst("sub")?.Value;
// var sid = context.Principal.FindFirst("sid")?.Value;
// if (LogoutSessions.IsLoggedOut(sub, sid))
// {
// context.RejectPrincipal();
// await context.HttpContext.SignOutAsync();
// }
// }
//}
}
}

View File

@ -7,8 +7,7 @@ namespace Teknik.Security
{
public class LogoutSessionManager
{
// yes - that needs to be thread-safe, distributed etc (it's a sample)
List<Session> _sessions = new List<Session>();
private static List<Session> _sessions = new List<Session>();
public void Add(string sub, string sid)
{