jasongoodwin / authentikat-jwt Goto Github PK
View Code? Open in Web Editor NEWJWT Scala Implementation - Claims based auth for Scala.
License: Apache License 2.0
JWT Scala Implementation - Claims based auth for Scala.
License: Apache License 2.0
Hi, Jason!
Looks like sonatype gave you the heads up to publish - do you know whether this has been pushed to maven central yet?
I see currently the RS256 is not supported. Can it be easily implemented? I need it for my project to validate the JWT which is RS256.
Message: java.lang.UnsupportedOperationException: RS256 is an unknown or unimplemented JWT algo key
authentikat.jwt.JsonWebSignature$.apply(JsonWebSignature.scala:28)
authentikat.jwt.JsonWebToken$.validate(JsonWebToken.scala:85)
Add Ecdsa Signing/Verification
Is it possible to create an RSA signature using SHA-256 hashing algorithm?
As this is the only one supported by the Google App Engine for authentication.
With version 0.4.4 the JwtHeader is wrongly trasformed as
[{"alg":"HS256"},{"typ":"JWT"}]
instead of
{"alg":"HS256","typ":"JWT"}
This is because in the JwtHeader class, in the asJsonString
function we do:
implicit val formats = org.json4s.DefaultFormats
org.json4s.jackson.Serialization.write(toSerialize)
instead of
SimpleJsonSerializer(toSerialize)
Please please fix it as this is making impossible to use the library!
Cheers,
D.
Trying to parse the JWT with scala 2.12.12 fails
The following snippet will return false
on validation:
val jwt = JsonWebToken(JwtHeader("HS256"), JwtClaimsSet(Map.empty[String, String]), "test")
JsonWebToken.validate(jwt, "test")
There appears to be a problem to parse the header properly and the following header parsing throws an exception by itself:
JwtHeader.fromJsonString(JwtHeader("HS256").asJsonString)
Exception in thread "main" java.lang.NoSuchMethodError: scala.collection.immutable.List.$anonfun$flatMap$1$adapted(Lscala/runtime/BooleanRef;Lscala/runtime/ObjectRef;Lscala/runtime/ObjectRef;Ljava/lang/Object;)Ljava/lang/Object;
at java.base/java.lang.invoke.MethodHandleNatives.resolve(Native Method)
at java.base/java.lang.invoke.MemberName$Factory.resolve(MemberName.java:1041)
at java.base/java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1066)
at java.base/java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:2040)
at java.base/java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(MethodHandles.java:2453)
at java.base/java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:501)
at org.json4s.MonadicJValue.findDirectByName(MonadicJValue.scala:25)
at org.json4s.MonadicJValue.$bslash(MonadicJValue.scala:18)
at authentikat.jwt.JwtHeader$.fromJsonString(JwtHeader.scala:42)
at com.playground$.main(App.scala:17)
at com.playground.App.main(App.scala)
The issue possibly comes from json4s and scala 2.12.12 problem with older json4s versions (e.g. scala/bug#12100), and if so possibly the json4s should be updated here
JsonWebToken.validate
does not currently handle cases where an invalid token is supplied.
For example, the snippet below raises the following exception:
>>> JsonWebToken.validate("", "secret")
com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input
at [Source: java.io.StringReader@263676bd; line: 1, column: 1]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:3036)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2978)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2098)
at org.json4s.jackson.JsonMethods$class.parse(JsonMethods.scala:19)
at org.json4s.jackson.JsonMethods$.parse(JsonMethods.scala:44)
at authentikat.jwt.JwtHeader$.fromJsonString(JwtHeader.scala:33)
at authentikat.jwt.JsonWebToken$.validate(JsonWebToken.scala:75)
at .<init>(<console>:11)
at .<clinit>(<console>)
at .<init>(<console>:7)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:734)
at scala.tools.nsc.interpreter.IMain$Request.loadAndRun(IMain.scala:983)
at scala.tools.nsc.interpreter.IMain.loadAndRunReq$1(IMain.scala:573)
at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:604)
at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:568)
at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:756)
at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:801)
at scala.tools.nsc.interpreter.ILoop.command(ILoop.scala:713)
at scala.tools.nsc.interpreter.ILoop.processLine$1(ILoop.scala:577)
at scala.tools.nsc.interpreter.ILoop.innerLoop$1(ILoop.scala:584)
at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:587)
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply$mcZ$sp(ILoop.scala:878)
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:833)
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:833)
at scala.tools.nsc.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:135)
at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:833)
at scala.tools.nsc.interpreter.ILoop.main(ILoop.scala:900)
at xsbt.ConsoleInterface.run(ConsoleInterface.scala:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:102)
at sbt.compiler.AnalyzingCompiler.console(AnalyzingCompiler.scala:77)
at sbt.Console.sbt$Console$$console0$1(Console.scala:23)
at sbt.Console$$anonfun$apply$2$$anonfun$apply$1.apply$mcV$sp(Console.scala:24)
at sbt.TrapExit$.sbt$TrapExit$$executeMain$1(TrapExit.scala:33)
at sbt.TrapExit$$anon$1.run(TrapExit.scala:42)
In cases such as this it seems that validate
should anticipate the problem and simply return false.
Right now, at least for HMac, the String
key is converted to Array[Byte]
(https://github.com/jasongoodwin/authentikat-jwt/blob/master/src/main/scala/authentikat/jwt/JsonWebSignature.scala#L47) using String.asBytes
(http://docs.oracle.com/javase/8/docs/api/java/lang/String.html#getBytes--).
This is kind of confusing, and unless I'm missing something is platform-dependent and reduces the key space to only those keys that are valid strings in the default encoding of the platform.
escape json comments
The index.html file is being included with the jar distribution and it is overriding the index.html page in my play app.
We have to be careful with handling jdk security classes so we end up making a bunch of extra objects to avoid thread safety issues.
I think bouncycastle offers threadsafe alternatives - it would be worthwhile to change the signing and verification to use bouncycastle
Tim McClean flagged that users may be able to guess how correct their guesses are by measuring time of response.
Seems this might be difficult to actually exploit but we can add some non-blocking delays or otherwise do a full comparison.
Add PS* Signing/Verification
Right now the library takes eg a map. I think the API should have explicit claims handling for the public claims in the specification.
Hi! I'm reaching out because I see you are on the search for a maintainer for this project. We utilize this dependency in our project's over here at SignalPath and would be willing to take over as maintainers of this project.
Recently we created a fork to address dependency vulnerabilities and to cross compile to Scala 2.13 as well. Would you be interested in these additions in your repo?
SignalPath's Fork: https://github.com/SignalPath/authentikat-jwt
Please, release a version compatible with Scala 2.12
This project should be under CI via travis.
There was a version bump in json4s that broke binary compatibility (json4s/json4s#212). I would love to use this library in my project but I need a later version of json4s than is used in 0.4.1. It looks like 0.4.2 has solved the problem, but it hasn't been pushed up to the maven repo. If someone could just push the latest version to maven it would really help me out. Thanks!
Currently the library is picky about input types. It actually uses a custom serialization strategy. The value Any should be serialized instead of calling toString. This should be addressed.
def apply(fields: Seq[(String, Any)]) = {
"{" +
fields.map {
case (key: String, value: Number) =>
""" + key + "":" + value
case (key: String, value: Date) =>
""" + key + "":" + """ + formatDateIso8601(value) + """
case (key: String, value: String) =>
""" + key + "":" + """ + value + """
case (key: String, value: Any) =>
""" + key + "":" + """ + value.toString + """
}.mkString(",") +
"}"
}
In the case where the public key is looked up from a map of kid -> publicKeys
, is it possible to parse the kid
from the Jwt Header for that map?
The so-called "kid" parameter: http://self-issued.info/docs/draft-jones-json-web-token-01.html#ReservedClaimName
Currently I only see the following Header params in the latest master build:
algorithm
, contentType
, typ
I would work around this by extending JwtHeader
to include kid
, but it does not inherit from a base trait and scala prohibits inheriting directly from another case class.
The only possible workaround I've found is copying and pasting the encoding apply
statement into a separate object that allows my header content. Because the kid
can be extracted separately in my own logic to deduce the key
, the JsomWebToken.validate()
can then be used as usual.
As per the recent JWT vulnerability concerns, (https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/), I was looking into the JsonWebToken.validate() method in this library and was interesting in forking off and adding an algorithm parameter to the validate method to avoid this recent vulnerability of being able to specify your own encryption algorithm. I will work on this today, and would appreciate any feedback if any.
Nate
This implementation is insecure, specifically the verification step can be circumvented easily. Because you use the algorithm specified in the header to verify, and attacker could just send you a JWT with algorithm=None, and your verification method would return true. Instead, JsonWebToken.validate should take the algorithm expected and verify using that algorithm. The algorithm should never be allowed to be chosen by the untrusted user.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.