2
0
mirror of https://github.com/VinylDNS/vinyldns synced 2025-08-22 10:10:12 +00:00

Fix portal login redirect

With the release of `0.10.0` the redirect for OIDC authentication was not working.

- Re-enable redirect in `setOidcSession.scala.html`
- Add support for redirecting to requested page after login, rather than `/index`-purgatory
This commit is contained in:
Emerle, Ryan 2021-12-18 11:40:00 -05:00
parent 3b63751278
commit a030fd3567
No known key found for this signature in database
GPG Key ID: C0D34C592AED41CE
8 changed files with 41 additions and 24 deletions

View File

@ -44,7 +44,7 @@ class LegacyApiAction @Inject() (
override val logger = LoggerFactory.getLogger(classOf[LegacyApiAction]) override val logger = LoggerFactory.getLogger(classOf[LegacyApiAction])
implicit val executionContext: ExecutionContext = scala.concurrent.ExecutionContext.global implicit val executionContext: ExecutionContext = scala.concurrent.ExecutionContext.global
def notLoggedInResult: Future[Result] = def notLoggedInResult(requestURI: String): Future[Result] =
Future.successful( Future.successful(
Unauthorized("You are not logged in. Please login to continue.").withHeaders(cacheHeaders: _*) Unauthorized("You are not logged in. Please login to continue.").withHeaders(cacheHeaders: _*)
) )

View File

@ -43,9 +43,9 @@ class LegacyFrontendAction(
override val logger = LoggerFactory.getLogger(classOf[LegacyFrontendAction]) override val logger = LoggerFactory.getLogger(classOf[LegacyFrontendAction])
implicit val executionContext: ExecutionContext = scala.concurrent.ExecutionContext.global implicit val executionContext: ExecutionContext = scala.concurrent.ExecutionContext.global
def notLoggedInResult: Future[Result] = def notLoggedInResult(requestURI: String): Future[Result] =
Future.successful( Future.successful(
Redirect("/login") Redirect(s"/login?target=$requestURI")
.flashing(VinylDNS.Alerts.error("You are not logged in. Please login to continue.")) .flashing(VinylDNS.Alerts.error("You are not logged in. Please login to continue."))
.withNewSession .withNewSession
.withHeaders(cacheHeaders: _*) .withHeaders(cacheHeaders: _*)

View File

@ -45,10 +45,10 @@ class LegacySecuritySupport @Inject() (
implicit request => implicit request =>
if (oidcAuthenticator.oidcEnabled) { if (oidcAuthenticator.oidcEnabled) {
request.session.get(VinylDNS.ID_TOKEN) match { request.session.get(VinylDNS.ID_TOKEN) match {
case Some(_) => Redirect("/index") case Some(_) => Redirect(request.getQueryString("target").getOrElse("/index"))
case None => case None =>
logger.info(s"No ${VinylDNS.ID_TOKEN} in session; Initializing oidc login") logger.info(s"No ${VinylDNS.ID_TOKEN} in session; Initializing oidc login")
Redirect(oidcAuthenticator.getCodeCall.toString, 302) Redirect(oidcAuthenticator.getCodeCall(request.uri).toString, 302)
} }
} else { } else {
request.session.get("username") match { request.session.get("username") match {

View File

@ -34,7 +34,7 @@ trait VinylDnsAction extends ActionFunction[Request, UserRequest] {
implicit val executionContext: ExecutionContext implicit val executionContext: ExecutionContext
def notLoggedInResult: Future[Result] def notLoggedInResult(requestURI: String): Future[Result]
def cantFindAccountResult(un: String): Future[Result] def cantFindAccountResult(un: String): Future[Result]
@ -62,7 +62,7 @@ trait VinylDnsAction extends ActionFunction[Request, UserRequest] {
userName match { userName match {
case None => case None =>
logger.info("User is not logged in or token expired; redirecting to login screen") logger.info("User is not logged in or token expired; redirecting to login screen")
notLoggedInResult notLoggedInResult(request.uri)
case Some(un) => case Some(un) =>
// user name in session, let's get it from the repo // user name in session, let's get it from the repo

View File

@ -105,10 +105,10 @@ class OidcAuthenticator @Inject() (wsClient: WSClient, configuration: Configurat
processor processor
} }
def getCodeCall: Uri = { def getCodeCall(requestURI: String): Uri = {
val nonce = new Nonce() val nonce = new Nonce()
val loginId = UUID.randomUUID().toString val loginId = UUID.randomUUID().toString
val redirectUri = s"${oidcInfo.redirectUri}/callback/$loginId" val redirectUri = s"${oidcInfo.redirectUri}/callback/${loginId}:${java.util.Base64.getEncoder.encodeToString(requestURI.getBytes)}"
val query = Query( val query = Query(
"client_id" -> oidcInfo.clientId, "client_id" -> oidcInfo.clientId,
@ -247,7 +247,7 @@ class OidcAuthenticator @Inject() (wsClient: WSClient, configuration: Configurat
implicit executionContext: ExecutionContext implicit executionContext: ExecutionContext
): EitherT[IO, ErrorResponse, JWTClaimsSet] = ): EitherT[IO, ErrorResponse, JWTClaimsSet] =
EitherT { EitherT {
val redirectUriString = s"${oidcInfo.redirectUri}/callback/$loginId" val redirectUriString = s"${oidcInfo.redirectUri}/callback/${loginId}"
val redirectUri = new URI(redirectUriString) val redirectUri = new URI(redirectUriString)
val codeGrant = new AuthorizationCodeGrant(code, redirectUri) val codeGrant = new AuthorizationCodeGrant(code, redirectUri)
val request = new TokenRequest(tokenEndpoint, clientAuth, codeGrant) val request = new TokenRequest(tokenEndpoint, clientAuth, codeGrant)

View File

@ -42,7 +42,7 @@ import vinyldns.core.logging.RequestTracing
import scala.collection.JavaConverters._ import scala.collection.JavaConverters._
import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future import scala.concurrent.Future
import scala.util.Try import scala.util.{Failure, Success, Try}
object VinylDNS { object VinylDNS {
@ -157,14 +157,24 @@ class VinylDNS @Inject() (
logger.info( logger.info(
s"LoginId [$loginId] complete: --LOGIN-- user [${user.userName}] logged in with id ${user.id}" s"LoginId [$loginId] complete: --LOGIN-- user [${user.userName}] logged in with id ${user.id}"
) )
Redirect("/index").withSession(ID_TOKEN -> token.toString)
val redirectLocation =
Try {
new String(java.util.Base64.getDecoder.decode(loginId.split(":").last))
} match {
case Success(x) => x
case Failure(_) => "/index"
}
Redirect(redirectLocation).withSession(ID_TOKEN -> token.toString)
case Left(err) => case Left(err) =>
logger.error(s"LoginId [$loginId] failed with error: $err") logger.error(s"LoginId [$loginId] failed with error: $err")
InternalServerError( InternalServerError(
views.html.systemMessage(""" views.html.systemMessage(
|There was an issue when logging in. """
|<a href="/index">Please try again by clicking this link.</a> |There was an issue when logging in.
|If the issue persists, contact your VinylDNS Administrators |<a href="/index">Please try again by clicking this link.</a>
|If the issue persists, contact your VinylDNS Administrators
""".stripMargin) """.stripMargin)
).withNewSession ).withNewSession
} }

View File

@ -1,18 +1,25 @@
@(setSessionUrl: String)(implicit requestHeader: RequestHeader) @(setSessionUrl: String)(implicit requestHeader: RequestHeader)
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" class="body-full-height"> <html lang="en" class="body-full-height">
<head> <head>
<!-- META SECTION --> <!-- META SECTION -->
<title>Login</title> <title>Login</title>
<meta name="google" content="notranslate" /> <meta name="google" content="notranslate" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta id="oidc" content="@setSessionUrl" /> <meta id="oidc" content="@setSessionUrl" />
<!-- END META SECTION --> <!-- END META SECTION -->
</head> </head>
<body> <body>
<a href="@{setSessionUrl}">Finishing login, if not redirected, click this link</a> <a href="@{setSessionUrl}">Finishing login, if not redirected, click this link</a>
@* <script src="/public/js/vinyldns.js"></script>*@ <script>
</body> window.setTimeout(function() {
let element = document.getElementById('oidc');
if (element != null) {
window.location = element.getAttribute('content');
}
}, 0);
</script>
</body>
</html> </html>

View File

@ -1 +1 @@
version in ThisBuild := "0.10.2" version in ThisBuild := "0.10.3"