No internet connection
  1. Home
  2. Issues

500 error with embedded SSO login

By Walter Mazur @mazurbeam
    2022-01-17 19:12:06.602Z

    Was able to get it working locally with the paseto token.

    Deployed it to staging and it hits upsert-user-and-login, and I can see a valid token in the request body but I get a 500 error. Is this something I'm doing wrong?

    500 Internal Server Error
    
    Something went wrong: [DwE500REX]
    
    java.lang.IllegalArgumentException: requirement failed: TyE5KBW06
    	at scala.Predef$.require(Predef.scala:281)
    	at com.debiki.core.ExternalUser.<init>(user.scala:849)
    	at talkyard.server.parser.PasetoParSer$.apiV0_parseExternalUserImpl(PasetoParSer.scala:59)
    	at talkyard.server.parser.PasetoParSer$.apiV0_parseExternalUser(PasetoParSer.scala:14)
    	at talkyard.server.authn.SsoAuthnController.$anonfun$apiV0_upsertUserAndLogin$3(SsoAuthnController.scala:232)
    	at scala.Option.map(Option.scala:230)
    	at talkyard.server.authn.SsoAuthnController.$anonfun$apiV0_upsertUserAndLogin$1(SsoAuthnController.scala:216)
    	at scala.Function1.$anonfun$andThen$1(Function1.scala:57)
    	at ed.server.http.PlainApiActions$$anon$1.runBlockIfAuthOk(PlainApiActions.scala:684)
    	at ed.server.http.PlainApiActions$$anon$1.invokeBlockAuthViaCookie(PlainApiActions.scala:432)
    	at ed.server.http.PlainApiActions$$anon$1.invokeBlockImpl(PlainApiActions.scala:250)
    	at ed.server.http.PlainApiActions$$anon$1.invokeBlock(PlainApiActions.scala:136)
    	at ed.server.http.PlainApiActions$$anon$1.invokeBlock(PlainApiActions.scala:109)
    	at play.api.mvc.ActionBuilder$$anon$9.apply(Action.scala:379)
    	at ed.server.http.PlainApiActions$$anon$1.$anonfun$composeAction$1(PlainApiActions.scala:123)
    	at ed.server.http.SafeActions$ExceptionAction$.invokeBlock(SafeActions.scala:126)
    	at ed.server.http.SafeActions$ExceptionAction$.invokeBlock(SafeActions.scala:83)
    	at play.api.mvc.ActionBuilder$$anon$9.apply(Action.scala:379)
    	at play.api.mvc.Action.$anonfun$apply$4(Action.scala:82)
    	at play.api.libs.streams.StrictAccumulator.$anonfun$mapFuture$4(Accumulator.scala:168)
    	at scala.util.Try$.apply(Try.scala:213)
    	at play.api.libs.streams.StrictAccumulator.$anonfun$mapFuture$3(Accumulator.scala:168)
    	at scala.Function1.$anonfun$andThen$1(Function1.scala:57)
    	at scala.Function1.$anonfun$andThen$1(Function1.scala:57)
    	at play.api.libs.streams.StrictAccumulator.run(Accumulator.scala:200)
    	at play.core.server.AkkaHttpServer.$anonfun$runAction$4(AkkaHttpServer.scala:418)
    	at akka.http.scaladsl.util.FastFuture$.strictTransform$1(FastFuture.scala:41)
    	at akka.http.scaladsl.util.FastFuture$.transformWith$extension1(FastFuture.scala:55)
    	at akka.http.scaladsl.util.FastFuture$.flatMap$extension(FastFuture.scala:26)
    	at play.core.server.AkkaHttpServer.runAction(AkkaHttpServer.scala:415)
    	at play.core.server.AkkaHttpServer.executeHandler(AkkaHttpServer.scala:360)
    	at play.core.server.AkkaHttpServer.handleRequest(AkkaHttpServer.scala:323)
    	at play.core.server.AkkaHttpServer.$anonfun$createServerBinding$1(AkkaHttpServer.scala:224)
    	at akka.stream.impl.fusing.MapAsync$$anon$30.onPush(Ops.scala:1307)
    	at akka.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:542)
    	at akka.stream.impl.fusing.GraphInterpreter.processEvent(GraphInterpreter.scala:496)
    	at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:390)
    	at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:650)
    	at akka.stream.impl.fusing.GraphInterpreterShell$AsyncInput.execute(ActorGraphInterpreter.scala:521)
    	at akka.stream.impl.fusing.GraphInterpreterShell.processEvent(ActorGraphInterpreter.scala:625)
    	at akka.stream.impl.fusing.ActorGraphInterpreter.akka$stream$impl$fusing$ActorGraphInterpreter$$processEvent(ActorGraphInterpreter.scala:800)
    	at akka.stream.impl.fusing.ActorGraphInterpreter$$anonfun$receive$1.applyOrElse(ActorGraphInterpreter.scala:818)
    	at akka.actor.Actor.aroundReceive(Actor.scala:537)
    	at akka.actor.Actor.aroundReceive$(Actor.scala:535)
    	at akka.stream.impl.fusing.ActorGraphInterpreter.aroundReceive(ActorGraphInterpreter.scala:716)
    	at akka.actor.ActorCell.receiveMessage(ActorCell.scala:580)
    	at akka.actor.ActorCell.invoke(ActorCell.scala:548)
    	at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:270)
    	at akka.dispatch.Mailbox.run(Mailbox.scala:231)
    	at akka.dispatch.Mailbox.exec(Mailbox.scala:243)
    	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
    	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
    	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
    
    • 2 replies
    1. Seems you can work around this problem (util it's been fixed),
      by either including no full name at all — that is, leaving out the fullName field,
      or, when including a full name, make sure it doesn't start or end with spaces, and that it's not the empty string ("").

      Details: Looks like a Talkyard bug, in that the PASETO parser allows non-trimmed or empty names,
      but other code doesn't allow it (requires that any full name either 1) is left out, or that 2) it's non-empty and doesn't start/end with spaces).

      (If you're curious, here's how the double check that fails looks:
      require(fullName.forall(_.isTrimmedNonEmpty), "TyE5KBW06") )

      Thanks for having including the stack trace

      ***

      Was able to get it working locally

      (I suppose the local environment didn't include any user name fields that triggered the bug.)

      ***

      Apart from running into this, how did the PASETO integration go this far?
      How hard / easy / (or maybe annoying?)   was it to find the right PASETO lib for you to use, and write the code? (What lib did you use, if I may ask?)
      What's your use case b.t.w., I suppose this is for a blog somewhere? (Or embedded comments ... for something else than a blog?)

      1. M
        In reply tomazurbeam:
        Walter Mazur @mazurbeam
          2022-01-18 20:35:04.743Z

          Awesome thanks removing username from the payload worked.

          Other than that the integration went pretty well using the python PASETO library. Struggled a little bit figuring out how to inject the key, but it ended up being pretty simple and obvious. Convert to hex and overwrite the key. Definitely a fan of these tokens now.

          And yep using this for embedded comments on a blog

          import paseto
          from paseto.keys.symmetric_key import SymmetricKey
          from paseto.protocols.v2 import ProtocolVersion2
          
          shared_secret_key_bytes = bytes.fromhex(SSO_TOKEN_SECRET)
          shared_key = SymmetricKey.generate(protocol=ProtocolVersion2)
          shared_key.key = shared_secret_key_bytes
          
          authn_message = {
                ...
          }
          token = paseto.create(
              key=shared_key,
              purpose='local',
              exp_seconds=300,
              claims=authn_message
          )
          
          1. Progress
            with handling this problem
          2. @KajMagnus marked this topic as Started 2022-01-18 07:21:43.507Z.