okta / okta-jwt-verifier-java Goto Github PK
View Code? Open in Web Editor NEWokta-jwt-verifier-java
Home Page: https://github.com/okta/okta-jwt-verifier-java
okta-jwt-verifier-java
Home Page: https://github.com/okta/okta-jwt-verifier-java
Hi there!
I'm interested in your recommendations about the best way to fetch the OIDC profile data for an authenticated user. My use case is as follows:
@okta/okta-react
okta/okta-jwt-verifier-java
)What I'd like to do is accomplish the following:
Authorization: Bearer
headerHowever, in order to verify the JWT using okta/okta-jwt-verifier-java
, I need to be able to supply a nonce
value to compare the expected nonce value I submitted while requesting an access token with the actual claim on the ID JWT.
Does this imply that I should not be passing around the ID token if I'm using the PKCE flow initiated by my frontend application, and should instead only be sending an access token JWT to my backend for verification?
Looks like we need an additional dependency upon commons-collection4 to use? Any way to add this to your dependencies so that consumers don't have to manage the dependency?
JjwtAccessTokenVerifierBuilder's build method checks if the issuer in the token is a valid issuer in BaseVerifierBuilderSupport.validate() which calls okta-config-checks JAR's ConfigurationValidator.assertIssuer(). However, when runing the code through a testing scenario, this implementation needs to allow a non HTTPS url as well.
In my case, I'm referring to https://developer.okta.com/blog/2018/05/02/testing-spring-boot-angular-components#mock-oktas-api-with-wiremock and using Wiremock to mock the HTTP calls, for which I've to send issuer such as "http://localhost:51592/oauth/issuer".
I've earlier also used okta.testing.disableHttpsCheck property which is accepted by Okta Java API SDK and works fine. May be we could use the same property here as well?
"okta.testing.disableHttpsCheck" flag should be read and issuer HTTPs check should be disabled if the flag is true.
Error thrown: Your Okta Issuer URL must start with https. Current value: http://localhost:64301/oauth/issuer. You can copy your domain from the Okta Developer Console. Follow these instructions to find it: https://bit.ly/finding-okta-domain
Pass a JWT token with localhost issuer.
0.5.0
Hey there,
I was integrating this lib into one of my apps and noticed that this makes use of the RemoteJwkSigningKeyResolver
which makes an HTTP request to jwkUri
everytime getKey()
is called (via updateKeys()).
Is it possible for me to use the library without making any HTTP requests? It adds a lot of latency to my token verification process.
Does the JSON returned by https://dev-******.okta.com/oauth2/default/v1/keys
change or can I save it locally and use that instead of querying the HTTP endpoint?
I know Okta recommends dynamically querying the endpoint, but trying to see if there is a faster way to achieve this.
Thanks for the lib! ๐
I am trying to use this maven artifact in an OSGI environment (Adobe Experience Manager), but it seems to be a non-OSGI jar, and when I deployed my application code, it says "com.okta.jwt -- Cannot be resolved".
It'll be good if you add support for OSGI.
Can you please update on the release of 0.4.2 version?
and want to use something like this for my own unit/integration tests - can this be refactored into java code and packaged as a jar/package suitable for unit tests for this library?
The setConnectionTimeout(1000)
and setReadTimeout(1000)
in the example in README.md take a Duration
instead of an integer. The example should be re-written as follows (assuming the right imports are done elsewhere)
Duration timeout = Duration.of(1, ChronoUnit.SECONDS)
and change the methods in the builder to
setConnectionTimeout(timeout)
setReadTimeout(timeout)
Add User-Agent header to http requests made to the /keys
endpoint
The next version of this library will use OkHttp which already handles retry, but configuring this behavior is currently NOT exposed to the developer.
In corporate there is sometimes a need to connect to Okta over Http proxy, JWT verifier should support it imho.
Hi,
I am trying to verify an freshly generated access_token using your library and I am encoutering this issue :
com.okta.jwt.JoseException: Failed to validate JWT string at com.okta.jwt.impl.NimbusJwtVerifier.decode(NimbusJwtVerifier.java:82) at com.okta.jwt.impl.NimbusJwtVerifier.decodeAccessToken(NimbusJwtVerifier.java:68) at com.xxx.poc.oauth2.api.endpoints.AuthenticationEndpoint.post(AuthenticationEndpoint.java:71) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60) at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205) at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75) at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288) at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108) at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84) at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469) at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400) at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349) at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339) at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416) at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537) at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699) at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:852) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:535) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:190) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595) at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1253) at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564) at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1155) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:219) at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) at org.eclipse.jetty.server.Server.handle(Server.java:530) at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:347) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:256) at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279) at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102) at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:247) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:140) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131) at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:382) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:708) at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:626) at java.lang.Thread.run(Thread.java:748) Caused by: com.nimbusds.jose.proc.BadJOSEException: Signed JWT rejected: Another algorithm expected, or no matching key(s) found at com.nimbusds.jwt.proc.DefaultJWTProcessor.<clinit>(DefaultJWTProcessor.java:100) at com.okta.jwt.JwtHelper.build(JwtHelper.java:79) at com.xxx.poc.oauth2.api.endpoints.AuthenticationEndpoint.post(AuthenticationEndpoint.java:69) ... 50 more
This seems to be the root cause :
Signed JWT rejected: Another algorithm expected, or no matching key(s) found
Do you have any idea ?
When you are using Google+ API for sign in using Oauth2 it can return both an URI or a string, in the OktaJWTClaimsVerifier it would be an improvement to check if the issuer is either URI or URI-link substring https://, or is there another workaround for this?
https://accounts.google.com
this is required for the JWTHelper to be an URI
accounts.google.com
what google actually can return as well
I am working on OpenID Connect implementation for the Okta Integration Network. The documentation says:
To support the potentially large numbers of Okta orgs accessing it through the OIN, an OIDC integration can't use a custom authorization server, including the default server. You can only use the Org Authorization Server (opens new window).
I assume that means the baseUrl
should not include default
or an authorizationServerId
. However, in JjwtAccessTokenVerifierBuilder.java
there is validation:
if (!getIssuer().matches(".*/oauth2/.*")) {
log.warn("Decoding access tokens from this issuer '{}' may not be possible. Your issuer URL should be in the format of 'https://{yourOktaDomain}/oauth2/qualifier'", getIssuer());
}
Is there a reason why the qualifier is necessary? Am I missing something about how this should work with a Org Authorization Server?
Everything works if I use the default
authorization server in my dev environment, but I'm worried that will not work for the Okta Integration Network based on the documentation above.
I thought it would validate the token.
Decoding access tokens from this issuer 'https://dev-55695188.okta.com/oauth2' may not be possible. Your issuer URL should be in the format of 'https://{yourOktaDomain}/oauth2/qualifier'
Failed to parse token
Submit a url like https://xxx.com/oauth2
as the issuer
"com.okta.jwt" % "okta-jwt-verifier" % "0.5.1",
"com.okta.jwt" % "okta-jwt-verifier-impl" % "0.5.1",
โน๏ธ If you have a question, please post it on the Okta Developer Forum instead. Issues in this repository are reserved for bug reports and feature requests only.
jwtVerifier = JwtVerifiers.accessTokenVerifierBuilder()
.setIssuer(oauthURL+"/oauth2/default")
.setAudience("api://default")
.setConnectionTimeout(Duration.ofSeconds(5)) // defaults to 1s
//.setReadTimeout(Duration.ofSeconds(5)) // defaults to 1s
.setRetryMaxAttempts(5)
.setRetryMaxElapsed(Duration.ofSeconds(5))
.build();
generates the following error when executed:
java.util.ServiceConfigurationError: com.okta.jwt.AccessTokenVerifier$Builder: Provider com.okta.jwt.impl.jjwt.JjwtAccessTokenVerifierBuilder not a subtype
JwtVerifiers.accessTokenVerifierBuilder should have initialized
Initializing the builder caused and Error to be thrown:
java.util.ServiceConfigurationError: com.okta.jwt.AccessTokenVerifier$Builder: Provider com.okta.jwt.impl.jjwt.JjwtAccessTokenVerifierBuilder not a subtype
Execut the code above
pom.xml says version is 25
On scala:
libraryDependencies ++= Seq(
"com.okta.jwt" % "okta-jwt-verifier" % "0.5.1",
"com.okta.jwt" % "okta-jwt-verifier-impl" % "0.5.1"// % "runtime,test",
)
[info] com.evenfinancial.auth.oidc.OidcConfigurationSpec *** ABORTED ***
[info] java.lang.NoSuchMethodError: 'io.jsonwebtoken.JwtParserBuilder io.jsonwebtoken.Jwts.parserBuilder()'
[info] at com.okta.jwt.impl.jjwt.TokenVerifierSupport.buildJwtParser(TokenVerifierSupport.java:50)
[info] at com.okta.jwt.impl.jjwt.TokenVerifierSupport.<init>(TokenVerifierSupport.java:46)
[info] at com.okta.jwt.impl.jjwt.JjwtAccessTokenVerifier.<init>(JjwtAccessTokenVerifier.java:39)
[info] at com.okta.jwt.impl.jjwt.JjwtAccessTokenVerifierBuilder.build(JjwtAccessTokenVerifierBuilder.java:58)
[info] at com.okta.jwt.impl.jjwt.JjwtAccessTokenVerifierBuilder.build(JjwtAccessTokenVerifierBuilder.java:27)
[info] at com.evenfinancial.auth.oidc.OidcConfiguration$.accessTokenVerifier(OidcConfiguration.scala:37)
[info] at com.evenfinancial.auth.oidc.OidcConfiguration$.accessTokenVerifier(OidcConfiguration.scala:29)
[info] at com.evenfinancial.auth.oidc.OidcConfiguration$.parseToken(OidcConfiguration.scala:19)
[info] at com.evenfinancial.auth.oidc.OidcConfigurationSpec.$anonfun$new$2(OidcConfigurationSpec.scala:11)
Is there a dependency missing in the pom?
โน๏ธ If you have a question, please post it on the Okta Developer Forum instead. Issues in this repository are reserved for bug reports and feature requests only.
In some rare cases I am seeing an IllegalArgumentException
being thrown from the AccessTokenVerifier#decode
. According to the documentation it should throw a JwtVerificationException
when parsing or validation errors occur.
It appears that the try/catch around the code that parses the JWT does not adequately handle all of the exceptions advertised by the JWT parser: https://github.com/okta/okta-jwt-verifier-java/blob/master/impl/src/main/java/com/okta/jwt/impl/jjwt/TokenVerifierSupport.java#L63-L71
A JwtVerificationException
should be thrown.
java.lang.IllegalArgumentException: A signing key must be specified if the specified JWT is digitally signed.
at io.jsonwebtoken.lang.Assert.notNull(Assert.java:82)
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:357)
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:513)
at com.okta.jwt.impl.jjwt.TokenVerifierSupport.decode(TokenVerifierSupport.java:61)
at com.okta.jwt.impl.jjwt.JjwtAccessTokenVerifier.decode(JjwtAccessTokenVerifier.java:45)
...
I'm not sure what the content of the JWT is unfortunately but this happens very rarely.
// okta
implementation 'com.okta.jwt:okta-jwt-verifier:0.4.0'
implementation 'com.okta.jwt:okta-jwt-verifier-impl:0.4.0'
We are using the below version of the library.
"@okta/jwt-verifier": {
"version": "0.0.14",
"resolved": "https://registry.npmjs.org/@okta/jwt-verifier/-/jwt-verifier-0.0.14.tgz",
"integrity": "sha512-O+CzOeMy6aUi0PtqmoZLmKjE1xpUF9nUMlZ3hYlz4fUpb3zKUUESohq/iSuBijw2dB0Lru6Tsi7OWJXFJT1vew==",
"requires": {
"@okta/configuration-validation": "^0.1.1",
"jwks-rsa": "^1.2.0",
"njwt": "^0.4.0"
}
}
The version of njwt used has been flagged with a Uninitialized Buffer Allocation Vulnerability.
https://www.sourceclear.com/vulnerability-database/security/sca/vulnerability/sid-6814/summary
Please can you review and use a new version of the library or use a different one so that the issue is resolved?
โน๏ธ If you have a question, please post it on the Okta Developer Forum instead. Issues in this repository are reserved for bug reports and feature requests only.
currently one issuer validation is supported but would be great to have list of issuer provided as we have custom authorization server and multiple authorization servers are being used for authentication
What should have happened?
Please provide log or error messages if applicable.
If the current behavior is a bug, please provide the steps to reproduce and a minimal demo if possible.
Right now the underlying nimbus library has a default 250ms timeout for accessing the JWKS endpoint. Customers are running into issues with this timeout value and we need to give the ability to override the default.
https://devforum.okta.com/t/jwt-verification-timeout-java/1074
When installed with okta-sdk-java >= 3.0.2, the id token verifier throws a NoSuchMethodError.
I believe this is probably because the okta.commons.version
is different between the two libraries (1.2.4
vs 1.2.5
). The method HttpClientConfiguration.getRequestExecutorParams
is called but does not exist and so throws a NoSuchMethodError. Potentially related: okta/okta-commons-java#42
When creating an id token verifier using the builder, an id token verifier is returned
An exception is thrown:
NoSuchMethodError: 'Map HttpClientConfiguration.getRequestExecutorParams()'
JwtVerifiers.idTokenVerifierBuilder()
.setClientId("my_client_id")
.setIssuer("baseurl.okta.com")
.build();
okta-jwt-verifier
: 0.5.0
okta-sdk-api
: >= 3.0.2
Release a new version of okta-jwt-verifier-java.
okta.commons.version = 1.2.5
is already set in the pom, the library just hasn't been released since 16th Sep 2020.
Limit the number of outbound requests to the /key
endpoint.
Hi,
I've been following the quick start guide https://developer.okta.com/quickstart/#/angular/java/spring but keep getting an invalid token exception from spring.
I'v double checked that all parameters are as described in the guide, angular widget is working properly and getting an access token but when this access token is being sent to the back-end as a "Authorization: 'Bearer ' + token" header, spring is throwing an invalid token exception after trying to restore it from some internal storage.
I'm attaching below the spring log & stack trace, lmk if any other info is required.
Spring security chain log:
o.s.security.web.FilterChainProxy : /admin/get-list at position 1 of 16 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
o.s.security.web.FilterChainProxy : /admin/get-list at position 2 of 16 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
o.s.security.web.FilterChainProxy : /admin/get-list at position 3 of 16 in additional filter chain; firing Filter: 'HeaderWriterFilter'
o.s.security.web.FilterChainProxy : /admin/get-list at position 4 of 16 in additional filter chain; firing Filter: 'LogoutFilter'
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', GET]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/admin/get-list'; against '/logout'
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', POST]
o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /admin/get-list' doesn't match 'POST /logout'
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', PUT]
o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /admin/get-list' doesn't match 'PUT /logout'
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', DELETE]
o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /admin/get-list' doesn't match 'DELETE /logout'
o.s.s.web.util.matcher.OrRequestMatcher : No matches found
o.s.security.web.FilterChainProxy : /admin/get-list at position 5 of 16 in additional filter chain; firing Filter: 'OAuth2AuthorizationRequestRedirectFilter'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/admin/get-list'; against '/oauth2/authorization/{registrationId}'
o.s.security.web.FilterChainProxy : /admin/get-list at position 6 of 16 in additional filter chain; firing Filter: 'OAuth2AuthenticationProcessingFilter'
p.a.OAuth2AuthenticationProcessingFilter : Authentication request failed: error="invalid_token", error_description="Invalid access token: undefined"
o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@3b99c2b1
s.s.o.p.e.DefaultOAuth2ExceptionRenderer : Written [error="invalid_token", error_description="Invalid access token: undefined"] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@498e5da7]
s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
Stack trace:
Daemon Thread [http-nio-9999-exec-5] (Suspended)
owns: NioEndpoint$NioSocketWrapper (id=466)
DefaultTokenServices.loadAuthentication(String) line: 231
OAuth2AuthenticationManager.authenticate(Authentication) line: 83
OAuth2AuthenticationProcessingFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 150
FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 334
OAuth2AuthorizationRequestRedirectFilter.doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line: 160
OAuth2AuthorizationRequestRedirectFilter(OncePerRequestFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 107
FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 334
LogoutFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 116
FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 334
HeaderWriterFilter.doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line: 66
HeaderWriterFilter(OncePerRequestFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 107
FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 334
SecurityContextPersistenceFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 105
FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 334
WebAsyncManagerIntegrationFilter.doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line: 56
WebAsyncManagerIntegrationFilter(OncePerRequestFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 107
FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 334
FilterChainProxy.doFilterInternal(ServletRequest, ServletResponse, FilterChain) line: 215
FilterChainProxy.doFilter(ServletRequest, ServletResponse, FilterChain) line: 178
DelegatingFilterProxyRegistrationBean$1(DelegatingFilterProxy).invokeDelegate(Filter, ServletRequest, ServletResponse, FilterChain) line: 357
DelegatingFilterProxyRegistrationBean$1(DelegatingFilterProxy).doFilter(ServletRequest, ServletResponse, FilterChain) line: 270
ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 193
ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 166
OrderedRequestContextFilter(RequestContextFilter).doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line: 99
OrderedRequestContextFilter(OncePerRequestFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 107
ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 193
ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 166
OrderedFormContentFilter(FormContentFilter).doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line: 92
OrderedFormContentFilter(OncePerRequestFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 107
ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 193
ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 166
OrderedHiddenHttpMethodFilter(HiddenHttpMethodFilter).doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line: 93
OrderedHiddenHttpMethodFilter(OncePerRequestFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 107
ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 193
ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 166
WebMvcMetricsFilter.filterAndRecordMetrics(HttpServletRequest, HttpServletResponse, FilterChain, Object) line: 154
WebMvcMetricsFilter.filterAndRecordMetrics(HttpServletRequest, HttpServletResponse, FilterChain) line: 122
WebMvcMetricsFilter.doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line: 107
WebMvcMetricsFilter(OncePerRequestFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 107
ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 193
ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 166
OrderedCharacterEncodingFilter(CharacterEncodingFilter).doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line: 200
OrderedCharacterEncodingFilter(OncePerRequestFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 107
ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 193
ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 166
CorsFilter.doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line: 96
CorsFilter(OncePerRequestFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 107
ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 193
ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 166
StandardWrapperValve.invoke(Request, Response) line: 199
StandardContextValve.invoke(Request, Response) line: 96
NonLoginAuthenticator(AuthenticatorBase).invoke(Request, Response) line: 490
StandardHostValve.invoke(Request, Response) line: 139
ErrorReportValve.invoke(Request, Response) line: 92
StandardEngineValve.invoke(Request, Response) line: 74
CoyoteAdapter.service(Request, Response) line: 343
Http11Processor.service(SocketWrapperBase<?>) line: 408
Http11Processor(AbstractProcessorLight).process(SocketWrapperBase<?>, SocketEvent) line: 66
AbstractProtocol$ConnectionHandler<S>.process(SocketWrapperBase<S>, SocketEvent) line: 770
NioEndpoint$SocketProcessor.doRun() line: 1415
NioEndpoint$SocketProcessor(SocketProcessorBase<S>).run() line: 49
ThreadPoolExecutor(ThreadPoolExecutor).runWorker(ThreadPoolExecutor$Worker) line: 1142
ThreadPoolExecutor$Worker.run() line: 617
TaskThread$WrappingRunnable.run() line: 61
TaskThread(Thread).run() line: 745
The javadoc leave a lot to be desired. What methods Block? What is a JoseException?
Reported under:
470337c#commitcomment-30819494
cc: @alexturc
It's not directly obvious how to configure the http client requests to an issuer URL using a Future
other than wrapping them in my own task runner.
I would like:
Future<Jwt> jwtFuture = jwtVerifier.asyncDecode(jwtString);
setExecutor(Executor executor)
in AccessTokenVerifier.Builder
Is there anyway we can add support for HS512 ? Looking at the code you only support SignatureAlgorithm.RS256 at the moment. If so, how do you handle PR? and releases. I can definitely help out if needed
@bdemers
I am following the example to build an AccessTokenVerifier
.
Here is my code:
AccessTokenVerifier jwtVerifier = JwtVerifiers.accessTokenVerifierBuilder()
.setIssuer("https://dev-******.okta.com/oauth2/default")
.setAudience("api://default")
.setConnectionTimeout(Duration.ofSeconds(1))
.setReadTimeout(Duration.ofSeconds(1))
.build();
Jwt jwt = jwtVerifier.decode(accessToken);
However, when calling jwtVerifier decode
here throws exception below:
java.lang.IllegalArgumentException: A signing key must be specified if the specified JWT is digitally signed.
at io.jsonwebtoken.lang.Assert.notNull(Assert.java:82) ~[auth-1.0-SNAPSHOT.jar:na]
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:357) ~[auth-1.0-SNAPSHOT.jar:na]
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:513) ~[auth-1.0-SNAPSHOT.jar:na]
at com.okta.jwt.impl.jjwt.TokenVerifierSupport.decode(TokenVerifierSupport.java:61) ~[auth-1.0-SNAPSHOT.jar:na]
at com.okta.jwt.impl.jjwt.JjwtAccessTokenVerifier.decode(JjwtAccessTokenVerifier.java:45) ~[auth-1.0-SNAPSHOT.jar:na]
#13 and checking the okta configuration in console don't help.
By digging a bit, when code is executing to line 334 - 357 in DefaultJwtParser.java
, we already decoded the whole accessToken, payload
and claims
contains everything same as a network introspect response.
However, in the RemoteJwkSigningKeyResolver.java
, i don't think the jwsHeader(contains two keys kid
and alg
) has a correct match with any keys in keyMap
.
Any places I can attach the Public Key when building the verifier and my jwkUri is https://dev-******.okta.com/oauth2/default/v1/keys
.
Hi Team,
I'm not able use the jar in my project which is in jdk 1.7. please suggest.
Thanks.
I was hoping this library would be usable as a general purpose JWT verifier, but it seems to only work with okta. Is that the intention? If so than please clarify this. If not then I have a few bugs that are blockers for me.
After I instantiate the JwtVerifier and call decode(jwt) method. Does this method check the JWT signature?
Do you have any gradle examples?
I try to use this in my gradle project:
plugins {
id 'java'
id 'com.github.johnrengelman.shadow' version '6.1.0'
}
repositories {
mavenCentral()
}
dependencies {
// ...
implementation('com.okta.jwt:okta-jwt-verifier:0.5.1') {
exclude group: 'org.slf4j'
}
runtimeOnly('com.okta.jwt:okta-jwt-verifier-impl:0.5.1') {
exclude group: 'org.slf4j'
}
}
shadowJar {
archiveClassifier.set('')
mergeServiceFiles()
}
But when I run my shadow jar will throws:
Caused by: java.lang.IllegalStateException: No `interface com.okta.jwt.AccessTokenVerifier$Builder` implementation found on the classpath. Have you remembered to include the okta-jwt-verifier-impl.jar in your runtime classpath?
at com.okta.jwt.JwtVerifiers.lambda$loadService$1(JwtVerifiers.java:60)
at <unknown class>.get(Unknown Source)
at java.base/java.util.Optional.orElseThrow(Optional.java:408)
at com.okta.jwt.JwtVerifiers.loadService(JwtVerifiers.java:60)
at com.okta.jwt.JwtVerifiers.accessTokenVerifierBuilder(JwtVerifiers.java:51)
at id.attestation.plugins.auth.FacebookAuthService.<init>(FacebookAuthService.java:22)
at java.base/java.lang.J9VMInternals.newInstanceImpl(Native Method)
at java.base/java.lang.Class.newInstance(Class.java:2288)
at org.pf4j.DefaultExtensionFactory.create(DefaultExtensionFactory.java:38)
... 30 common frames omitted
In fact okta-jwt-verifier-impl
and services files already contains in shadow jar file:
META-INF/
META-INF/MANIFEST.MF
...
META-INF/okta/
META-INF/okta/version.properties
com/
com/okta/
com/okta/jwt/
com/okta/jwt/impl/
com/okta/jwt/impl/jjwt/
com/okta/jwt/impl/jjwt/BaseVerifierBuilderSupport.class
com/okta/jwt/impl/jjwt/TokenVerifierSupport.class
com/okta/jwt/impl/jjwt/TokenVerifierSupport$OktaJwtHandler.class
com/okta/jwt/impl/jjwt/ClaimsValidator$CompositeClaimsValidator.class
com/okta/jwt/impl/jjwt/ClaimsValidator.class
com/okta/jwt/impl/jjwt/ClaimsValidator$ContainsAudienceClaimsValidator.class
com/okta/jwt/impl/jjwt/IssuerMatchingSigningKeyResolver.class
com/okta/jwt/impl/jjwt/models/
com/okta/jwt/impl/jjwt/models/JwkKeys.class
com/okta/jwt/impl/jjwt/models/JwkKey.class
com/okta/jwt/impl/jjwt/JjwtAccessTokenVerifierBuilder.class
com/okta/jwt/impl/jjwt/RemoteJwkSigningKeyResolver.class
com/okta/jwt/impl/jjwt/JjwtIdTokenVerifier.class
com/okta/jwt/impl/jjwt/JjwtAccessTokenVerifier.class
com/okta/jwt/impl/jjwt/JjwtIdTokenVerifierBuilder.class
com/okta/jwt/impl/http/
com/okta/jwt/impl/http/HttpClient.class
com/okta/jwt/impl/http/OktaCommonsHttpClient.class
com/okta/jwt/impl/DefaultJwt.class
...
META-INF/services/com.okta.jwt.AccessTokenVerifier$Builder
META-INF/services/com.okta.jwt.IdTokenVerifier$Builder
META-INF/services/com.okta.commons.http.RequestExecutorFactory
META-INF/services/io.jsonwebtoken.CompressionCodec
META-INF/services/io.jsonwebtoken.io.Serializer
META-INF/services/io.jsonwebtoken.io.Deserializer
META-INF/services/com.fasterxml.jackson.core.JsonFactory
META-INF/services/com.fasterxml.jackson.core.ObjectCodec
...
If the current behavior is a bug, please provide the steps to reproduce and a minimal demo if possible.
0.5.1
Hi ,
We have a mobile app that authenticates using oidc lib from okta and passes the access token to our resource service part of itโs request call (POST, GET, etc). We have setup an authorization server in our dashboard with default settings and using /oauth2/default endpoint with default audience โapi://defaultโ. With this setup, we are using oktaโs okta-jwt-verifier-java lib to verify the access token. The problem is we always get java.lang.IllegalArgumentException: A signing key must be specified if the specified JWT is digitally signed.
When we try to verify the access token. Not sure we made anything wrong here. Is this a bug?
[Update 1] I tried with nodejs resource api from the sample too i got below error when i tried to verify JWT from the app Error while resolving signing key for kid "cgtXxWFpMZm3g62lMjRpnwiF2dY4r3mqsBRh2HB9NyM"
So native app signing the jwt but the okta-jwt-verifier unable to resolve the signature? Am I missing something here? Either this should be a config issue which I missed or there is a bug in the verifier.
[Update 2] I tried to verify a JWT generated by another application which is a java web app. Here I am successfully able to verify the JWT using above node and java services but I am unable to verify the JWT generated only by the android app.
I have a mockito webservice and unit tests with a fixed java.time.Clock, when I try to decode the bearer token, I get an exception on the expired state of the token from the okta library sigh. I'd like to have an optional java.time.Clock
argument in AccessTokenVerifier
for the: Jwt decode(String accessToken) throws JwtVerificationException
I'd love to see a vertx implementation of the verifier.
โน๏ธ If you have a question, please post it on the Okta Developer Forum instead. Issues in this repository are reserved for bug reports and feature requests only.
Upgrading from 0.5.4
-> 0.5.5
results in a NoClassDefFoundError
Behavior remains unchanged.
The following stacktrace illustrates the issue, related to exclusion of the kotlin stdlib in #130
java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics
at okhttp3.ConnectionPool.<init>(ConnectionPool.kt)
at okhttp3.ConnectionPool.<init>(ConnectionPool.kt:47)
at okhttp3.OkHttpClient$Builder.<init>(OkHttpClient.kt:471)
at com.okta.commons.http.okhttp.OkHttpRequestExecutor.createOkHttpClient([OkHttpRequestExecutor.java:73]
at com.okta.commons.http.okhttp.OkHttpRequestExecutor.([OkHttpRequestExecutor.java:62]
at com.okta.commons.http.okhttp.OkHttpRequestExecutorFactory.create([OkHttpRequestExecutorFactory.java:58]
at com.okta.jwt.impl.http.OktaCommonsHttpClient.createRequestExecutor([OktaCommonsHttpClient.java:67]
at com.okta.jwt.impl.http.OktaCommonsHttpClient.([OktaCommonsHttpClient.java:47]
at com.okta.jwt.impl.jjwt.BaseVerifierBuilderSupport.httpClient([BaseVerifierBuilderSupport.java:182]
at com.okta.jwt.impl.jjwt.BaseVerifierBuilderSupport.signingKeyResolver([BaseVerifierBuilderSupport.java:166]
at com.okta.jwt.impl.jjwt.JjwtAccessTokenVerifierBuilder.build([JjwtAccessTokenVerifierBuilder.java:58]
at com.okta.jwt.impl.jjwt.JjwtAccessTokenVerifierBuilder.build([JjwtAccessTokenVerifierBuilder.java:27]
Upgrade to 0.5.5
and create an AccessTokenVerifier
something like:
final String issuer = "https://my-oauth-domain/oauth2/default";
final AccessTokenVerifier.Builder builder = JwtVerifiers.accessTokenVerifierBuilder().setIssuer(issuer);
this.verifier = builder.build();
Explicitly re-adding the kotlin stdlib as a direct dependency in the project restores the original behavior, e.g.
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>1.7.20</version>
</dependency>
0.5.5
Hi there,
We have a use case where we would like to decode a JWT token while ignoring the aud
field.
Is it a valid use case? can it somehow be achieved with the latest version?
in case it's not possible - as a 2nd best, I found functionality in the nodeJs library that we can use:
https://github.com/okta/okta-oidc-js/tree/master/packages/jwt-verifier#how-to-use
where we can pass the audience dynamically to the decode call (rather then to the builder) - is that likely to be part of the Java lib anytime soon?
Thanks
I was originally using my own implementation of a JWT verifier based on nimbus' jwt jose library, but kept getting "com.nimbusds.jwt.SignedJWT@4dc6c945 : Signed JWT rejected: Another algorithm expected, or no matching key(s) found"
So I found this library, and followed the example on the first page https://github.com/okta/okta-jwt-verifier-java
I get the same exception. code is currently:
JwtVerifier jwtVerifier = new JwtHelper()
.setIssuerUrl("https://dev-******.oktapreview.com/oauth2/default")
.setAudience("api://default") // defaults to 'api://default'
.setConnectionTimeout(1000) // defaults to 1000ms
.setReadTimeout(1000) // defaults to 1000ms
.setClientId("******") // optional
.build();
String accessToken = "eyJ******";
Jwt jwt = jwtVerifier.decodeAccessToken(accessToken);
And fails on "build". I've masked my okta domain and client id and accessToken. I don't see how I can make this simpler than this. Maybe my Okta config is wrong?
Exception is:
Exception in thread "main" com.okta.jwt.JoseException: Failed to validate JWT string
at com.okta.jwt.impl.NimbusJwtVerifier.decode(NimbusJwtVerifier.java:82)
at com.okta.jwt.impl.NimbusJwtVerifier.decodeAccessToken(NimbusJwtVerifier.java:68)
at veeva.vdm.auth.core.Sandbox.main(Sandbox.java:31)
Caused by: com.nimbusds.jose.proc.BadJOSEException: Signed JWT rejected: Another algorithm expected, or no matching key(s) found
at com.nimbusds.jwt.proc.DefaultJWTProcessor.(DefaultJWTProcessor.java:100)
at com.okta.jwt.JwtHelper.build(JwtHelper.java:92)
at veeva.vdm.auth.core.Sandbox.main(Sandbox.java:23)
Additional note: I am using the following tool to get the accessToken to test with: https://oidcdebugger.com/
This specific method returns null map which was resulting in following exception: java.lang.IllegalArgumentException
: A signing key must be specified if the specified JWT is digitally signed. I could see in debug mode that the key is retrieved and should pass both filters (sig - public key use, RSA - key type) and go into .map/.collect. This wasn't happening. I copied the code into my own java class, was trying to work out whenever i had a free moment and the problem lies with collection to map. it just cannot see the key and value of AbstractMap this way. I got it working in my local code but obviously this needs to be fixed on library level. This is my fixed code:
Map<String, Key> newKeys = (Map) keys.stream()
.filter(jwkKey -> "sig".equals(jwkKey.getPublicKeyUse()) &&
"RSA".equals(jwkKey.getKeyType()))
.collect(Collectors.toMap(key -> key.getKeyId(), key -> {
BigInteger modulus = base64ToBigInteger(key.getPublicKeyModulus());
BigInteger exponent = base64ToBigInteger(key.getPublicKeyExponent());
RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(modulus, exponent);
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(rsaPublicKeySpec);
return publicKey;
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
throw new IllegalStateException("Failed to parse public key");
}}));
Much appreciated,
Ania Richardson
Hello,
currently I have an issue with my api authentication.
Setup:
I'm building a basic Ktor API and provided an Authentication feature to validate Okta accessTokens.
Via a swagger UI I login at okta and retrieve my accessToken, which contains an issuer:
"iss": "https://dev-ylqkdtaqkg6cqazy.eu.auth0.com/"
When I am using the accessTokenVerifier to validate and verify the incoming accessToken using the following builder
JwtVerifiers.accessTokenVerifierBuilder()
.setIssuer("https://dev-ylqkdtaqkg6cqazy.eu.auth0.com/")
.setAudience("api://default")
.build()
I get an exception that issuer claim does not match
Caused by: io.jsonwebtoken.IncorrectClaimException: Expected iss claim to be: https://dev-ylqkdtaqkg6cqazy.eu.auth0.com, but was: https://dev-ylqkdtaqkg6cqazy.eu.auth0.com/.
Checking the BaseVerifierBuilderSupport it seams like the trailing slash was removed, when setIssuer() is called
What can I do, as the issuer in the accessToken comes from auth0 as well. See my openid-configuration
https://dev-ylqkdtaqkg6cqazy.eu.auth0.com/.well-known/openid-configuration
Regards
I am writing an authorizer that will verify a given access token using the readme file in this repository. However, I keep getting the below error whenever the code tries to create AccessTokenVerifier
class.
An instance of the implementation of AccessTokenVerifier
must be returned instead.
Here is my pom.xml
file's dependencies section and the dependency tree.
<dependencies>
<!-- AWS -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>3.10.0</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-log4j2</artifactId>
<version>1.2.0</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
<!-- Testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.0.0</version>
<scope>test</scope>
</dependency>
<!-- Okta verifier -->
<dependency>
<groupId>com.okta.jwt</groupId>
<artifactId>okta-jwt-verifier</artifactId>
<version>0.5.1</version>
</dependency>
<dependency>
<groupId>com.okta.jwt</groupId>
<artifactId>okta-jwt-verifier-impl</artifactId>
<version>0.5.1</version>
<scope>runtime</scope>
</dependency>
</dependencies>
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ api ---
[INFO] com.doosan.sa:api:jar:1.0-SNAPSHOT
[INFO] +- com.amazonaws:aws-lambda-java-core:jar:1.2.1:compile
[INFO] +- com.amazonaws:aws-lambda-java-events:jar:3.10.0:compile
[INFO] | \- joda-time:joda-time:jar:2.6:compile
[INFO] +- com.amazonaws:aws-lambda-java-log4j2:jar:1.2.0:compile
[INFO] | +- (com.amazonaws:aws-lambda-java-core:jar:1.2.1:compile - omitted for duplicate)
[INFO] | +- org.apache.logging.log4j:log4j-core:jar:2.13.2:compile
[INFO] | | \- (org.apache.logging.log4j:log4j-api:jar:2.13.2:compile - omitted for duplicate)
[INFO] | \- org.apache.logging.log4j:log4j-api:jar:2.13.2:compile
[INFO] +- org.projectlombok:lombok:jar:1.18.22:compile
[INFO] +- junit:junit:jar:4.13.2:test
[INFO] | \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] +- org.mockito:mockito-core:jar:4.0.0:test
[INFO] | +- net.bytebuddy:byte-buddy:jar:1.11.19:test
[INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.11.19:test
[INFO] | \- org.objenesis:objenesis:jar:3.2:test
[INFO] +- com.okta.jwt:okta-jwt-verifier:jar:0.5.1:compile
[INFO] \- com.okta.jwt:okta-jwt-verifier-impl:jar:0.5.1:runtime
[INFO] +- (com.okta.jwt:okta-jwt-verifier:jar:0.5.1:runtime - omitted for duplicate)
[INFO] +- com.okta.commons:okta-config-check:jar:1.2.5:runtime
[INFO] | \- (org.slf4j:slf4j-api:jar:1.7.29:runtime - omitted for duplicate)
[INFO] +- com.okta.commons:okta-commons-lang:jar:1.2.5:runtime
[INFO] | \- (org.slf4j:slf4j-api:jar:1.7.29:runtime - omitted for duplicate)
[INFO] +- com.okta.commons:okta-http-api:jar:1.2.5:runtime
[INFO] | +- (com.okta.commons:okta-commons-lang:jar:1.2.5:runtime - omitted for duplicate)
[INFO] | \- (org.slf4j:slf4j-api:jar:1.7.29:runtime - omitted for duplicate)
[INFO] +- com.okta.commons:okta-http-okhttp:jar:1.2.5:runtime
[INFO] | +- (com.okta.commons:okta-http-api:jar:1.2.5:runtime - omitted for duplicate)
[INFO] | +- (com.squareup.okhttp3:okhttp:jar:3.14.4:runtime - omitted for conflict with 4.9.1)
[INFO] | \- org.slf4j:jcl-over-slf4j:jar:1.7.29:runtime
[INFO] | \- (org.slf4j:slf4j-api:jar:1.7.29:runtime - omitted for duplicate)
[INFO] +- org.slf4j:slf4j-api:jar:1.7.29:runtime
[INFO] +- io.jsonwebtoken:jjwt-api:jar:0.11.2:runtime
[INFO] +- io.jsonwebtoken:jjwt-impl:jar:0.11.2:runtime
[INFO] | \- (io.jsonwebtoken:jjwt-api:jar:0.11.2:runtime - omitted for duplicate)
[INFO] +- io.jsonwebtoken:jjwt-jackson:jar:0.11.2:runtime
[INFO] | +- (io.jsonwebtoken:jjwt-api:jar:0.11.2:runtime - omitted for duplicate)
[INFO] | \- (com.fasterxml.jackson.core:jackson-databind:jar:2.9.10.4:runtime - omitted for conflict with 2.12.1)
[INFO] +- com.fasterxml.jackson.core:jackson-annotations:jar:2.12.1:runtime
[INFO] +- com.fasterxml.jackson.core:jackson-databind:jar:2.12.1:runtime
[INFO] | +- (com.fasterxml.jackson.core:jackson-annotations:jar:2.12.1:runtime - omitted for duplicate)
[INFO] | \- com.fasterxml.jackson.core:jackson-core:jar:2.12.1:runtime
[INFO] \- com.squareup.okhttp3:okhttp:jar:4.9.1:runtime
[INFO] +- com.squareup.okio:okio:jar:2.8.0:runtime
[INFO] | +- (org.jetbrains.kotlin:kotlin-stdlib:jar:1.4.0:runtime - omitted for conflict with 1.4.10)
[INFO] | \- org.jetbrains.kotlin:kotlin-stdlib-common:jar:1.4.0:runtime
[INFO] \- org.jetbrains.kotlin:kotlin-stdlib:jar:1.4.10:runtime
[INFO] +- (org.jetbrains.kotlin:kotlin-stdlib-common:jar:1.4.10:runtime - omitted for conflict with 1.4.0)
[INFO] \- org.jetbrains:annotations:jar:13.0:runtime
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
I see here com.okta.jwt:okta-jwt-verifier:jar:0.5.1:runtime - omitted for duplicate
and I suppose that may be the cause. But I tried many ways to resolve it but nothing worked.
What am I missing?
0.5.1
This would be better to have a concrete class, rather than a Map
.
I'd prefer not to have to cast / pattern match / infer types when interacting with this API.
Reference for the upstream library is: https://github.com/jwtk/jjwt/blob/master/api/src/main/java/io/jsonwebtoken/Claims.java
First class support for scp
is also desireable.
(e.g. create a Claims that extends that interface, and adds the scp
)
Best Regards,
Eric
Submitting a feature request for token introspection method so that a separate code for API call will not have to be developed.
Token Introspection with Okta Introspect API
I tried to use this dependancy in spring webflux library but i am getting error. Please help me is there any way to do custom validation for signature and scopes using oauth2 okta in spring webflux reactive APIs.
I'm interested in using #117 :)
โน๏ธ If you have a question, please post it on the Okta Developer Forum instead. Issues in this repository are reserved for bug reports and feature requests only.
Describe your issue or request here (if necessary).
we are using OKTA verifier for OKTA token offline validation. Sometime we got the exceptions message while parsing the token. It is inconsistency
<dependency>
<groupId>com.okta.jwt</groupId>
<artifactId>okta-jwt-verifier</artifactId>
<version>${okta-jwt.version}</version>
</dependency>
<dependency>
<groupId>com.okta.jwt</groupId>
<artifactId>okta-jwt-verifier-impl</artifactId>
<version>${okta-jwt.version}</version>
<scope>runtime</scope>
</dependency>
Version details: 0.4.1
StackTrace details :
com.okta.jwt.JwtVerificationException: Failed to parse token
at com.okta.jwt.impl.jjwt.TokenVerifierSupport.decode(TokenVerifierSupport.java:67)
at com.okta.jwt.impl.jjwt.JjwtAccessTokenVerifier.decode(JjwtAccessTokenVerifier.java:45)
at com.pgs.subsurface.util.JwtTokenProvider.resolveTokenDetails(JwtTokenProvider.java:40)
at com.pgs.subsurface.util.CommonFunctionUtil.fetchJWTClaimValues(CommonFunctionUtil.java:17)
at com.pgs.subsurface.service.HelperService.extractedLogCheck(HelperService.java:237)
at com.pgs.subsurface.controller.ReferenceController.getProductCatagory(ReferenceController.java:63)
at jdk.internal.reflect.GeneratedMethodAccessor112.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:626)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: io.jsonwebtoken.JwtException: Failed to fetch keys from URL: https://XXXXXXXXXXXXX/oauth2/default/v1/keys
at com.okta.jwt.impl.jjwt.RemoteJwkSigningKeyResolver.updateKeys(RemoteJwkSigningKeyResolver.java:95)
at com.okta.jwt.impl.jjwt.RemoteJwkSigningKeyResolver.getKey(RemoteJwkSigningKeyResolver.java:69)
at com.okta.jwt.impl.jjwt.RemoteJwkSigningKeyResolver.resolveSigningKey(RemoteJwkSigningKeyResolver.java:54)
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:376)
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:550)
at com.okta.jwt.impl.jjwt.TokenVerifierSupport.decode(TokenVerifierSupport.java:61)
... 58 more
Caused by: java.net.SocketTimeoutException: connect timed out
Version upgraded form 0.4.1 to 0.5.6:
Exception details: Unable to execute HTTP request - retryable exception: timeout
Configuration Value:
Connection timedout - 1 seconds
retryAttempt: 2
retryMaxElapsed: 10
Could you please help on this.
Here the exception stacktrace:
com.okta.jwt.JoseException: Failed to validate JWT string
at com.okta.jwt.impl.NimbusJwtVerifier.decode(NimbusJwtVerifier.java:82)
at com.okta.jwt.impl.NimbusJwtVerifier.decodeAccessToken(NimbusJwtVerifier.java:68)
at com.cuebiq.apigateway.handler.OktaAuthHandler.handle(OktaAuthHandler.kt:23)
at com.cuebiq.apigateway.handler.OktaAuthHandler.handle(OktaAuthHandler.kt:11)
at io.vertx.reactivex.ext.web.Route$1.handle(Route.java:155)
at io.vertx.reactivex.ext.web.Route$1.handle(Route.java:153)
at io.vertx.ext.web.impl.RouteImpl.handleContext(RouteImpl.java:219)
at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:120)
at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:133)
at io.vertx.ext.web.impl.RouterImpl.accept(RouterImpl.java:79)
at io.vertx.reactivex.ext.web.Router.accept(Router.java:94)
at com.cuebiq.apigateway.verticle.ApiGatewayVerticle$startHttpServer$1.invoke(ApiGatewayVerticle.kt:75)
at com.cuebiq.apigateway.verticle.ApiGatewayVerticle$startHttpServer$1.invoke(ApiGatewayVerticle.kt:20)
at com.cuebiq.apigateway.verticle.ApiGatewayVerticleKt$sam$Handler$4b7b53e4.handle(ApiGatewayVerticle.kt)
at io.vertx.reactivex.core.http.HttpServer$1.handle(HttpServer.java:111)
at io.vertx.reactivex.core.http.HttpServer$1.handle(HttpServer.java:109)
at io.vertx.core.http.impl.Http1xServerConnection.processMessage(Http1xServerConnection.java:454)
at io.vertx.core.http.impl.Http1xServerConnection.handleMessage(Http1xServerConnection.java:144)
at io.vertx.core.http.impl.HttpServerImpl$ServerHandlerWithWebSockets.handleMessage(HttpServerImpl.java:669)
at io.vertx.core.http.impl.HttpServerImpl$ServerHandlerWithWebSockets.handleMessage(HttpServerImpl.java:622)
at io.vertx.core.net.impl.VertxHandler.lambda$channelRead$1(VertxHandler.java:146)
at io.vertx.core.impl.ContextImpl.lambda$wrapTask$2(ContextImpl.java:337)
at io.vertx.core.impl.ContextImpl.executeFromIO(ContextImpl.java:195)
at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:144)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.vertx.core.http.impl.HttpServerImpl$Http2UpgradeHandler.channelRead(HttpServerImpl.java:970)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:284)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1359)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:935)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:141)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)
Caused by: com.nimbusds.jose.proc.BadJOSEException: Signed JWT rejected: Another algorithm expected, or no matching key(s) found
at com.nimbusds.jwt.proc.DefaultJWTProcessor.<clinit>(DefaultJWTProcessor.java:100)
at com.okta.jwt.JwtHelper.build(JwtHelper.java:92)
at com.cuebiq.apigateway.handler.OktaAuthHandler.handle(OktaAuthHandler.kt:19)
... 45 more
Root cause seems to be: Signed JWT rejected: Another algorithm expected, or no matching key(s)
Here my configuration of JWTVerifier:
val jwtVerifier = JwtHelper()
.setIssuerUrl("https://dev-826799.oktapreview.com/oauth2/default")
.setAudience("api://default") // defaults to 'api://default'
.setConnectionTimeout(1000) // defaults to 1000ms
.setReadTimeout(1000) // defaults to 1000ms
.setClientId("0oafjb9h4f3lcTja20h7") // optional
.build()
what's happening?
To help avoid misconfiguration, this library should implement these checks against common errors: https://oktawiki.atlassian.net/wiki/spaces/PM/pages/552049922/Library+configuration+checks
For this library, these checks apply:
Additionally, make sure these placeholders are always used in documentation or samples:
https://{yourOktaDomain}
(not {yourOktaDomain}.com
){clientId}
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.