Comments (18)
Does RegistryRequestModifier
, used by HttpLib.modifyByService
work for you? It can add the header.
https://jena.apache.org/documentation/sparql-apis/#customization-of-http-requests
4.5.0 has been built and is currently awaiting the VOTE from the PMC.
The build uses the Apache release configuration of the maven release plugin. If the version moves on,
from jena.
Hi Andy, thanks alot - the snippet below works:
String bearerToken = "SECRET";
HttpRequestModifier modifier = (params, headers) -> {
headers.put("Authorization", "Bearer " + bearerToken);
};
RegistryRequestModifier.get().add(url, modifier);
However, there is a minor follow up issue:
If the bearer token times out, then first a message is logged such as:
Bearer error="invalid_token", error_description="An error occurred while attempting to decode the Jwt: Jwt expired at 2022-05-03T20:22:50Z", error_uri="https://tools.ietf.org/html/rfc6750#section-3.1"
but then it causes a non-ideal NPE in AuthLib.authenticateHeader:
public class AuthLib {
private static AuthChallenge authenticateHeader(HttpResponse<?> httpResponse) {
List<String> headers = httpResponse.headers().allValues("WWW-Authenticate");
if ( headers.size() == 0 )
return null;
// Choose first digest or first basic.
AuthChallenge aHeader = null;
String result = null;
for ( String headerValue : headers ) {
AuthChallenge aHeader2 = AuthChallenge.parse(headerValue);
if ( aHeader2 == null )
AuthEnv.LOG.warn("Bad authentication response - ignored: "+headerValue);
// Prefer Digest
switch(aHeader2.authScheme) { // BUG: If aHeader2 is null we get a NPE here
case DIGEST :
return aHeader2;
case BASIC:
/* .. */
from jena.
That would have happened if an AuthModifier
were used.
It needs AuthScheme
extending and AuthChallenge.parse
etc changing. Then there needs to be a recovery or more likely, passing on up the 401.
What else needs to accommodate that?
from jena.
Some context so we can build or simulate test cases:
- What software system are you calling?
- What
WWW-Authentication
header do you get back?
from jena.
The software is a commercial product from @eccenca called corporate memory (cmem) which is a knowledge graph platform - which means it combines sparql enpdoint, workflow engine, interlinking, vocabulary management, user management, etc + user interfaces. It also uses Apache Jena in the backend.
So far I haven't used auth much, therefore I am not very familiar with the issues that arise with latest Jena and how to best address them - but maybe @seebi and his team (from eccenca) have already done some deeper investigation with tasks/issues on their backlog.
curl -I
on the currently private cmem instance yields:
HTTP/2 401
server: nginx/1.21.6
date: Tue, 03 May 2022 21:32:52 GMT
vary: Origin,Access-Control-Request-Method,Access-Control-Request-Headers
www-authenticate: Bearer
from jena.
HI together, this is our architecture.
The sparql endpoint is a resource server in an oauth2 zone used together with keycloak.
You could do something similar e.g. with oauth2 proxy ...
from jena.
Could you test for other things that might be needed by avoiding the NPE so the system returns without NPE?
It really would be helpful to get all the points enumerated where "bearer" matters and not deal with them one by one.
from jena.
The new title is a bit broad. What is the scope? Just handling "Authorization: Bearer"? There isn't a general way to process a 401 because obtaining the token involves both local context and scheme-specific choices as well as timeouts.
On the Fuseki side, I'm adding a servlet filter for handling "Authorization: Bearer" (for the day job) for JWT. A fuseki module is probably the way to go because the token needs handling per-bearer scheme and local auth services.
from jena.
I've been working with oauth in the past days and IMHO just handling Authorization: Bearer
should be enough.
I managed to use spring security to authenticate with my local test app that I registered with my gitlab account .
Because obtaining the bearer token is 'app-driven' I'd say its an application's concern to pass on the bearer token to components such as Jena remote sparql requests. It may make sense having a global callback registry in Jena for getting notified about failed authentications so that an application can then take action, such as redirecting the user to repeat the auth process.
from jena.
The application sees a failed authentication as an exception 401.
Fixes and improvements in #1301. HTTP authentication is a bit squirly because of legacy cases.
Adding challenge handling for bearer auth is probably doable but it's yet another step. Rather than delay everything PR #1301 at least fixes the original problems and should work when the bearer token is added - failure is a 401 exception.
One case is that the token is being passed along a path service requests and code in the 401 handler may find it hard to give transparent. PR #1301 at least fixes the original problems and should work when the bearer token is added.
@seebi -- I'm guessing that in your architecture, the token is added before the original request and not based on a HTTP challenge. Is that correct?
Testing the PR would be great - this is quite sensitive to the execution environment (and my reading of the RFCs!).
from jena.
@seebi -- I'm guessing that in your architecture, the token is added before the original request and not based on a HTTP challenge. Is that correct?
correct, the token is fetched from a different component (e.g. keycloak) and then added to all requests.
from jena.
@Aklakan Do you need help in testing this?
from jena.
The current PR needs the bearer token provided.
@seebi sounds like our setup - we don't involve 401, the token is known to be needed and is always added.
from jena.
mhmm .. In our case requests without a token return a 401
∴ curl -H "Authorization: Bearer $(cmemc admin token)" "$(cmemc config get DP_API_ENDPOINT)/proxy/default/sparql"
{"title":"Bad Request","status":400,"detail":"Required request parameter 'query' for method parameter type String is not present"}
∴ curl "$(cmemc config get DP_API_ENDPOINT)/proxy/default/sparql"
{"title":"Unauthorized","status":401,"detail":"Full authentication is required to access this resource"}
from jena.
As it stand currently, the PR will not crash (NPE) in the Jena client-side code for SPARQL operations when encountering bearer auth. Challenges for basic and digest are handled internally with registered user-password (no change there). Bearer auth is different because the app needs to get the token and tokens may have a limited lifetime.
This PR is the necessary part : #1292 (comment)
Adding challenge handling for bearer auth is probably doable but it's yet another step. Rather than delay everything PR #1301 at least fixes the original problems and should work when the bearer token is added - failure is a 401 exception.
The first one is a 400 due to the lack of ?query=
. Presumably authentication should have been done before request parsing and so did happen.
The second is 401 and the calling code should either have added the token (@Aklakan current solution) or caught the 401 and retried with a token added. There is no Jena there that I can see.
The best Jena client-library can do is have a registry of callbacks so 401 causes a call out to app code to provide the token (see the current AuthRequestModifier
which can add HTTP headers based on target URI @Aklakan has been using). Something to do carefully to avoid security leaks in multi-tenant situations.
from jena.
#1335 provides code to handle a 401 challenge for bearer tokens. It calls back into the application to get a token.
from jena.
So I can confirm that the solution from more than an hour ago seems satisfactory to me - using an invalid token or none at all against a bearer-token-protected endpoint resulted in 401 rather than NPE:
Caused by: org.apache.jena.atlas.web.HttpException: 401 - Unauthorized
at org.apache.jena.http.HttpLib.exception(HttpLib.java:231)
at org.apache.jena.http.HttpLib.handleHttpStatusCode(HttpLib.java:161)
Andy just added a new PR like 30min ago which I haven't tried yet.
from jena.
Thanks.
The new commit adds some helper support (AuthEnv.setBearerToken
, AuthEnv.setBearerTokenProvider
) for ahead-of-time setting the token and challenge response handling.
The test suite covers requests with ahead of time registration of a token and with responses to a 401 challenge.
Almost everything to do with bearer auth involves application supplied code to access the deployment environment.
from jena.
Related Issues (20)
- Use PrefixMappingBase for BufferingPrefixMapping
- Update `PrefixMappingImpl` prefix checking rule to align with Turtle and XML 1.1
- a Fuseki Jetty server behind an Apache HTTPd proxy-pass HOT 17
- Remove Fuseki system database
- QueryExec: abort before exec is ignored.
- RDFParserBuilder.toDatasetGraph() is much slower than calling RDFParserBuilder.parse(DatasetGraph) HOT 3
- RDF Patch Binary Reader silently accepts some invalid patch files HOT 4
- Support for multi-variable join keys
- improve arq command line documentation
- Incorrect JoinClassifier results with unbound values.
- Fix broken Fuseki when using a context path in the URL
- Update the lexical space and value space of rdf:XMLLiteral to comply with RDF 1.1 HOT 2
- Remove commons-cli dependency from jena-core
- Update various @Deprecation to include "forRemoval"
- The CORS filter has references to Jetty code.
- Make jena-fuseki-core independent of Eclipse Jetty
- Lookup script name "javascript"
- Fuseki WAR file fails to start HOT 1
- vite-plugin-istanbul 6.0.1+ not compatible with Fuseki UI build. HOT 1
- moving/renaming `:jena-ontapi` vocabularies.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from jena.