You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jena.apache.org by Arthur Vaïsse-Lesteven <ar...@yahoo.fr> on 2013/06/21 08:51:35 UTC

Tr : Basic Authentication for SPARQL Update

Hi Rob, I'm in trouble with the basic authentication process ( I'm now using ARQ 2.10.1 )


In one hand the Queries work like this : 
when we calls one of the 4 method execX of a queryExecution, the QueryEngineHTTP calls makeHttpQuery, and after few steps this code line is executed : 
    httpConnection.setRequestProperty("Authorization", "Basic "+y) ;
where y contains userName:password 64Bits encrypted.

This make the http request header contains the Key, Value couple : "Authorization" "Basic username:password".

I'm OK with this.

In the other hand, the update seem to handle Basic Authentication in a different way.

I used this code :

UpdateRequest update =
 UpdateFactory.create(queryString);    
UpdateProcessRemoteForm exec = (UpdateProcessRemoteForm) UpdateExecutionFactory.createRemoteForm(update, service);
exec.setAuthentication("arnaud@gmail.com", "savaillon".toCharArray());

And I'm unable to retrieve the usename and the password.
Request contains following fields :
In headers : 
content-lenght : 273
content-type : application/x-www-form-urlencoded; charset=UTF-8
host : localhost:8080
conection : Keep-Alive
user-agent: Apache-HttpClient/4.2.3 (java 1.5)
In params : 
update : my update
No attribute.

I tried to follow in the ARQ library the path of my username and password, and finally they transited to the applyAuthentication in HttpOp.

This method create a CredentialsProvider and set the credentials username and
 password. But this method has a void return type, and I don't see any communication point with the rest of the HttpOp code.

Do I missed something ?

VAÏSSE-LESTEVEN Arthur.


>I was using the 2.9.2 ARQ version. I'll update to 2.10.1.
>Thanks for your quick answer and for your work  Rob!
>
>VAÏSSE-LESTEVEN Arthur.
>
>
>>What version of ARQ are you using?
>>
>>I put changes in place which went into the 2.10.1 release which should
>>permit easy HTTP auth on SPARQL updates.  Both
>>UpdateExecutionFactory.createRemote() and
>>UpdateExecutionFactory.createRemoteForm() return an instance derived from
>>UpdateProcessRemoteBase which has a setAuthentication() method
>>
>>If you are using a version of ARQ prior to 2.10.0 there is no common base
>>class but both UpdateProcessRemote and UpdateProcessRemoteForm
 would still
>>have a setHttpContext() method which allows you to pass in a HttpContext
>>which can be used to pass in authentication settings using the HttpClient
>>APIs.  Even with 2.10.1 you can still choose to use this method
>>particularly if you need to pass complex credentials.
>>
>>Rob
>>
>>
>>On 6/18/13 8:10 AM, "Arthur Vaïsse-Lesteven" <ar...@yahoo.fr> wrote:
>>
>>>Hi,
>>>
>>>
>>>The remote execution of SPARQL queries offer the setBasicAuthentication
>>>fonctionality(1). I'm using it; and when I tried to use it with SPARQL
>>>Update it appears that SPARQL Update doesn't handle Authentication.
>>>I would like to know, do it exist any way to do the same thing in ARQ ? I
>>>writted some code by extending 2 apache classes, but it would be
 better
>>>to just use the API. Do you intend to not allow basicAuthentification ?
>>>It is incompatible with http basic authentication ? There are only
>>>24hours per day and you don't had the time to do it yet ?
>>>
>>>Do this functionality is planed ?
>>>
>>>________________________________________________________________________
>>>
>>>(1) What i can write :
>>>
>>>[...]
>>>
>>>
>>>QueryEngineHTTP exec = (QueryEngineHTTP)
>>>QueryExecutionFactory.createServiceRequest(endpoint_URL, query);
>>>exec.setBasicAuthentication(user, password);
>>>
>>>exec.exec...
>>>
>>>[...]
>>>
>>>(2)What I want to write :
>>>
>>>[...]
>>>UpdateProcessRemote exec =
 (UpdateProcessRemote)
>>>UpdateExecutionFactory.createRemote(update, endpoint_URL);
>>>exec.setBasicAuthentication(user, password);
>>>
>>>exec.excute();
>>>
>>>[...]
>>>
>>>
>>>
>>>I tried to custom the UpdateProcessRemote class to allow (2). This
>>>currently don't work on my computer, but it seem's to be due to a maven
>>>version conflict at level of HttpClient. This class must be compatible
>>>with current version of Jena.( I set my modifications in bold ).( also
>>>downlodable at : http://arthurvaisse.free.fr/classes/ )
>>>
>>>Thank you,
>>>VAÏSSE-LESTEVEN Arthur.
>>>
>>>
>>>________________________________________________________________________
>>>
>>>public class UpdateProcessRemote
 implements UpdateProcessor{
>>>
>>>    private String user = null ;
>>>    private char[] password = null ;
>>>
>>>    private final UpdateRequest request ;
>>>    private final String endpoint ;
>>>
>>>    public UpdateProcessRemote(UpdateRequest request , String endpoint )
>>>    {
>>>        this.request = request ;
>>>        this.endpoint = endpoint ;
>>>
>>> }
>>>
>>>    @Override
>>>    public void setInitialBinding(QuerySolution binding)
>>>    {
>>>        throw new ARQException("Initial bindings
 for a remote update
>>>execution request not supported") ;
>>>    }
>>>
>>>    @Override
>>>    public GraphStore getGraphStore()
>>>    {
>>>        return null ;
>>>    }
>>>
>>>    @Override
>>>    public void execute()
>>>    {
>>>        String reqStr = request.toString() ;
>>>      HttpOpCustom.execHttpPost(endpoint,
>>>WebContent.contentTypeSPARQLUpdate, reqStr, user, password);
>>>    }
>>>
>>>    //comes from QueryEngineHTTP.
>>>    public void
 setBasicAuthentication(String user, char[] password)
>>>
>>> {
>>>        this.user = user ;
>>>        this.password = password ;
>>>    }
>>>________________________________________________________________________
>>>
>>>I added this functions to HttpOp to create my custom HttpOp :
>>>
>>>    //Just added credentials in parameters
>>>    public static void execHttpPost(String url, String contentType,
>>>String content, String user, char[] password)
>>>    {
>>>        execHttpPost(url, contentType, content, null, null, user,
>>>password) ;
>>>   
 }
>>>
>>>
>>>    //Just added credentials in parameters
>>>    public static void execHttpPost(String url, String contentType,
>>>String content,
>>>            String acceptType, Map<String, HttpResponseHandler> handlers,
>>>            String user, char[] password)
>>>    {
>>>        StringEntity e = null ;
>>>        try
>>>        {
>>>            e = new StringEntity(content, "UTF-8") ;
>>>           
 e.setContentType(contentType) ;
>>>            execHttpPost(url, e, acceptType, handlers, user, password) ;
>>>        } catch (UnsupportedEncodingException e1)
>>>        {
>>>            throw new ARQInternalErrorException("Platform does not
>>>support required UTF-8") ;
>>>        } finally { closeEntity(e) ; }
>>>    }
>>>
>>>
>>>    public static void execHttpPost(String url,  HttpEntity provider,
>>>            String acceptType, Map<String, HttpResponseHandler>
 handlers,
>>>            String user, char[] password)
>>>    {
>>>        try {
>>>            long id = counter.incrementAndGet() ;
>>>            String requestURI = determineBaseIRI(url) ;
>>>            String baseIRI = determineBaseIRI(requestURI) ;
>>>
>>>            HttpPost httppost = new HttpPost(requestURI);
>>>
>>>            if ( user != null || password !=
 null){
>>>                if(user==null || password == null){
>>>                    log.warn("Only one of user/password is set") ;
>>>                }
>>>                //this code come from httpQuery
>>>                StringBuffer x = new StringBuffer() ;
>>>                byte b[] =
>>>x.append(user).append(":").append(password).toString().getBytes("UTF-8")
 ;
>>>                String y = Base64.encodeBase64String(b) ;
>>>                //this single code line is mine
>>>                httppost.addHeader("Authorization", "Basic "+y);
>>>            }
>>>            if ( log.isDebugEnabled() )
>>>                log.debug(format("[%d] %s %s",id
>>>,httppost.getMethod(),httppost.getURI().toString())) ;
>>>
>>>            if (
 provider.getContentType() == null )
>>>                log.debug(format("[%d] No content type")) ;
>>>
>>>            // Execute
>>>            HttpClient httpclient = new DefaultHttpClient();
>>>            httppost.setEntity(provider) ;
>>>            HttpResponse response = httpclient.execute(httppost) ;
>>>            httpResponse(id, response, baseIRI, handlers) ;
>>>
>>>           
 httpclient.getConnectionManager().shutdown();
>>>        } catch (IOException ex)
>>>        {
>>>            ex.printStackTrace(System.err) ;
>>>        }
>>>        finally { closeEntity(provider) ; }
>>>    }

Re: Tr : Basic Authentication for SPARQL Update

Posted by Arthur Vaïsse-Lesteven <ar...@yahoo.fr>.
Hi again Rob.

Finally it works, the error was mine.

You said : "You appear to have missed the point of my previous email, your proxy is not doing Proxy Authentication properly."

And you were right. I was misunderstanding how authentication works. Just sending correct error code and correct header was enought to solve the problem. ( Thank to point me the RFC )

It's just ... disconcerting that the two remote request type in ARQ has not the same default behaviour. I'll live with it !

Thank to you Rob for your time and your work.

VAISSE-LESTEVEN Arthur.



________________________________
 De : Rob Vesse <rv...@yarcdata.com>
À : Arthur Vaïsse-Lesteven <ar...@yahoo.fr> 
Envoyé le : Jeudi 27 juin 2013 18h18
Objet : Re: Tr : Basic Authentication for SPARQL Update
 


You appear to have missed the point of my previous email, your proxy is not doing Proxy Authentication properly.

Per the HTTP 1.1 specification (RFC 2616 - http://www.ietf.org/rfc/rfc2616.txt)

10.4.8 407 Proxy Authentication Required
This code is similar to 401 (Unauthorized), but indicates that the client must first authenticate itself with the proxy. The proxy MUST return a Proxy-Authenticate header field (section 14.33) containing a challenge applicable to the proxy for the requested resource. The client MAY repeat the request with a suitable Proxy-Authorization header field (section 14.34). HTTP access authentication is explained in "HTTP Authentication: Basic and Digest Access Authentication" [43].

This is confirmed by the fact that in your HTTP trace I see the following:

53    10:34:45,650 DEBUG [SystemDefaultHttpClient:98] Response contains no authentication challenges

As you failed to send the required Proxy-Authenticate header (you are sending WWW-Authenticate instead which is for non-proxy auth) with your 407 the HttpClient cannot respond appropriately because it can't find the challenge.

Also as I previously pointed out your proxy should be expecting a Proxy-Authorization header in response to a 407 not a Authorization header which again is for non-proxy authentication.

Rob
From: Arthur Vaïsse-Lesteven <ar...@yahoo.fr>
Reply-To: Arthur Vaïsse-Lesteven <ar...@yahoo.fr>
Date: Thursday, June 27, 2013 4:24 AM
To: Rob Vesse <rv...@yarcdata.com>, "users@jena.apache.org" <us...@jena.apache.org>
Subject: Re: Tr : Basic Authentication for SPARQL Update


Hi again Rob.
>
>
>It seems that the HttpClient do not respond to 407 challenges.
>
>
>My proxy contain this code:
>
>
>
>
>   class MyProxyClass extends HTTPServlet {
>
>
>        [...]
>
>
>        String[] credentials = extractCredentials(req);
>
>
>        
>
>        if( credentials == null || credentials.length != 2){
>            resp.addHeader("WWW-Authenticate", "BASIC realm=\"realm\"");
>            resp.sendError(HttpServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED);
>        }
>
>
>        [...]
>
>
>    }
>
>
>
>And with the debug mode activated we get this execution trace :
>
>
>1    10:34:45,260 DEBUG [FileManager:155] Add location: LocatorFile
>2    10:34:45,262 DEBUG [FileManager:155] Add location: ClassLoaderLocator
>3    10:34:45,263 DEBUG [LocationMapper:153] Failed to find configuration: file:location-mapping.rdf;file:location-mapping.n3;file:location-mapping.ttl;file:etc/location-mapping.rdf;file:etc/location-mapping.n3;file:etc/location-mapping.ttl
>4    10:34:45,263 DEBUG [FileManager:155] Add location: LocatorFile
>5    10:34:45,264 DEBUG [FileManager:155] Add location: LocatorURL
>6    10:34:45,264 DEBUG [FileManager:155] Add location: ClassLoaderLocator
>7    10:34:45,374 DEBUG [ARQMgt:99] Register MBean: org.apache.jena.arq.system:type=Context
>8    10:34:45,374 DEBUG [ARQMgt:99] Register MBean: org.apache.jena.arq.system:type=Engine
>9    10:34:45,382 DEBUG [ARQMgt:99] Register MBean: org.apache.jena.arq.system:type=SystemInfo
>10    10:34:45,383 DEBUG [ARQMgt:99] Register MBean: org.apache.jena.riot.system:type=SystemInfo
>11    {symbol:http://jena.hpl.hp.com/Service#queryAuthUser=arnaud@gmail.com, symbol:http://jena.hpl.hp.com/Service#queryAuthPwd=savaillon}
>12    10:34:45,459 DEBUG [HttpOp:321] [1] POST http://localhost:8080/Proxy/proxy_update
>13    10:34:45,602 DEBUG [PoolingClientConnectionManager:186] Connection request: [route: {}->http://localhost:8080][total kept alive: 0; route allocated: 0 of 5; total allocated: 0 of 10]
>14    10:34:45,611 DEBUG [PoolingClientConnectionManager:220] Connection leased: [id: 0][route: {}->http://localhost:8080][total kept alive: 0; route allocated: 1 of 5; total allocated: 1 of 10]
>15    10:34:45,612 DEBUG [DefaultClientConnectionOperator:177] Connecting to localhost:8080
>16    10:34:45,624 DEBUG [RequestAddCookies:132] CookieSpec selected: best-match
>17    10:34:45,632 DEBUG [RequestAuthCache:78] Auth cache not set in the context
>18    10:34:45,633 DEBUG [RequestTargetAuthentication:78] Target auth state: UNCHALLENGED
>19    10:34:45,633 DEBUG [RequestProxyAuthentication:87] Proxy auth state: UNCHALLENGED
>20    10:34:45,633 DEBUG [SystemDefaultHttpClient:715] Attempt 1 to execute request
>21    10:34:45,633 DEBUG [DefaultClientConnection:269] Sending request: POST /Proxy/proxy_update HTTP/1.1
>22    10:34:45,634 DEBUG [wire:63] >> "POST /Proxy/proxy_update HTTP/1.1[\r][\n]"
>23    10:34:45,635 DEBUG [wire:63] >> "Content-Length: 273[\r][\n]"
>24    10:34:45,635 DEBUG [wire:63] >> "Content-Type: application/x-www-form-urlencoded; charset=UTF-8[\r][\n]"
>25    10:34:45,635 DEBUG [wire:63] >> "Host: localhost:8080[\r][\n]"
>26    10:34:45,635 DEBUG [wire:63] >> "Connection: Keep-Alive[\r][\n]"
>27    10:34:45,635 DEBUG [wire:63] >> "User-Agent: Apache-HttpClient/4.2.3 (java 1.5)[\r][\n]"
>28    10:34:45,635 DEBUG [wire:63] >> "[\r][\n]"
>29    10:34:45,635 DEBUG [headers:273] >> POST /Proxy/proxy_update HTTP/1.1
>30    10:34:45,635 DEBUG [headers:276] >> Content-Length: 273
>31    10:34:45,636 DEBUG [headers:276] >> Content-Type: application/x-www-form-urlencoded; charset=UTF-8
>32    10:34:45,636 DEBUG [headers:276] >> Host: localhost:8080
>33    10:34:45,636 DEBUG [headers:276] >> Connection: Keep-Alive
>34    10:34:45,636 DEBUG [headers:276] >> User-Agent: Apache-HttpClient/4.2.3 (java 1.5)
>35    10:34:45,636 DEBUG [wire:77] >> "update=INSERT+DATA+%7B%0A++GRAPH+%3Chttp%3A%2F%2Fexample.com%23Public_Graphe%3E+%7B%0A++++%3Chttp%3A%2F%2Fexample.com%23ProofOfConcept%3E+%3Chttp%3A%2F%2Fexample.com%23enjeux%3E+%22Capital%22%5E%5E%3Chttp%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema%23string%3E+.%0A++%7D%0A%7D%0A"
>36    10:34:45,644 DEBUG [wire:63] << "HTTP/1.1 407 Authentification de Relais N?cessaire[\r][\n]"
>37    10:34:45,646 DEBUG [wire:63] << "Server: Apache-Coyote/1.1[\r][\n]"
>38    10:34:45,646 DEBUG [wire:63] << "WWW-Authenticate: BASIC realm="realm"[\r][\n]"
>39    10:34:45,646 DEBUG [wire:63] << "Content-Type: text/html;charset=utf-8[\r][\n]"
>40    10:34:45,646 DEBUG [wire:63] << "Content-Length: 973[\r][\n]"
>41    10:34:45,646 DEBUG [wire:63] << "Date: Thu, 27 Jun 2013 08:34:45 GMT[\r][\n]"
>42    10:34:45,646 DEBUG [wire:63] << "[\r][\n]"
>43    10:34:45,647 DEBUG [DefaultClientConnection:254] Receiving response: HTTP/1.1 407 Authentification de Relais Nécessaire
>44    10:34:45,647 DEBUG [headers:257] << HTTP/1.1 407 Authentification de Relais Nécessaire
>45    10:34:45,647 DEBUG [headers:260] << Server: Apache-Coyote/1.1
>46    10:34:45,647 DEBUG [headers:260] << WWW-Authenticate: BASIC realm="realm"
>47    10:34:45,647 DEBUG [headers:260] << Content-Type: text/html;charset=utf-8
>48    10:34:45,647 DEBUG [headers:260] << Content-Length: 973
>49    10:34:45,647 DEBUG [headers:260] << Date: Thu, 27 Jun 2013 08:34:45 GMT
>50    10:34:45,649 DEBUG [SystemDefaultHttpClient:545] Connection can be kept alive indefinitely
>51    10:34:45,650 DEBUG [SystemDefaultHttpClient:67] Authentication required
>52    10:34:45,650 DEBUG [SystemDefaultHttpClient:94] localhost:8080 requested authentication
>53    10:34:45,650 DEBUG [SystemDefaultHttpClient:98] Response contains no authentication challenges
>54    10:34:45,651 DEBUG [HttpOp:459] [1] 407 Authentification de Relais Nécessaire
>55    10:34:45,651 DEBUG [wire:77] << "<html><head><title>Apache Tomcat/7.0.40 - Rapport d''erreur</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;}
 H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A
 {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>Etat HTTP 407 - </h1><HR size="1" noshade="noshade"><p><b>type</b> Rapport d''[0xc3][0xa9]tat</p><p><b>message</b> <u></u></p><p><b>description</b> <u>Le client doit d''abord
 s''authentifier aupr[0xc3][0xa8]s du relais.</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/7.0.40</h3></body></html>"
>56    10:34:45,651 DEBUG [PoolingClientConnectionManager:274] Connection [id: 0][route: {}->http://localhost:8080] can be kept alive indefinitely
>57    10:34:45,652 DEBUG [PoolingClientConnectionManager:281] Connection released: [id: 0][route: {}->http://localhost:8080][total kept alive: 1; route allocated: 1 of 5; total allocated: 1 of 10]
>
>
>
>
>Debug line 43 to 49 show that my proxy send a 407 error code with the following header : [WWW-Authenticate: BASIC realm="realm"]. The HTTPClient do not react by re-sending an HTTP request with credentials.
>
>
>VAISSE-LESTEVEN Arthur
>
>
>
>
>________________________________
> De : Rob Vesse <rv...@yarcdata.com>
>À : Arthur Vaïsse-Lesteven <ar...@yahoo.fr> 
>Envoyé le : Mercredi 26 juin 2013 18h33
>Objet : Re: Tr : Basic Authentication for SPARQL Update
>
>
>
>It sounds like your proxy is not doing HTTP Challenge Response properly, if it is a proxy it should be expecting Proxy-Authenticate header as part of the request following a 407 Proxy Authenticate challenge.
>
>
>Typically the way HTTP auth works is that the client tries to make a request without auth credentials, the server responds with a 401 Unauthorized/407 Proxy Authenticate with appropriate headers indicated how it wants the client to authenticate and then if possible the client makes an additional HTTP request this time including the appropriate authentication headers (Authorization/Proxy Authorization)
>
>
>So there are two possibilities here:
>
>
>1 – HttpClient does not automatically respond to 407 challenges (some googling suggests this it should respond to 407 fine)
>2 – Your proxy is not challenging properly
>
>
>Wrt query there appears to be no issue because that code pre-authenticates, this essentially trades security for the performance gain of avoiding the challenge response.  However looking at that code (which I didn't write) I'm not sure that this behavior is even correct because in principal it won't authenticate properly for proxies which should be expecting the Proxy-Authorization header rather than Authorization header.
>
>
>In principal HttpClient usage can be changed to do pre-emptive authentication but I am reluctant to trade off security for the update case, and as noted above you have to be careful how you pre-authenticate depending on whether the target server is doing standard/proxy auth.
>
>
>It would be interesting to see a complete HTTP trace of the update case, turning on DEBUG level logging should give you this as HttpClient has pretty verbose logging when turned up.
>
>
>Rob
>
>From: Arthur Vaïsse-Lesteven <ar...@yahoo.fr>
>Reply-To: Arthur Vaïsse-Lesteven <ar...@yahoo.fr>
>Date: Wednesday, June 26, 2013 1:02 AM
>To: "users@jena.apache.org" <us...@jena.apache.org>, Rob Vesse <rv...@yarcdata.com>
>Subject: Re: Tr : Basic Authentication for SPARQL Update
>
>
>
>>Is there any HTTP proxying/redirection involved in your setup?
>>No. The only proxy is the SPARQL proxy that I'm coding. It is based on the work of wimmic team ( http://wimmics.inria.fr/projects/shi3ld/ ).
>>
>>This is my code :
>>
>>The query engine Http add to the HTTP Header ("Authorization", "Basic <username>:<password>") where user informations are 64Bits encoded.
>>My test consist in sending request to the proxy ( no redirection involved, the user credentials check is done by the proxy ).
>>For the sparql queries ( SELECT/ASK/DESCRIBE/CONSTRUCT ) I use this code in order to extract credentials :
>>
>>    import org.apache.commons.codec.binary.Base64;
>>    import org.apache.commons.codec.binary.StringUtils;
>>    
>>    protected String[] extractCredentials(HttpServletRequest req){
>>        String auth = req.getHeader("Authorization");
>>        if( auth == null || !(auth.toUpperCase().startsWith("BASIC")) ){return null;} 
>>        return this.decode(auth.substring(6)).split(":"); 
>>    }
>>    
>>    private String decode(String s) {
>>        return StringUtils.newStringUtf8(Base64.decodeBase64(s));
>>    }
>>
>>The UpdateProcessRemoteForm don't add anything to header during my test. I do this :
>>
>>    UpdateRequest update = UpdateFactory.create(queryString);    
>>    UpdateProcessRemoteForm exec = (UpdateProcessRemoteForm) UpdateExecutionFactory.createRemoteForm(update, service);
>>    exec.setAuthentication("arthurvaisse@yahoo.fr", "test".toCharArray());
>>    exec.execute();   
>>
>>And as there is no header corresponding to the key "Authorization" my proxy send a 407 error ( authentication required ).
>>
>>>>>>>Request contains following fields :
>>>>>>>In headers :
>>>>>>>content-lenght : 273
>>>>>>>content-type : application/x-www-form-urlencoded; charset=UTF-8
>>>>>>>host : localhost:8080
>>>>>>>conection : Keep-Alive
>>>>>>>user-agent: Apache-HttpClient/4.2.3 (java 1.5)
>>
>>Maybe your code is working but work in an other way ?
>>
>>VAISSE-LESTEVEN Arthur.
>>
>>>I added simple basic auth support to Fuseki and wrote unit tests that
>>>verified that authentication is working correctly.
>>>
>>>It would be useful to know what error code/messages you get with the
>>>latest SNAPSHOTs?
>>>
>>>Is there any HTTP proxying/redirection involved in your setup?
>>>
>>>The applyAuthentication() code scopes provided credentials to the given
>>>service URI so if the server is responding with a 401 Unauthorized on a
>>>different URI from the original request then HTTP Client may be failing to
>>>attempt to pass any credentials at all in response to the servers
>>>challenge and simply bailing out and throwing up the 401 error
>>>
>>>Rob
>>>
>>>
>>>On 6/25/13 2:44 AM, "Arthur Vaïsse-Lesteven" <ar...@yahoo.fr> wrote:
>>>
>>>>
>>>>Hi again.
>>>>
>>>>It seems that the bug is still present. The HTTPheader not contains
>>>>basicAuthentification informations. What test did you do about the new
>>>>httpOp ? I may doing it in a wrong way :/
>>>>
>>>>After the debugged applyAuthentication in HttpOp, there is the following
>>>>line : "HttpResponse response = httpclient.execute(httppost,
>>>>httpContext);"
>>>>
>>>>And I think that the HttpClient.execute method doesn't use the
>>>>authentication information available in his Credential provider.
>>>>
>>>>Rob : "Don't forget you can always check out and do a mvn install locally"
>>>>Ho yes, I'll do that next time!
>>>>
>>>>VAÏSSE-LESTEVEN Arthur.
>>>>
>>>>
>>>>>Hmmm, that is a little weird
>>>>>
>>>>>I just forced a rebuild and the latest build does have the change in it,
>>>>>not sure what happened there. Sometimes the Apache build servers are
>>>>>just a little flaky.
>>>>>
>>>>>Don't forget you can always check out and do a mvn install locally
>>>>>
>>>>>Rob
>>>>>
>>>>>From: Arthur Vaïsse-Lesteven
>>>>><ar...@yahoo.fr>>
>>>>>Reply-To: "users@jena.apache.org<ma...@jena.apache.org>"
>>>>><us...@jena.apache.org>>, Arthur
>>>>>Vaïsse-Lesteven <ar...@yahoo.fr>>
>>>>>Date: Monday, June 24, 2013 5:26 AM
>>>>>To: "users@jena.apache.org<ma...@jena.apache.org>"
>>>>><us...@jena.apache.org>>
>>>>>Subject: Re: Tr : Basic Authentication for SPARQL Update
>>>>>
>>>>>Hi Rob,
>>>>>
>>>>>It's a little confusing.
>>>>>
>>>>>You modified the HttpOp class in the release number 34 on the maven repo
>>>>>[1], but this modification isn't present in the last version ( 38 ) as
>>>>>you can see in the java file joined to this mail.
>>>>>
>>>>>The add of "client.setCredentialsProvider(provider);" line 400 probably
>>>>>solve the problem but I'm not able to test it as it isn't present in the
>>>>>last released version of ARQ.
>>>>>
>>>>>( The trunk version of your SVN seems to contains this code too ).
>>>>>
>>>>>Thanks for your work.
>>>>>
>>>>>VAISSE-LESTEVEN Arthur.
>>>>>
>>>>>
>>>>>[1]
>>>>>https://repository.apache.org/content/repositories/snapshots/org/apache/j
>>>>>ena/jena-arq/2.10.2-SNAPSHOT/
>>>>>________________________________
>>>>>De : Rob Vesse <rv...@yarcdata.com>>
>>>>>À : "users@jena.apache.org<ma...@jena.apache.org>"
>>>>><us...@jena.apache.org>>
>>>>>Envoyé le : Vendredi 21 juin 2013 19h35
>>>>>Objet : Re: Tr : Basic Authentication for SPARQL Update
>>>>>
>>>>>The latest SNAPSHOTS now have the fix, you may need to add -U to your mvn
>>>>>calls if you have recently updated SNAPSHOTs to get the very latest
>>>>>
>>>>>Please test and confirm whether this resolves the issue
>>>>>
>>>>>Rob
>>>>>
>>>>>
>>>>>On 6/21/13 9:13 AM, "Rob Vesse"
>>>>><rv...@cray.com>> wrote:
>>>>>
>>>>>>Nice catch
>>>>>>
>>>>>>Yes I appear to have made an error, I never associated the created
>>>>>>credentials provider with the HTTP Client
>>>>>>
>>>>>>Filed as JENA-475 (https://issues.apache.org/jira/browse/JENA-475)
>>>>>>
>>>>>>I will commit a fix ASAP and you should be able to pick up a
>>>>>>2.10.2-SNAPSHOT build in a few hours with the fix, if you can test with
>>>>>>the snapshot and report if this resolves the issue that would be great.
>>>>>>
>>>>>>You can verify whether the fix has gone into the snapshots by looking at
>>>>>>https://builds.apache.org/job/Jena__Development_Test/changes and seeing
>>>>>>if
>>>>>>there is a build listed where the commit messages mention JENA-475
>>>>>>
>>>>>>Rob
>>>>>>
>>>>>>
>>>>>>
>>>>>>On 6/20/13 11:51 PM, "Arthur Vaïsse-Lesteven"
>>>>>><ar...@yahoo.fr>>
>>>>>>wrote:
>>>>>>
>>>>>>>Hi Rob, I'm in trouble with the basic authentication process ( I'm now
>>>>>>>using ARQ 2.10.1 )
>>>>>>>
>>>>>>>
>>>>>>>In one hand the Queries work like this :
>>>>>>>when we calls one of the 4 method execX of a queryExecution, the
>>>>>>>QueryEngineHTTP calls makeHttpQuery, and after few steps this code line
>>>>>>>is executed :
>>>>>>>    httpConnection.setRequestProperty("Authorization", "Basic "+y) ;
>>>>>>>where y contains userName:password 64Bits encrypted.
>>>>>>>
>>>>>>>This make the http request header contains the Key, Value couple :
>>>>>>>"Authorization" "Basic username:password".
>>>>>>>
>>>>>>>I'm OK with this.
>>>>>>>
>>>>>>>In the other hand, the update seem to handle Basic Authentication in a
>>>>>>>different way.
>>>>>>>
>>>>>>>I used this code :
>>>>>>>
>>>>>>>UpdateRequest update =
>>>>>>> UpdateFactory.create(queryString);
>>>>>>>UpdateProcessRemoteForm exec = (UpdateProcessRemoteForm)
>>>>>>>UpdateExecutionFactory.createRemoteForm(update, service);
>>>>>>>exec.setAuthentication("arnaud@gmail.com<ma...@gmail.com>",
>>>>>>>"savaillon".toCharArray());
>>>>>>>
>>>>>>>And I'm unable to retrieve the usename and the password.
>>>>>>>Request contains following fields :
>>>>>>>In headers :
>>>>>>>content-lenght : 273
>>>>>>>content-type : application/x-www-form-urlencoded; charset=UTF-8
>>>>>>>host : localhost:8080
>>>>>>>conection : Keep-Alive
>>>>>>>user-agent: Apache-HttpClient/4.2.3 (java 1.5)
>>>>>>>In params :
>>>>>>>update : my update
>>>>>>>No attribute.
>>>>>>>
>>>>>>>I tried to follow in the ARQ library the path of my username and
>>>>>>>password, and finally they transited to the applyAuthentication in
>>>>>>>HttpOp.
>>>>>>>
>>>>>>>This method create a CredentialsProvider and set the credentials
>>>>>>>username
>>>>>>>and
>>>>>>> password. But this method has a void return type, and I don't see any
>>>>>>>communication point with the rest of the HttpOp code.
>>>>>>>
>>>>>>>Do I missed something ?
>>>>>>>
>>>>>>>VAÏSSE-LESTEVEN Arthur.
>>>>>>>
>>>>>>>
>>>>>>>>I was using the 2.9.2 ARQ version. I'll update to 2.10.1.
>>>>>>>>Thanks for your quick answer and for your work  Rob!
>>>>>>>>
>>>>>>>>VAÏSSE-LESTEVEN Arthur.
>>>>>>>>
>>>>>>>>
>>>>>>>>>What version of ARQ are you using?
>>>>>>>>>
>>>>>>>>>I put changes in place which went into the 2.10.1 release which
>>>>>>>>>should
>>>>>>>>>permit easy HTTP auth on SPARQL updates.  Both
>>>>>>>>>UpdateExecutionFactory.createRemote() and
>>>>>>>>>UpdateExecutionFactory.createRemoteForm() return an instance derived
>>>>>>>>>from
>>>>>>>>>UpdateProcessRemoteBase which has a setAuthentication() method
>>>>>>>>>
>>>>>>>>>If you are using a version of ARQ prior to 2.10.0 there is no common
>>>>>>>>>base
>>>>>>>>>class but both UpdateProcessRemote and UpdateProcessRemoteForm
>>>>>>> would still
>>>>>>>>>have a setHttpContext() method which allows you to pass in a
>>>>>>>>>HttpContext
>>>>>>>>>which can be used to pass in authentication settings using the
>>>>>>>>>HttpClient
>>>>>>>>>APIs.  Even with 2.10.1 you can still choose to use this method
>>>>>>>>>particularly if you need to pass complex credentials.
>>>>>>>>>
>>>>>>>>>Rob
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>On 6/18/13 8:10 AM, "Arthur Vaïsse-Lesteven"
>>>>>>>>><ar...@yahoo.fr>>
>>>>>>>>>wrote:
>>>>>>>>>
>>>>>>>>>>Hi,
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>The remote execution of SPARQL queries offer the
>>>>>>>>>>setBasicAuthentication
>>>>>>>>>>fonctionality(1). I'm using it; and when I tried to use it with
>>>>>>>>>>SPARQL
>>>>>>>>>>Update it appears that SPARQL Update doesn't handle Authentication.
>>>>>>>>>>I would like to know, do it exist any way to do the same thing in
>>>>>>>>>>ARQ
>>>>>>>>>>? I
>>>>>>>>>>writted some code by extending 2 apache classes, but it would be
>>>>>>> better
>>>>>>>>>>to just use the API. Do you intend to not allow
>>>>>>>>>>basicAuthentification
>>>>>>>>>>?
>>>>>>>>>>It is incompatible with http basic authentication ? There are only
>>>>>>>>>>24hours per day and you don't had the time to do it yet ?
>>>>>>>>>>
>>>>>>>>>>Do this functionality is planed ?
>>>>>>>>>>
>>>>>>>>>>____________________________________________________________________
>>>>>>>>>>__
>>>>>>>>>>_
>>>>>>>>>>_
>>>>>>>>>>
>>>>>>>>>>(1) What i can write :
>>>>>>>>>>
>>>>>>>>>>[...]
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>QueryEngineHTTP exec = (QueryEngineHTTP)
>>>>>>>>>>QueryExecutionFactory.createServiceRequest(endpoint_URL, query);
>>>>>>>>>>exec.setBasicAuthentication(user, password);
>>>>>>>>>>
>>>>>>>>>>exec.exec...
>>>>>>>>>>
>>>>>>>>>>[...]
>>>>>>>>>>
>>>>>>>>>>(2)What I want to write :
>>>>>>>>>>
>>>>>>>>>>[...]
>>>>>>>>>>UpdateProcessRemote exec =
>>>>>>> (UpdateProcessRemote)
>>>>>>>>>>UpdateExecutionFactory.createRemote(update, endpoint_URL);
>>>>>>>>>>exec.setBasicAuthentication(user, password);
>>>>>>>>>>
>>>>>>>>>>exec.excute();
>>>>>>>>>>
>>>>>>>>>>[...]
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>I tried to custom the UpdateProcessRemote class to allow (2). This
>>>>>>>>>>currently don't work on my computer, but it seem's to be due to a
>>>>>>>>>>maven
>>>>>>>>>>version conflict at level of HttpClient. This class must be
>>>>>>>>>>compatible
>>>>>>>>>>with current version of Jena.( I set my modifications in bold ).(
>>>>>>>>>>also
>>>>>>>>>>downlodable at : http://arthurvaisse.free.fr/classes/ )
>>>>>>>>>>
>>>>>>>>>>Thank you,
>>>>>>>>>>VAÏSSE-LESTEVEN Arthur.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>____________________________________________________________________
>>>>>>>>>>__
>>>>>>>>>>_
>>>>>>>>>>_
>>>>>>>>>>
>>>>>>>>>>public class UpdateProcessRemote
>>>>>>> implements UpdateProcessor{
>>>>>>>>>>
>>>>>>>>>>    private String user = null ;
>>>>>>>>>>    private char[] password = null ;
>>>>>>>>>>
>>>>>>>>>>    private final UpdateRequest request ;
>>>>>>>>>>    private final String endpoint ;
>>>>>>>>>>
>>>>>>>>>>    public UpdateProcessRemote(UpdateRequest request , String
>>>>>>>>>>endpoint
>>>>>>>>>>)
>>>>>>>>>>    {
>>>>>>>>>>        this.request = request ;
>>>>>>>>>>        this.endpoint = endpoint ;
>>>>>>>>>>
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>>    @Override
>>>>>>>>>>    public void setInitialBinding(QuerySolution binding)
>>>>>>>>>>    {
>>>>>>>>>>        throw new ARQException("Initial bindings
>>>>>>> for a remote update
>>>>>>>>>>execution request not supported") ;
>>>>>>>>>>    }
>>>>>>>>>>
>>>>>>>>>>    @Override
>>>>>>>>>>    public GraphStore getGraphStore()
>>>>>>>>>>    {
>>>>>>>>>>        return null ;
>>>>>>>>>>    }
>>>>>>>>>>
>>>>>>>>>>    @Override
>>>>>>>>>>    public void execute()
>>>>>>>>>>    {
>>>>>>>>>>        String reqStr = request.toString() ;
>>>>>>>>>>      HttpOpCustom.execHttpPost(endpoint,
>>>>>>>>>>WebContent.contentTypeSPARQLUpdate, reqStr, user, password);
>>>>>>>>>>    }
>>>>>>>>>>
>>>>>>>>>>    //comes from QueryEngineHTTP.
>>>>>>>>>>    public void
>>>>>>> setBasicAuthentication(String user, char[] password)
>>>>>>>>>>
>>>>>>>>>> {
>>>>>>>>>>        this.user = user ;
>>>>>>>>>>        this.password = password ;
>>>>>>>>>>    }
>>>>>>>>>>____________________________________________________________________
>>>>>>>>>>__
>>>>>>>>>>_
>>>>>>>>>>_
>>>>>>>>>>
>>>>>>>>>>I added this functions to HttpOp to create my custom HttpOp :
>>>>>>>>>>
>>>>>>>>>>    //Just added credentials in parameters
>>>>>>>>>>    public static void execHttpPost(String url, String contentType,
>>>>>>>>>>String content, String user, char[] password)
>>>>>>>>>>    {
>>>>>>>>>>        execHttpPost(url, contentType, content, null, null, user,
>>>>>>>>>>password) ;
>>>>>>>>>>
>>>>>>> }
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>    //Just added credentials in parameters
>>>>>>>>>>    public static void execHttpPost(String url, String contentType,
>>>>>>>>>>String content,
>>>>>>>>>>            String acceptType, Map<String, HttpResponseHandler>
>>>>>>>>>>handlers,
>>>>>>>>>>            String user, char[] password)
>>>>>>>>>>    {
>>>>>>>>>>        StringEntity e = null ;
>>>>>>>>>>        try
>>>>>>>>>>        {
>>>>>>>>>>            e = new StringEntity(content, "UTF-8") ;
>>>>>>>>>>
>>>>>>> e.setContentType(contentType) ;
>>>>>>>>>>            execHttpPost(url, e, acceptType, handlers, user,
>>>>>>>>>>password)
>>>>>>>>>>;
>>>>>>>>>>        } catch (UnsupportedEncodingException e1)
>>>>>>>>>>        {
>>>>>>>>>>            throw new ARQInternalErrorException("Platform does not
>>>>>>>>>>support required UTF-8") ;
>>>>>>>>>>        } finally { closeEntity(e) ; }
>>>>>>>>>>    }
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>    public static void execHttpPost(String url,  HttpEntity
>>>>>>>>>>provider,
>>>>>>>>>>            String acceptType, Map<String, HttpResponseHandler>
>>>>>>> handlers,
>>>>>>>>>>            String user, char[] password)
>>>>>>>>>>    {
>>>>>>>>>>        try {
>>>>>>>>>>            long id = counter.incrementAndGet() ;
>>>>>>>>>>            String requestURI = determineBaseIRI(url) ;
>>>>>>>>>>            String baseIRI = determineBaseIRI(requestURI) ;
>>>>>>>>>>
>>>>>>>>>>            HttpPost httppost = new HttpPost(requestURI);
>>>>>>>>>>
>>>>>>>>>>            if ( user != null || password !=
>>>>>>> null){
>>>>>>>>>>                if(user==null || password == null){
>>>>>>>>>>                    log.warn("Only one of user/password is set") ;
>>>>>>>>>>                }
>>>>>>>>>>                //this code come from httpQuery
>>>>>>>>>>                StringBuffer x = new StringBuffer() ;
>>>>>>>>>>                byte b[] =
>>>>>>>>>>x.append(user).append(":").append(password).toString().getBytes("UTF
>>>>>>>>>>-8
>>>>>>>>>>"
>>>>>>>>>>)
>>>>>>> ;
>>>>>>>>>>                String y = Base64.encodeBase64String(b) ;
>>>>>>>>>>                //this single code line is mine
>>>>>>>>>>                httppost.addHeader("Authorization", "Basic "+y);
>>>>>>>>>>            }
>>>>>>>>>>            if ( log.isDebugEnabled() )
>>>>>>>>>>                log.debug(format("[%d] %s %s",id
>>>>>>>>>>,httppost.getMethod(),httppost.getURI().toString())) ;
>>>>>>>>>>
>>>>>>>>>>            if (
>>>>>>> provider.getContentType() == null )
>>>>>>>>>>                log.debug(format("[%d] No content type")) ;
>>>>>>>>>>
>>>>>>>>>>            // Execute
>>>>>>>>>>            HttpClient httpclient = new DefaultHttpClient();
>>>>>>>>>>            httppost.setEntity(provider) ;
>>>>>>>>>>            HttpResponse response = httpclient.execute(httppost) ;
>>>>>>>>>>            httpResponse(id, response, baseIRI, handlers) ;
>>>>>>>>>>
>>>>>>>>>>
>>>>>>> httpclient.getConnectionManager().shutdown();
>>>>>>>>>>        } catch (IOException ex)
>>>>>>>>>>        {
>>>>>>>>>>            ex.printStackTrace(System.err) ;
>>>>>>>>>>        }
>>>>>>>>>>        finally { closeEntity(provider) ; }
>>>>>>>>>>    }
>
> 

Re: Tr : Basic Authentication for SPARQL Update

Posted by Arthur Vaïsse-Lesteven <ar...@yahoo.fr>.
Hi again Rob.

It seems that the HttpClient do not respond to 407 challenges.

My proxy contain this code:


   class MyProxyClass extends HTTPServlet {

        [...]

        String[] credentials = extractCredentials(req);

        

        if( credentials == null || credentials.length != 2){
            resp.addHeader("WWW-Authenticate", "BASIC realm=\"realm\"");
            resp.sendError(HttpServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED);
        }

        [...]

    }


And with the debug mode activated we get this execution trace :

1    10:34:45,260 DEBUG [FileManager:155] Add location: LocatorFile
2    10:34:45,262 DEBUG [FileManager:155] Add location: ClassLoaderLocator
3    10:34:45,263 DEBUG [LocationMapper:153] Failed to find configuration: file:location-mapping.rdf;file:location-mapping.n3;file:location-mapping.ttl;file:etc/location-mapping.rdf;file:etc/location-mapping.n3;file:etc/location-mapping.ttl
4    10:34:45,263 DEBUG [FileManager:155] Add location: LocatorFile
5    10:34:45,264 DEBUG [FileManager:155] Add location: LocatorURL
6    10:34:45,264 DEBUG [FileManager:155] Add location: ClassLoaderLocator
7    10:34:45,374 DEBUG [ARQMgt:99] Register MBean: org.apache.jena.arq.system:type=Context
8    10:34:45,374 DEBUG [ARQMgt:99] Register MBean: org.apache.jena.arq.system:type=Engine
9    10:34:45,382 DEBUG [ARQMgt:99] Register MBean: org.apache.jena.arq.system:type=SystemInfo
10    10:34:45,383 DEBUG [ARQMgt:99] Register MBean: org.apache.jena.riot.system:type=SystemInfo
11    {symbol:http://jena.hpl.hp.com/Service#queryAuthUser=arnaud@gmail.com, symbol:http://jena.hpl.hp.com/Service#queryAuthPwd=savaillon}
12    10:34:45,459 DEBUG [HttpOp:321] [1] POST http://localhost:8080/Proxy/proxy_update
13    10:34:45,602 DEBUG [PoolingClientConnectionManager:186] Connection request: [route: {}->http://localhost:8080][total kept alive: 0; route allocated: 0 of 5; total allocated: 0 of 10]
14    10:34:45,611 DEBUG [PoolingClientConnectionManager:220] Connection leased: [id: 0][route: {}->http://localhost:8080][total kept alive: 0; route allocated: 1 of 5; total allocated: 1 of 10]
15    10:34:45,612 DEBUG [DefaultClientConnectionOperator:177] Connecting to localhost:8080
16    10:34:45,624 DEBUG [RequestAddCookies:132] CookieSpec selected: best-match
17    10:34:45,632 DEBUG [RequestAuthCache:78] Auth cache not set in the context
18    10:34:45,633 DEBUG [RequestTargetAuthentication:78] Target auth state: UNCHALLENGED
19    10:34:45,633 DEBUG [RequestProxyAuthentication:87] Proxy auth state: UNCHALLENGED
20    10:34:45,633 DEBUG [SystemDefaultHttpClient:715] Attempt 1 to execute request
21    10:34:45,633 DEBUG [DefaultClientConnection:269] Sending request: POST /Proxy/proxy_update HTTP/1.1
22    10:34:45,634 DEBUG [wire:63] >> "POST /Proxy/proxy_update HTTP/1.1[\r][\n]"
23    10:34:45,635 DEBUG [wire:63] >> "Content-Length: 273[\r][\n]"
24    10:34:45,635 DEBUG [wire:63] >> "Content-Type: application/x-www-form-urlencoded; charset=UTF-8[\r][\n]"
25    10:34:45,635 DEBUG [wire:63] >> "Host: localhost:8080[\r][\n]"
26    10:34:45,635 DEBUG [wire:63] >> "Connection: Keep-Alive[\r][\n]"
27    10:34:45,635 DEBUG [wire:63] >> "User-Agent: Apache-HttpClient/4.2.3 (java 1.5)[\r][\n]"
28    10:34:45,635 DEBUG [wire:63] >> "[\r][\n]"
29    10:34:45,635 DEBUG [headers:273] >> POST /Proxy/proxy_update HTTP/1.1
30    10:34:45,635 DEBUG [headers:276] >> Content-Length: 273
31    10:34:45,636 DEBUG [headers:276] >> Content-Type: application/x-www-form-urlencoded; charset=UTF-8
32    10:34:45,636 DEBUG [headers:276] >> Host: localhost:8080
33    10:34:45,636 DEBUG [headers:276] >> Connection: Keep-Alive
34    10:34:45,636 DEBUG [headers:276] >> User-Agent: Apache-HttpClient/4.2.3 (java 1.5)
35    10:34:45,636 DEBUG [wire:77] >> "update=INSERT+DATA+%7B%0A++GRAPH+%3Chttp%3A%2F%2Fexample.com%23Public_Graphe%3E+%7B%0A++++%3Chttp%3A%2F%2Fexample.com%23ProofOfConcept%3E+%3Chttp%3A%2F%2Fexample.com%23enjeux%3E+%22Capital%22%5E%5E%3Chttp%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema%23string%3E+.%0A++%7D%0A%7D%0A"
36    10:34:45,644 DEBUG [wire:63] << "HTTP/1.1 407 Authentification de Relais N?cessaire[\r][\n]"
37    10:34:45,646 DEBUG [wire:63] << "Server: Apache-Coyote/1.1[\r][\n]"
38    10:34:45,646 DEBUG [wire:63] << "WWW-Authenticate: BASIC realm="realm"[\r][\n]"
39    10:34:45,646 DEBUG [wire:63] << "Content-Type: text/html;charset=utf-8[\r][\n]"
40    10:34:45,646 DEBUG [wire:63] << "Content-Length: 973[\r][\n]"
41    10:34:45,646 DEBUG [wire:63] << "Date: Thu, 27 Jun 2013 08:34:45 GMT[\r][\n]"
42    10:34:45,646 DEBUG [wire:63] << "[\r][\n]"
43    10:34:45,647 DEBUG [DefaultClientConnection:254] Receiving response: HTTP/1.1 407 Authentification de Relais Nécessaire
44    10:34:45,647 DEBUG [headers:257] << HTTP/1.1 407 Authentification de Relais Nécessaire
45    10:34:45,647 DEBUG [headers:260] << Server: Apache-Coyote/1.1
46    10:34:45,647 DEBUG [headers:260] << WWW-Authenticate: BASIC realm="realm"
47    10:34:45,647 DEBUG [headers:260] << Content-Type: text/html;charset=utf-8
48    10:34:45,647 DEBUG [headers:260] << Content-Length: 973
49    10:34:45,647 DEBUG [headers:260] << Date: Thu, 27 Jun 2013 08:34:45 GMT
50    10:34:45,649 DEBUG [SystemDefaultHttpClient:545] Connection can be kept alive indefinitely
51    10:34:45,650 DEBUG [SystemDefaultHttpClient:67] Authentication required
52    10:34:45,650 DEBUG [SystemDefaultHttpClient:94] localhost:8080 requested authentication
53    10:34:45,650 DEBUG [SystemDefaultHttpClient:98] Response contains no authentication challenges
54    10:34:45,651 DEBUG [HttpOp:459] [1] 407 Authentification de Relais Nécessaire
55    10:34:45,651 DEBUG [wire:77] << "<html><head><title>Apache Tomcat/7.0.40 - Rapport d''erreur</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>Etat HTTP 407 - </h1><HR size="1" noshade="noshade"><p><b>type</b> Rapport d''[0xc3][0xa9]tat</p><p><b>message</b> <u></u></p><p><b>description</b> <u>Le client doit d''abord s''authentifier aupr[0xc3][0xa8]s du relais.</u></p><HR
 size="1" noshade="noshade"><h3>Apache Tomcat/7.0.40</h3></body></html>"
56    10:34:45,651 DEBUG [PoolingClientConnectionManager:274] Connection [id: 0][route: {}->http://localhost:8080] can be kept alive indefinitely
57    10:34:45,652 DEBUG [PoolingClientConnectionManager:281] Connection released: [id: 0][route: {}->http://localhost:8080][total kept alive: 1; route allocated: 1 of 5; total allocated: 1 of 10]



Debug line 43 to 49 show that my proxy send a 407 error code with the following header : [WWW-Authenticate: BASIC realm="realm"].The HTTPClient do not react by re-sending an HTTP request with credentials.

VAISSE-LESTEVEN Arthur



________________________________
 De : Rob Vesse <rv...@yarcdata.com>
À : Arthur Vaïsse-Lesteven <ar...@yahoo.fr> 
Envoyé le : Mercredi 26 juin 2013 18h33
Objet : Re: Tr : Basic Authentication for SPARQL Update
 


It sounds like your proxy is not doing HTTP Challenge Response properly, if it is a proxy it should be expecting Proxy-Authenticate header as part of the request following a 407 Proxy Authenticate challenge.

Typically the way HTTP auth works is that the client tries to make a request without auth credentials, the server responds with a 401 Unauthorized/407 Proxy Authenticate with appropriate headers indicated how it wants the client to authenticate and then if possible the client makes an additional HTTP request this time including the appropriate authentication headers (Authorization/Proxy Authorization)

So there are two possibilities here:

1 – HttpClient does not automatically respond to 407 challenges (some googling suggests this it should respond to 407 fine)
2 – Your proxy is not challenging properly

Wrt query there appears to be no issue because that code pre-authenticates, this essentially trades security for the performance gain of avoiding the challenge response.  However looking at that code (which I didn't write) I'm not sure that this behavior is even correct because in principal it won't authenticate properly for proxies which should be expecting the Proxy-Authorization header rather than Authorization header.

In principal HttpClient usage can be changed to do pre-emptive authentication but I am reluctant to trade off security for the update case, and as noted above you have to be careful how you pre-authenticate depending on whether the target server is doing standard/proxy auth.

It would be interesting to see a complete HTTP trace of the update case, turning on DEBUG level logging should give you this as HttpClient has pretty verbose logging when turned up.

Rob
From: Arthur Vaïsse-Lesteven <ar...@yahoo.fr>
Reply-To: Arthur Vaïsse-Lesteven <ar...@yahoo.fr>
Date: Wednesday, June 26, 2013 1:02 AM
To: "users@jena.apache.org" <us...@jena.apache.org>, Rob Vesse <rv...@yarcdata.com>
Subject: Re: Tr : Basic Authentication for SPARQL Update


>Is there any HTTP proxying/redirection involved in your setup?
>No. The only proxy is the SPARQL proxy that I'm coding. It is based on the work of wimmic team ( http://wimmics.inria.fr/projects/shi3ld/ ).
>
>This is my code :
>
>The query engine Http add to the HTTP Header ("Authorization", "Basic <username>:<password>") where user informations are 64Bits encoded.
>My test consist in sending request to the proxy ( no redirection involved, the user credentials check is done by the proxy ).
>For the sparql queries ( SELECT/ASK/DESCRIBE/CONSTRUCT ) I use this code in order to extract credentials :
>
>    import org.apache.commons.codec.binary.Base64;
>    import org.apache.commons.codec.binary.StringUtils;
>    
>    protected String[] extractCredentials(HttpServletRequest req){
>        String auth = req.getHeader("Authorization");
>        if( auth == null || !(auth.toUpperCase().startsWith("BASIC")) ){return null;} 
>        return this.decode(auth.substring(6)).split(":"); 
>    }
>    
>    private String decode(String s) {
>        return StringUtils.newStringUtf8(Base64.decodeBase64(s));
>    }
>
>The UpdateProcessRemoteForm don't add anything to header during my test. I do this :
>
>    UpdateRequest update = UpdateFactory.create(queryString);    
>    UpdateProcessRemoteForm exec = (UpdateProcessRemoteForm) UpdateExecutionFactory.createRemoteForm(update, service);
>    exec.setAuthentication("arthurvaisse@yahoo.fr", "test".toCharArray());
>    exec.execute();   
>
>And as there is no header corresponding to the key "Authorization" my proxy send a 407 error ( authentication required ).
>
>>>>>>Request contains following fields :
>>>>>>In headers :
>>>>>>content-lenght : 273
>>>>>>content-type : application/x-www-form-urlencoded; charset=UTF-8
>>>>>>host : localhost:8080
>>>>>>conection : Keep-Alive
>>>>>>user-agent: Apache-HttpClient/4.2.3 (java 1.5)
>
>Maybe your code is working but work in an other way ?
>
>VAISSE-LESTEVEN Arthur.
>
>>I added simple basic auth support to Fuseki and wrote unit tests that
>>verified that authentication is working correctly.
>>
>>It would be useful to know what error code/messages you get with the
>>latest SNAPSHOTs?
>>
>>Is there any HTTP proxying/redirection involved in your setup?
>>
>>The applyAuthentication() code scopes provided credentials to the given
>>service URI so if the server is responding with a 401 Unauthorized on a
>>different URI from the original request then HTTP Client may be failing to
>>attempt to pass any credentials at all in response to the servers
>>challenge and simply bailing out and throwing up the 401 error
>>
>>Rob
>>
>>
>>On 6/25/13 2:44 AM, "Arthur Vaïsse-Lesteven" <ar...@yahoo.fr> wrote:
>>
>>>
>>>Hi again.
>>>
>>>It seems that the bug is still present. The HTTPheader not contains
>>>basicAuthentification informations. What test did you do about the new
>>>httpOp ? I may doing it in a wrong way :/
>>>
>>>After the debugged applyAuthentication in HttpOp, there is the following
>>>line : "HttpResponse response = httpclient.execute(httppost,
>>>httpContext);"
>>>
>>>And I think that the HttpClient.execute method doesn't use the
>>>authentication information available in his Credential provider.
>>>
>>>Rob : "Don't forget you can always check out and do a mvn install locally"
>>>Ho yes, I'll do that next time!
>>>
>>>VAÏSSE-LESTEVEN Arthur.
>>>
>>>
>>>>Hmmm, that is a little weird
>>>>
>>>>I just forced a rebuild and the latest build does have the change in it,
>>>>not sure what happened there. Sometimes the Apache build servers are
>>>>just a little flaky.
>>>>
>>>>Don't forget you can always check out and do a mvn install locally
>>>>
>>>>Rob
>>>>
>>>>From: Arthur Vaïsse-Lesteven
>>>><ar...@yahoo.fr>>
>>>>Reply-To: "users@jena.apache.org<ma...@jena.apache.org>"
>>>><us...@jena.apache.org>>, Arthur
>>>>Vaïsse-Lesteven <ar...@yahoo.fr>>
>>>>Date: Monday, June 24, 2013 5:26 AM
>>>>To: "users@jena.apache.org<ma...@jena.apache.org>"
>>>><us...@jena.apache.org>>
>>>>Subject: Re: Tr : Basic Authentication for SPARQL Update
>>>>
>>>>Hi Rob,
>>>>
>>>>It's a little confusing.
>>>>
>>>>You modified the HttpOp class in the release number 34 on the maven repo
>>>>[1], but this modification isn't present in the last version ( 38 ) as
>>>>you can see in the java file joined to this mail.
>>>>
>>>>The add of "client.setCredentialsProvider(provider);" line 400 probably
>>>>solve the problem but I'm not able to test it as it isn't present in the
>>>>last released version of ARQ.
>>>>
>>>>( The trunk version of your SVN seems to contains this code too ).
>>>>
>>>>Thanks for your work.
>>>>
>>>>VAISSE-LESTEVEN Arthur.
>>>>
>>>>
>>>>[1]
>>>>https://repository.apache.org/content/repositories/snapshots/org/apache/j
>>>>ena/jena-arq/2.10.2-SNAPSHOT/
>>>>________________________________
>>>>De : Rob Vesse <rv...@yarcdata.com>>
>>>>À : "users@jena.apache.org<ma...@jena.apache.org>"
>>>><us...@jena.apache.org>>
>>>>Envoyé le : Vendredi 21 juin 2013 19h35
>>>>Objet : Re: Tr : Basic Authentication for SPARQL Update
>>>>
>>>>The latest SNAPSHOTS now have the fix, you may need to add -U to your mvn
>>>>calls if you have recently updated SNAPSHOTs to get the very latest
>>>>
>>>>Please test and confirm whether this resolves the issue
>>>>
>>>>Rob
>>>>
>>>>
>>>>On 6/21/13 9:13 AM, "Rob Vesse"
>>>><rv...@cray.com>> wrote:
>>>>
>>>>>Nice catch
>>>>>
>>>>>Yes I appear to have made an error, I never associated the created
>>>>>credentials provider with the HTTP Client
>>>>>
>>>>>Filed as JENA-475 (https://issues.apache.org/jira/browse/JENA-475)
>>>>>
>>>>>I will commit a fix ASAP and you should be able to pick up a
>>>>>2.10.2-SNAPSHOT build in a few hours with the fix, if you can test with
>>>>>the snapshot and report if this resolves the issue that would be great.
>>>>>
>>>>>You can verify whether the fix has gone into the snapshots by looking at
>>>>>https://builds.apache.org/job/Jena__Development_Test/changes and seeing
>>>>>if
>>>>>there is a build listed where the commit messages mention JENA-475
>>>>>
>>>>>Rob
>>>>>
>>>>>
>>>>>
>>>>>On 6/20/13 11:51 PM, "Arthur Vaïsse-Lesteven"
>>>>><ar...@yahoo.fr>>
>>>>>wrote:
>>>>>
>>>>>>Hi Rob, I'm in trouble with the basic authentication process ( I'm now
>>>>>>using ARQ 2.10.1 )
>>>>>>
>>>>>>
>>>>>>In one hand the Queries work like this :
>>>>>>when we calls one of the 4 method execX of a queryExecution, the
>>>>>>QueryEngineHTTP calls makeHttpQuery, and after few steps this code line
>>>>>>is executed :
>>>>>>    httpConnection.setRequestProperty("Authorization", "Basic "+y) ;
>>>>>>where y contains userName:password 64Bits encrypted.
>>>>>>
>>>>>>This make the http request header contains the Key, Value couple :
>>>>>>"Authorization" "Basic username:password".
>>>>>>
>>>>>>I'm OK with this.
>>>>>>
>>>>>>In the other hand, the update seem to handle Basic Authentication in a
>>>>>>different way.
>>>>>>
>>>>>>I used this code :
>>>>>>
>>>>>>UpdateRequest update =
>>>>>> UpdateFactory.create(queryString);
>>>>>>UpdateProcessRemoteForm exec = (UpdateProcessRemoteForm)
>>>>>>UpdateExecutionFactory.createRemoteForm(update, service);
>>>>>>exec.setAuthentication("arnaud@gmail.com<ma...@gmail.com>",
>>>>>>"savaillon".toCharArray());
>>>>>>
>>>>>>And I'm unable to retrieve the usename and the password.
>>>>>>Request contains following fields :
>>>>>>In headers :
>>>>>>content-lenght : 273
>>>>>>content-type : application/x-www-form-urlencoded; charset=UTF-8
>>>>>>host : localhost:8080
>>>>>>conection : Keep-Alive
>>>>>>user-agent: Apache-HttpClient/4.2.3 (java 1.5)
>>>>>>In params :
>>>>>>update : my update
>>>>>>No attribute.
>>>>>>
>>>>>>I tried to follow in the ARQ library the path of my username and
>>>>>>password, and finally they transited to the applyAuthentication in
>>>>>>HttpOp.
>>>>>>
>>>>>>This method create a CredentialsProvider and set the credentials
>>>>>>username
>>>>>>and
>>>>>> password. But this method has a void return type, and I don't see any
>>>>>>communication point with the rest of the HttpOp code.
>>>>>>
>>>>>>Do I missed something ?
>>>>>>
>>>>>>VAÏSSE-LESTEVEN Arthur.
>>>>>>
>>>>>>
>>>>>>>I was using the 2.9.2 ARQ version. I'll update to 2.10.1.
>>>>>>>Thanks for your quick answer and for your work  Rob!
>>>>>>>
>>>>>>>VAÏSSE-LESTEVEN Arthur.
>>>>>>>
>>>>>>>
>>>>>>>>What version of ARQ are you using?
>>>>>>>>
>>>>>>>>I put changes in place which went into the 2.10.1 release which
>>>>>>>>should
>>>>>>>>permit easy HTTP auth on SPARQL updates.  Both
>>>>>>>>UpdateExecutionFactory.createRemote() and
>>>>>>>>UpdateExecutionFactory.createRemoteForm() return an instance derived
>>>>>>>>from
>>>>>>>>UpdateProcessRemoteBase which has a setAuthentication() method
>>>>>>>>
>>>>>>>>If you are using a version of ARQ prior to 2.10.0 there is no common
>>>>>>>>base
>>>>>>>>class but both UpdateProcessRemote and UpdateProcessRemoteForm
>>>>>> would still
>>>>>>>>have a setHttpContext() method which allows you to pass in a
>>>>>>>>HttpContext
>>>>>>>>which can be used to pass in authentication settings using the
>>>>>>>>HttpClient
>>>>>>>>APIs.  Even with 2.10.1 you can still choose to use this method
>>>>>>>>particularly if you need to pass complex credentials.
>>>>>>>>
>>>>>>>>Rob
>>>>>>>>
>>>>>>>>
>>>>>>>>On 6/18/13 8:10 AM, "Arthur Vaïsse-Lesteven"
>>>>>>>><ar...@yahoo.fr>>
>>>>>>>>wrote:
>>>>>>>>
>>>>>>>>>Hi,
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>The remote execution of SPARQL queries offer the
>>>>>>>>>setBasicAuthentication
>>>>>>>>>fonctionality(1). I'm using it; and when I tried to use it with
>>>>>>>>>SPARQL
>>>>>>>>>Update it appears that SPARQL Update doesn't handle Authentication.
>>>>>>>>>I would like to know, do it exist any way to do the same thing in
>>>>>>>>>ARQ
>>>>>>>>>? I
>>>>>>>>>writted some code by extending 2 apache classes, but it would be
>>>>>> better
>>>>>>>>>to just use the API. Do you intend to not allow
>>>>>>>>>basicAuthentification
>>>>>>>>>?
>>>>>>>>>It is incompatible with http basic authentication ? There are only
>>>>>>>>>24hours per day and you don't had the time to do it yet ?
>>>>>>>>>
>>>>>>>>>Do this functionality is planed ?
>>>>>>>>>
>>>>>>>>>____________________________________________________________________
>>>>>>>>>__
>>>>>>>>>_
>>>>>>>>>_
>>>>>>>>>
>>>>>>>>>(1) What i can write :
>>>>>>>>>
>>>>>>>>>[...]
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>QueryEngineHTTP exec = (QueryEngineHTTP)
>>>>>>>>>QueryExecutionFactory.createServiceRequest(endpoint_URL, query);
>>>>>>>>>exec.setBasicAuthentication(user, password);
>>>>>>>>>
>>>>>>>>>exec.exec...
>>>>>>>>>
>>>>>>>>>[...]
>>>>>>>>>
>>>>>>>>>(2)What I want to write :
>>>>>>>>>
>>>>>>>>>[...]
>>>>>>>>>UpdateProcessRemote exec =
>>>>>> (UpdateProcessRemote)
>>>>>>>>>UpdateExecutionFactory.createRemote(update, endpoint_URL);
>>>>>>>>>exec.setBasicAuthentication(user, password);
>>>>>>>>>
>>>>>>>>>exec.excute();
>>>>>>>>>
>>>>>>>>>[...]
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>I tried to custom the UpdateProcessRemote class to allow (2). This
>>>>>>>>>currently don't work on my computer, but it seem's to be due to a
>>>>>>>>>maven
>>>>>>>>>version conflict at level of HttpClient. This class must be
>>>>>>>>>compatible
>>>>>>>>>with current version of Jena.( I set my modifications in bold ).(
>>>>>>>>>also
>>>>>>>>>downlodable at : http://arthurvaisse.free.fr/classes/ )
>>>>>>>>>
>>>>>>>>>Thank you,
>>>>>>>>>VAÏSSE-LESTEVEN Arthur.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>____________________________________________________________________
>>>>>>>>>__
>>>>>>>>>_
>>>>>>>>>_
>>>>>>>>>
>>>>>>>>>public class UpdateProcessRemote
>>>>>> implements UpdateProcessor{
>>>>>>>>>
>>>>>>>>>    private String user = null ;
>>>>>>>>>    private char[] password = null ;
>>>>>>>>>
>>>>>>>>>    private final UpdateRequest request ;
>>>>>>>>>    private final String endpoint ;
>>>>>>>>>
>>>>>>>>>    public UpdateProcessRemote(UpdateRequest request , String
>>>>>>>>>endpoint
>>>>>>>>>)
>>>>>>>>>    {
>>>>>>>>>        this.request = request ;
>>>>>>>>>        this.endpoint = endpoint ;
>>>>>>>>>
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>>    @Override
>>>>>>>>>    public void setInitialBinding(QuerySolution binding)
>>>>>>>>>    {
>>>>>>>>>        throw new ARQException("Initial bindings
>>>>>> for a remote update
>>>>>>>>>execution request not supported") ;
>>>>>>>>>    }
>>>>>>>>>
>>>>>>>>>    @Override
>>>>>>>>>    public GraphStore getGraphStore()
>>>>>>>>>    {
>>>>>>>>>        return null ;
>>>>>>>>>    }
>>>>>>>>>
>>>>>>>>>    @Override
>>>>>>>>>    public void execute()
>>>>>>>>>    {
>>>>>>>>>        String reqStr = request.toString() ;
>>>>>>>>>      HttpOpCustom.execHttpPost(endpoint,
>>>>>>>>>WebContent.contentTypeSPARQLUpdate, reqStr, user, password);
>>>>>>>>>    }
>>>>>>>>>
>>>>>>>>>    //comes from QueryEngineHTTP.
>>>>>>>>>    public void
>>>>>> setBasicAuthentication(String user, char[] password)
>>>>>>>>>
>>>>>>>>> {
>>>>>>>>>        this.user = user ;
>>>>>>>>>        this.password = password ;
>>>>>>>>>    }
>>>>>>>>>____________________________________________________________________
>>>>>>>>>__
>>>>>>>>>_
>>>>>>>>>_
>>>>>>>>>
>>>>>>>>>I added this functions to HttpOp to create my custom HttpOp :
>>>>>>>>>
>>>>>>>>>    //Just added credentials in parameters
>>>>>>>>>    public static void execHttpPost(String url, String contentType,
>>>>>>>>>String content, String user, char[] password)
>>>>>>>>>    {
>>>>>>>>>        execHttpPost(url, contentType, content, null, null, user,
>>>>>>>>>password) ;
>>>>>>>>>
>>>>>> }
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>    //Just added credentials in parameters
>>>>>>>>>    public static void execHttpPost(String url, String contentType,
>>>>>>>>>String content,
>>>>>>>>>            String acceptType, Map<String, HttpResponseHandler>
>>>>>>>>>handlers,
>>>>>>>>>            String user, char[] password)
>>>>>>>>>    {
>>>>>>>>>        StringEntity e = null ;
>>>>>>>>>        try
>>>>>>>>>        {
>>>>>>>>>            e = new StringEntity(content, "UTF-8") ;
>>>>>>>>>
>>>>>> e.setContentType(contentType) ;
>>>>>>>>>            execHttpPost(url, e, acceptType, handlers, user,
>>>>>>>>>password)
>>>>>>>>>;
>>>>>>>>>        } catch (UnsupportedEncodingException e1)
>>>>>>>>>        {
>>>>>>>>>            throw new ARQInternalErrorException("Platform does not
>>>>>>>>>support required UTF-8") ;
>>>>>>>>>        } finally { closeEntity(e) ; }
>>>>>>>>>    }
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>    public static void execHttpPost(String url,  HttpEntity
>>>>>>>>>provider,
>>>>>>>>>            String acceptType, Map<String, HttpResponseHandler>
>>>>>> handlers,
>>>>>>>>>            String user, char[] password)
>>>>>>>>>    {
>>>>>>>>>        try {
>>>>>>>>>            long id = counter.incrementAndGet() ;
>>>>>>>>>            String requestURI = determineBaseIRI(url) ;
>>>>>>>>>            String baseIRI = determineBaseIRI(requestURI) ;
>>>>>>>>>
>>>>>>>>>            HttpPost httppost = new HttpPost(requestURI);
>>>>>>>>>
>>>>>>>>>            if ( user != null || password !=
>>>>>> null){
>>>>>>>>>                if(user==null || password == null){
>>>>>>>>>                    log.warn("Only one of user/password is set") ;
>>>>>>>>>                }
>>>>>>>>>                //this code come from httpQuery
>>>>>>>>>                StringBuffer x = new StringBuffer() ;
>>>>>>>>>                byte b[] =
>>>>>>>>>x.append(user).append(":").append(password).toString().getBytes("UTF
>>>>>>>>>-8
>>>>>>>>>"
>>>>>>>>>)
>>>>>> ;
>>>>>>>>>                String y = Base64.encodeBase64String(b) ;
>>>>>>>>>                //this single code line is mine
>>>>>>>>>                httppost.addHeader("Authorization", "Basic "+y);
>>>>>>>>>            }
>>>>>>>>>            if ( log.isDebugEnabled() )
>>>>>>>>>                log.debug(format("[%d] %s %s",id
>>>>>>>>>,httppost.getMethod(),httppost.getURI().toString())) ;
>>>>>>>>>
>>>>>>>>>            if (
>>>>>> provider.getContentType() == null )
>>>>>>>>>                log.debug(format("[%d] No content type")) ;
>>>>>>>>>
>>>>>>>>>            // Execute
>>>>>>>>>            HttpClient httpclient = new DefaultHttpClient();
>>>>>>>>>            httppost.setEntity(provider) ;
>>>>>>>>>            HttpResponse response = httpclient.execute(httppost) ;
>>>>>>>>>            httpResponse(id, response, baseIRI, handlers) ;
>>>>>>>>>
>>>>>>>>>
>>>>>> httpclient.getConnectionManager().shutdown();
>>>>>>>>>        } catch (IOException ex)
>>>>>>>>>        {
>>>>>>>>>            ex.printStackTrace(System.err) ;
>>>>>>>>>        }
>>>>>>>>>        finally { closeEntity(provider) ; }
>>>>>>>>>    } 

Re: Tr : Basic Authentication for SPARQL Update

Posted by Arthur Vaïsse-Lesteven <ar...@yahoo.fr>.
>Is there any HTTP proxying/redirection involved in your setup?
No. The only proxy is the SPARQL proxy that I'm coding. It is based on the work of wimmic team ( http://wimmics.inria.fr/projects/shi3ld/ ).

This is my code :

The query engine Http add to the HTTP Header ("Authorization", "Basic <username>:<password>") where user informations are 64Bits encoded.
My test consist in sending request to the proxy ( no redirection involved, the user credentials check is done by the proxy ).
For the sparql queries ( SELECT/ASK/DESCRIBE/CONSTRUCT ) I use this code in order to extract credentials :

    import org.apache.commons.codec.binary.Base64;
    import org.apache.commons.codec.binary.StringUtils;
    
    protected String[] extractCredentials(HttpServletRequest req){
        String auth = req.getHeader("Authorization");
        if( auth == null || !(auth.toUpperCase().startsWith("BASIC")) ){return null;} 
        return this.decode(auth.substring(6)).split(":"); 
    }
    
    private String decode(String s) {
        return StringUtils.newStringUtf8(Base64.decodeBase64(s));
    }

The UpdateProcessRemoteForm don't add anything to header during my test. I do this :

    UpdateRequest update = UpdateFactory.create(queryString);    
    UpdateProcessRemoteForm exec = (UpdateProcessRemoteForm) UpdateExecutionFactory.createRemoteForm(update, service);
    exec.setAuthentication("arthurvaisse@yahoo.fr", "test".toCharArray());
    exec.execute();   

And as there is no header corresponding to the key "Authorization" my proxy send a 407 error ( authentication required ).

>>>>>Request contains following fields :
>>>>>In headers :
>>>>>content-lenght : 273
>>>>>content-type : application/x-www-form-urlencoded; charset=UTF-8
>>>>>host : localhost:8080
>>>>>conection : Keep-Alive
>>>>>user-agent: Apache-HttpClient/4.2.3 (java 1.5)

Maybe your code is working but work in an other way ?

VAISSE-LESTEVEN Arthur.

>I added simple basic auth support to Fuseki and wrote unit tests that
>verified that authentication is working correctly.
>
>It would be useful to know what error code/messages you get with the
>latest SNAPSHOTs?
>
>Is there any HTTP proxying/redirection involved in your setup?
>
>The applyAuthentication() code scopes provided credentials to the given
>service URI so if the server is responding with a 401 Unauthorized on a
>different URI from the original request then HTTP Client may be failing to
>attempt to pass any credentials at all in response to the servers
>challenge and simply bailing out and throwing up the 401 error
>
>Rob
>
>
>On 6/25/13 2:44 AM, "Arthur Vaïsse-Lesteven" <ar...@yahoo.fr> wrote:
>
>>
>>Hi again.
>>
>>It seems that the bug is still present. The HTTPheader not contains
>>basicAuthentification informations. What test did you do about the new
>>httpOp ? I may doing it in a wrong way :/
>>
>>After the debugged applyAuthentication in HttpOp, there is the following
>>line : "HttpResponse response = httpclient.execute(httppost,
>>httpContext);"
>>
>>And I think that the HttpClient.execute method doesn't use the
>>authentication information available in his Credential provider.
>>
>>Rob : "Don't forget you can always check out and do a mvn install locally"
>>Ho yes, I'll do that next time!
>>
>>VAÏSSE-LESTEVEN Arthur.
>>
>>
>>>Hmmm, that is a little weird
>>>
>>>I just forced a rebuild and the latest build does have the change in it,
>>>not sure what happened there. Sometimes the Apache build servers are
>>>just a little flaky.
>>>
>>>Don't forget you can always check out and do a mvn install locally
>>>
>>>Rob
>>>
>>>From: Arthur Vaïsse-Lesteven
>>><ar...@yahoo.fr>>
>>>Reply-To: "users@jena.apache.org<ma...@jena.apache.org>"
>>><us...@jena.apache.org>>, Arthur
>>>Vaïsse-Lesteven <ar...@yahoo.fr>>
>>>Date: Monday, June 24, 2013 5:26 AM
>>>To: "users@jena.apache.org<ma...@jena.apache.org>"
>>><us...@jena.apache.org>>
>>>Subject: Re: Tr : Basic Authentication for SPARQL Update
>>>
>>>Hi Rob,
>>>
>>>It's a little confusing.
>>>
>>>You modified the HttpOp class in the release number 34 on the maven repo
>>>[1], but this modification isn't present in the last version ( 38 ) as
>>>you can see in the java file joined to this mail.
>>>
>>>The add of "client.setCredentialsProvider(provider);" line 400 probably
>>>solve the problem but I'm not able to test it as it isn't present in the
>>>last released version of ARQ.
>>>
>>>( The trunk version of your SVN seems to contains this code too ).
>>>
>>>Thanks for your work.
>>>
>>>VAISSE-LESTEVEN Arthur.
>>>
>>>
>>>[1]
>>>https://repository.apache.org/content/repositories/snapshots/org/apache/j
>>>ena/jena-arq/2.10.2-SNAPSHOT/
>>>________________________________
>>>De : Rob Vesse <rv...@yarcdata.com>>
>>>À : "users@jena.apache.org<ma...@jena.apache.org>"
>>><us...@jena.apache.org>>
>>>Envoyé le : Vendredi 21 juin 2013 19h35
>>>Objet : Re: Tr : Basic Authentication for SPARQL Update
>>>
>>>The latest SNAPSHOTS now have the fix, you may need to add -U to your mvn
>>>calls if you have recently updated SNAPSHOTs to get the very latest
>>>
>>>Please test and confirm whether this resolves the issue
>>>
>>>Rob
>>>
>>>
>>>On 6/21/13 9:13 AM, "Rob Vesse"
>>><rv...@cray.com>> wrote:
>>>
>>>>Nice catch
>>>>
>>>>Yes I appear to have made an error, I never associated the created
>>>>credentials provider with the HTTP Client
>>>>
>>>>Filed as JENA-475 (https://issues.apache.org/jira/browse/JENA-475)
>>>>
>>>>I will commit a fix ASAP and you should be able to pick up a
>>>>2.10.2-SNAPSHOT build in a few hours with the fix, if you can test with
>>>>the snapshot and report if this resolves the issue that would be great.
>>>>
>>>>You can verify whether the fix has gone into the snapshots by looking at
>>>>https://builds.apache.org/job/Jena__Development_Test/changes and seeing
>>>>if
>>>>there is a build listed where the commit messages mention JENA-475
>>>>
>>>>Rob
>>>>
>>>>
>>>>
>>>>On 6/20/13 11:51 PM, "Arthur Vaïsse-Lesteven"
>>>><ar...@yahoo.fr>>
>>>>wrote:
>>>>
>>>>>Hi Rob, I'm in trouble with the basic authentication process ( I'm now
>>>>>using ARQ 2.10.1 )
>>>>>
>>>>>
>>>>>In one hand the Queries work like this :
>>>>>when we calls one of the 4 method execX of a queryExecution, the
>>>>>QueryEngineHTTP calls makeHttpQuery, and after few steps this code line
>>>>>is executed :
>>>>>    httpConnection.setRequestProperty("Authorization", "Basic "+y) ;
>>>>>where y contains userName:password 64Bits encrypted.
>>>>>
>>>>>This make the http request header contains the Key, Value couple :
>>>>>"Authorization" "Basic username:password".
>>>>>
>>>>>I'm OK with this.
>>>>>
>>>>>In the other hand, the update seem to handle Basic Authentication in a
>>>>>different way.
>>>>>
>>>>>I used this code :
>>>>>
>>>>>UpdateRequest update =
>>>>> UpdateFactory.create(queryString);
>>>>>UpdateProcessRemoteForm exec = (UpdateProcessRemoteForm)
>>>>>UpdateExecutionFactory.createRemoteForm(update, service);
>>>>>exec.setAuthentication("arnaud@gmail.com<ma...@gmail.com>",
>>>>>"savaillon".toCharArray());
>>>>>
>>>>>And I'm unable to retrieve the usename and the password.
>>>>>Request contains following fields :
>>>>>In headers :
>>>>>content-lenght : 273
>>>>>content-type : application/x-www-form-urlencoded; charset=UTF-8
>>>>>host : localhost:8080
>>>>>conection : Keep-Alive
>>>>>user-agent: Apache-HttpClient/4.2.3 (java 1.5)
>>>>>In params :
>>>>>update : my update
>>>>>No attribute.
>>>>>
>>>>>I tried to follow in the ARQ library the path of my username and
>>>>>password, and finally they transited to the applyAuthentication in
>>>>>HttpOp.
>>>>>
>>>>>This method create a CredentialsProvider and set the credentials
>>>>>username
>>>>>and
>>>>> password. But this method has a void return type, and I don't see any
>>>>>communication point with the rest of the HttpOp code.
>>>>>
>>>>>Do I missed something ?
>>>>>
>>>>>VAÏSSE-LESTEVEN Arthur.
>>>>>
>>>>>
>>>>>>I was using the 2.9.2 ARQ version. I'll update to 2.10.1.
>>>>>>Thanks for your quick answer and for your work  Rob!
>>>>>>
>>>>>>VAÏSSE-LESTEVEN Arthur.
>>>>>>
>>>>>>
>>>>>>>What version of ARQ are you using?
>>>>>>>
>>>>>>>I put changes in place which went into the 2.10.1 release which
>>>>>>>should
>>>>>>>permit easy HTTP auth on SPARQL updates.  Both
>>>>>>>UpdateExecutionFactory.createRemote() and
>>>>>>>UpdateExecutionFactory.createRemoteForm() return an instance derived
>>>>>>>from
>>>>>>>UpdateProcessRemoteBase which has a setAuthentication() method
>>>>>>>
>>>>>>>If you are using a version of ARQ prior to 2.10.0 there is no common
>>>>>>>base
>>>>>>>class but both UpdateProcessRemote and UpdateProcessRemoteForm
>>>>> would still
>>>>>>>have a setHttpContext() method which allows you to pass in a
>>>>>>>HttpContext
>>>>>>>which can be used to pass in authentication settings using the
>>>>>>>HttpClient
>>>>>>>APIs.  Even with 2.10.1 you can still choose to use this method
>>>>>>>particularly if you need to pass complex credentials.
>>>>>>>
>>>>>>>Rob
>>>>>>>
>>>>>>>
>>>>>>>On 6/18/13 8:10 AM, "Arthur Vaïsse-Lesteven"
>>>>>>><ar...@yahoo.fr>>
>>>>>>>wrote:
>>>>>>>
>>>>>>>>Hi,
>>>>>>>>
>>>>>>>>
>>>>>>>>The remote execution of SPARQL queries offer the
>>>>>>>>setBasicAuthentication
>>>>>>>>fonctionality(1). I'm using it; and when I tried to use it with
>>>>>>>>SPARQL
>>>>>>>>Update it appears that SPARQL Update doesn't handle Authentication.
>>>>>>>>I would like to know, do it exist any way to do the same thing in
>>>>>>>>ARQ
>>>>>>>>? I
>>>>>>>>writted some code by extending 2 apache classes, but it would be
>>>>> better
>>>>>>>>to just use the API. Do you intend to not allow
>>>>>>>>basicAuthentification
>>>>>>>>?
>>>>>>>>It is incompatible with http basic authentication ? There are only
>>>>>>>>24hours per day and you don't had the time to do it yet ?
>>>>>>>>
>>>>>>>>Do this functionality is planed ?
>>>>>>>>
>>>>>>>>____________________________________________________________________
>>>>>>>>__
>>>>>>>>_
>>>>>>>>_
>>>>>>>>
>>>>>>>>(1) What i can write :
>>>>>>>>
>>>>>>>>[...]
>>>>>>>>
>>>>>>>>
>>>>>>>>QueryEngineHTTP exec = (QueryEngineHTTP)
>>>>>>>>QueryExecutionFactory.createServiceRequest(endpoint_URL, query);
>>>>>>>>exec.setBasicAuthentication(user, password);
>>>>>>>>
>>>>>>>>exec.exec...
>>>>>>>>
>>>>>>>>[...]
>>>>>>>>
>>>>>>>>(2)What I want to write :
>>>>>>>>
>>>>>>>>[...]
>>>>>>>>UpdateProcessRemote exec =
>>>>> (UpdateProcessRemote)
>>>>>>>>UpdateExecutionFactory.createRemote(update, endpoint_URL);
>>>>>>>>exec.setBasicAuthentication(user, password);
>>>>>>>>
>>>>>>>>exec.excute();
>>>>>>>>
>>>>>>>>[...]
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>I tried to custom the UpdateProcessRemote class to allow (2). This
>>>>>>>>currently don't work on my computer, but it seem's to be due to a
>>>>>>>>maven
>>>>>>>>version conflict at level of HttpClient. This class must be
>>>>>>>>compatible
>>>>>>>>with current version of Jena.( I set my modifications in bold ).(
>>>>>>>>also
>>>>>>>>downlodable at : http://arthurvaisse.free.fr/classes/ )
>>>>>>>>
>>>>>>>>Thank you,
>>>>>>>>VAÏSSE-LESTEVEN Arthur.
>>>>>>>>
>>>>>>>>
>>>>>>>>____________________________________________________________________
>>>>>>>>__
>>>>>>>>_
>>>>>>>>_
>>>>>>>>
>>>>>>>>public class UpdateProcessRemote
>>>>> implements UpdateProcessor{
>>>>>>>>
>>>>>>>>    private String user = null ;
>>>>>>>>    private char[] password = null ;
>>>>>>>>
>>>>>>>>    private final UpdateRequest request ;
>>>>>>>>    private final String endpoint ;
>>>>>>>>
>>>>>>>>    public UpdateProcessRemote(UpdateRequest request , String
>>>>>>>>endpoint
>>>>>>>>)
>>>>>>>>    {
>>>>>>>>        this.request = request ;
>>>>>>>>        this.endpoint = endpoint ;
>>>>>>>>
>>>>>>>> }
>>>>>>>>
>>>>>>>>    @Override
>>>>>>>>    public void setInitialBinding(QuerySolution binding)
>>>>>>>>    {
>>>>>>>>        throw new ARQException("Initial bindings
>>>>> for a remote update
>>>>>>>>execution request not supported") ;
>>>>>>>>    }
>>>>>>>>
>>>>>>>>    @Override
>>>>>>>>    public GraphStore getGraphStore()
>>>>>>>>    {
>>>>>>>>        return null ;
>>>>>>>>    }
>>>>>>>>
>>>>>>>>    @Override
>>>>>>>>    public void execute()
>>>>>>>>    {
>>>>>>>>        String reqStr = request.toString() ;
>>>>>>>>      HttpOpCustom.execHttpPost(endpoint,
>>>>>>>>WebContent.contentTypeSPARQLUpdate, reqStr, user, password);
>>>>>>>>    }
>>>>>>>>
>>>>>>>>    //comes from QueryEngineHTTP.
>>>>>>>>    public void
>>>>> setBasicAuthentication(String user, char[] password)
>>>>>>>>
>>>>>>>> {
>>>>>>>>        this.user = user ;
>>>>>>>>        this.password = password ;
>>>>>>>>    }
>>>>>>>>____________________________________________________________________
>>>>>>>>__
>>>>>>>>_
>>>>>>>>_
>>>>>>>>
>>>>>>>>I added this functions to HttpOp to create my custom HttpOp :
>>>>>>>>
>>>>>>>>    //Just added credentials in parameters
>>>>>>>>    public static void execHttpPost(String url, String contentType,
>>>>>>>>String content, String user, char[] password)
>>>>>>>>    {
>>>>>>>>        execHttpPost(url, contentType, content, null, null, user,
>>>>>>>>password) ;
>>>>>>>>
>>>>> }
>>>>>>>>
>>>>>>>>
>>>>>>>>    //Just added credentials in parameters
>>>>>>>>    public static void execHttpPost(String url, String contentType,
>>>>>>>>String content,
>>>>>>>>            String acceptType, Map<String, HttpResponseHandler>
>>>>>>>>handlers,
>>>>>>>>            String user, char[] password)
>>>>>>>>    {
>>>>>>>>        StringEntity e = null ;
>>>>>>>>        try
>>>>>>>>        {
>>>>>>>>            e = new StringEntity(content, "UTF-8") ;
>>>>>>>>
>>>>> e.setContentType(contentType) ;
>>>>>>>>            execHttpPost(url, e, acceptType, handlers, user,
>>>>>>>>password)
>>>>>>>>;
>>>>>>>>        } catch (UnsupportedEncodingException e1)
>>>>>>>>        {
>>>>>>>>            throw new ARQInternalErrorException("Platform does not
>>>>>>>>support required UTF-8") ;
>>>>>>>>        } finally { closeEntity(e) ; }
>>>>>>>>    }
>>>>>>>>
>>>>>>>>
>>>>>>>>    public static void execHttpPost(String url,  HttpEntity
>>>>>>>>provider,
>>>>>>>>            String acceptType, Map<String, HttpResponseHandler>
>>>>> handlers,
>>>>>>>>            String user, char[] password)
>>>>>>>>    {
>>>>>>>>        try {
>>>>>>>>            long id = counter.incrementAndGet() ;
>>>>>>>>            String requestURI = determineBaseIRI(url) ;
>>>>>>>>            String baseIRI = determineBaseIRI(requestURI) ;
>>>>>>>>
>>>>>>>>            HttpPost httppost = new HttpPost(requestURI);
>>>>>>>>
>>>>>>>>            if ( user != null || password !=
>>>>> null){
>>>>>>>>                if(user==null || password == null){
>>>>>>>>                    log.warn("Only one of user/password is set") ;
>>>>>>>>                }
>>>>>>>>                //this code come from httpQuery
>>>>>>>>                StringBuffer x = new StringBuffer() ;
>>>>>>>>                byte b[] =
>>>>>>>>x.append(user).append(":").append(password).toString().getBytes("UTF
>>>>>>>>-8
>>>>>>>>"
>>>>>>>>)
>>>>> ;
>>>>>>>>                String y = Base64.encodeBase64String(b) ;
>>>>>>>>                //this single code line is mine
>>>>>>>>                httppost.addHeader("Authorization", "Basic "+y);
>>>>>>>>            }
>>>>>>>>            if ( log.isDebugEnabled() )
>>>>>>>>                log.debug(format("[%d] %s %s",id
>>>>>>>>,httppost.getMethod(),httppost.getURI().toString())) ;
>>>>>>>>
>>>>>>>>            if (
>>>>> provider.getContentType() == null )
>>>>>>>>                log.debug(format("[%d] No content type")) ;
>>>>>>>>
>>>>>>>>            // Execute
>>>>>>>>            HttpClient httpclient = new DefaultHttpClient();
>>>>>>>>            httppost.setEntity(provider) ;
>>>>>>>>            HttpResponse response = httpclient.execute(httppost) ;
>>>>>>>>            httpResponse(id, response, baseIRI, handlers) ;
>>>>>>>>
>>>>>>>>
>>>>> httpclient.getConnectionManager().shutdown();
>>>>>>>>        } catch (IOException ex)
>>>>>>>>        {
>>>>>>>>            ex.printStackTrace(System.err) ;
>>>>>>>>        }
>>>>>>>>        finally { closeEntity(provider) ; }
>>>>>>>>    }

Re: Tr : Basic Authentication for SPARQL Update

Posted by Martynas Jusevičius <ma...@graphity.org>.
Rob, as a sidenote for this thread and some previous ones about
uniform HTTP access in Jena, I wanted to show how easily
authentication can be done using Jersey (implementation of JAX-RS).
This is from Graphity subclass of UpdateProcessRemote:

    @Override
    public void execute()
    {
        Client client = Client.create();
        WebResource wr = client.resource(endpointURI);

        if (user != null && password != null) client.addFilter(new
HTTPBasicAuthFilter(user, password));

        ClientResponse response =
            wr.type(WebContent.contentTypeSPARQLUpdate).
            accept(WebContent.contentTypeResultsXML).
            post(ClientResponse.class, request.toString());
    }

Martynas
graphityhq.com

On Wed, Jun 26, 2013 at 3:00 AM, Rob Vesse <rv...@yarcdata.com> wrote:
> I added simple basic auth support to Fuseki and wrote unit tests that
> verified that authentication is working correctly.
>
> It would be useful to know what error code/messages you get with the
> latest SNAPSHOTs?
>
> Is there any HTTP proxying/redirection involved in your setup?
>
> The applyAuthentication() code scopes provided credentials to the given
> service URI so if the server is responding with a 401 Unauthorized on a
> different URI then the original request then HTTP Client may be failing to
> attempt to pass any credentials at all in response to the servers
> challenge and simply bailing out and throwing up the 401 error
>
> Rob
>
>
> On 6/25/13 2:44 AM, "Arthur Vaïsse-Lesteven" <ar...@yahoo.fr> wrote:
>
>>
>>Hi again.
>>
>>It seems that the bug is still present. The HTTPheader not contains
>>basicAuthentification informations. What test did you do about the new
>>httpOp ? I may doing it in a wrong way :/
>>
>>After the debugged applyAuthentication in HttpOp, there is the following
>>line : "HttpResponse response = httpclient.execute(httppost,
>>httpContext);"
>>
>>And I think that the HttpClient.execute method doesn't use the
>>authentication information available in his Credential provider.
>>
>>Rob : "Don't forget you can always check out and do a mvn install locally"
>>Ho yes, I'll do that next time!
>>
>>VAÏSSE-LESTEVEN Arthur.
>>
>>
>>>Hmmm, that is a little weird
>>>
>>>I just forced a rebuild and the latest build does have the change in it,
>>>not sure what happened there. Sometimes the Apache build servers are
>>>just a little flaky.
>>>
>>>Don't forget you can always check out and do a mvn install locally
>>>
>>>Rob
>>>
>>>From: Arthur Vaïsse-Lesteven
>>><ar...@yahoo.fr>>
>>>Reply-To: "users@jena.apache.org<ma...@jena.apache.org>"
>>><us...@jena.apache.org>>, Arthur
>>>Vaïsse-Lesteven <ar...@yahoo.fr>>
>>>Date: Monday, June 24, 2013 5:26 AM
>>>To: "users@jena.apache.org<ma...@jena.apache.org>"
>>><us...@jena.apache.org>>
>>>Subject: Re: Tr : Basic Authentication for SPARQL Update
>>>
>>>Hi Rob,
>>>
>>>It's a little confusing.
>>>
>>>You modified the HttpOp class in the release number 34 on the maven repo
>>>[1], but this modification isn't present in the last version ( 38 ) as
>>>you can see in the java file joined to this mail.
>>>
>>>The add of "client.setCredentialsProvider(provider);" line 400 probably
>>>solve the problem but I'm not able to test it as it isn't present in the
>>>last released version of ARQ.
>>>
>>>( The trunk version of your SVN seems to contains this code too ).
>>>
>>>Thanks for your work.
>>>
>>>VAISSE-LESTEVEN Arthur.
>>>
>>>
>>>[1]
>>>https://repository.apache.org/content/repositories/snapshots/org/apache/j
>>>ena/jena-arq/2.10.2-SNAPSHOT/
>>>________________________________
>>>De : Rob Vesse <rv...@yarcdata.com>>
>>>À : "users@jena.apache.org<ma...@jena.apache.org>"
>>><us...@jena.apache.org>>
>>>Envoyé le : Vendredi 21 juin 2013 19h35
>>>Objet : Re: Tr : Basic Authentication for SPARQL Update
>>>
>>>The latest SNAPSHOTS now have the fix, you may need to add -U to your mvn
>>>calls if you have recently updated SNAPSHOTs to get the very latest
>>>
>>>Please test and confirm whether this resolves the issue
>>>
>>>Rob
>>>
>>>
>>>On 6/21/13 9:13 AM, "Rob Vesse"
>>><rv...@cray.com>> wrote:
>>>
>>>>Nice catch
>>>>
>>>>Yes I appear to have made an error, I never associated the created
>>>>credentials provider with the HTTP Client
>>>>
>>>>Filed as JENA-475 (https://issues.apache.org/jira/browse/JENA-475)
>>>>
>>>>I will commit a fix ASAP and you should be able to pick up a
>>>>2.10.2-SNAPSHOT build in a few hours with the fix, if you can test with
>>>>the snapshot and report if this resolves the issue that would be great.
>>>>
>>>>You can verify whether the fix has gone into the snapshots by looking at
>>>>https://builds.apache.org/job/Jena__Development_Test/changes and seeing
>>>>if
>>>>there is a build listed where the commit messages mention JENA-475
>>>>
>>>>Rob
>>>>
>>>>
>>>>
>>>>On 6/20/13 11:51 PM, "Arthur Vaïsse-Lesteven"
>>>><ar...@yahoo.fr>>
>>>>wrote:
>>>>
>>>>>Hi Rob, I'm in trouble with the basic authentication process ( I'm now
>>>>>using ARQ 2.10.1 )
>>>>>
>>>>>
>>>>>In one hand the Queries work like this :
>>>>>when we calls one of the 4 method execX of a queryExecution, the
>>>>>QueryEngineHTTP calls makeHttpQuery, and after few steps this code line
>>>>>is executed :
>>>>>    httpConnection.setRequestProperty("Authorization", "Basic "+y) ;
>>>>>where y contains userName:password 64Bits encrypted.
>>>>>
>>>>>This make the http request header contains the Key, Value couple :
>>>>>"Authorization" "Basic username:password".
>>>>>
>>>>>I'm OK with this.
>>>>>
>>>>>In the other hand, the update seem to handle Basic Authentication in a
>>>>>different way.
>>>>>
>>>>>I used this code :
>>>>>
>>>>>UpdateRequest update =
>>>>> UpdateFactory.create(queryString);
>>>>>UpdateProcessRemoteForm exec = (UpdateProcessRemoteForm)
>>>>>UpdateExecutionFactory.createRemoteForm(update, service);
>>>>>exec.setAuthentication("arnaud@gmail.com<ma...@gmail.com>",
>>>>>"savaillon".toCharArray());
>>>>>
>>>>>And I'm unable to retrieve the usename and the password.
>>>>>Request contains following fields :
>>>>>In headers :
>>>>>content-lenght : 273
>>>>>content-type : application/x-www-form-urlencoded; charset=UTF-8
>>>>>host : localhost:8080
>>>>>conection : Keep-Alive
>>>>>user-agent: Apache-HttpClient/4.2.3 (java 1.5)
>>>>>In params :
>>>>>update : my update
>>>>>No attribute.
>>>>>
>>>>>I tried to follow in the ARQ library the path of my username and
>>>>>password, and finally they transited to the applyAuthentication in
>>>>>HttpOp.
>>>>>
>>>>>This method create a CredentialsProvider and set the credentials
>>>>>username
>>>>>and
>>>>> password. But this method has a void return type, and I don't see any
>>>>>communication point with the rest of the HttpOp code.
>>>>>
>>>>>Do I missed something ?
>>>>>
>>>>>VAÏSSE-LESTEVEN Arthur.
>>>>>
>>>>>
>>>>>>I was using the 2.9.2 ARQ version. I'll update to 2.10.1.
>>>>>>Thanks for your quick answer and for your work  Rob!
>>>>>>
>>>>>>VAÏSSE-LESTEVEN Arthur.
>>>>>>
>>>>>>
>>>>>>>What version of ARQ are you using?
>>>>>>>
>>>>>>>I put changes in place which went into the 2.10.1 release which
>>>>>>>should
>>>>>>>permit easy HTTP auth on SPARQL updates.  Both
>>>>>>>UpdateExecutionFactory.createRemote() and
>>>>>>>UpdateExecutionFactory.createRemoteForm() return an instance derived
>>>>>>>from
>>>>>>>UpdateProcessRemoteBase which has a setAuthentication() method
>>>>>>>
>>>>>>>If you are using a version of ARQ prior to 2.10.0 there is no common
>>>>>>>base
>>>>>>>class but both UpdateProcessRemote and UpdateProcessRemoteForm
>>>>> would still
>>>>>>>have a setHttpContext() method which allows you to pass in a
>>>>>>>HttpContext
>>>>>>>which can be used to pass in authentication settings using the
>>>>>>>HttpClient
>>>>>>>APIs.  Even with 2.10.1 you can still choose to use this method
>>>>>>>particularly if you need to pass complex credentials.
>>>>>>>
>>>>>>>Rob
>>>>>>>
>>>>>>>
>>>>>>>On 6/18/13 8:10 AM, "Arthur Vaïsse-Lesteven"
>>>>>>><ar...@yahoo.fr>>
>>>>>>>wrote:
>>>>>>>
>>>>>>>>Hi,
>>>>>>>>
>>>>>>>>
>>>>>>>>The remote execution of SPARQL queries offer the
>>>>>>>>setBasicAuthentication
>>>>>>>>fonctionality(1). I'm using it; and when I tried to use it with
>>>>>>>>SPARQL
>>>>>>>>Update it appears that SPARQL Update doesn't handle Authentication.
>>>>>>>>I would like to know, do it exist any way to do the same thing in
>>>>>>>>ARQ
>>>>>>>>? I
>>>>>>>>writted some code by extending 2 apache classes, but it would be
>>>>> better
>>>>>>>>to just use the API. Do you intend to not allow
>>>>>>>>basicAuthentification
>>>>>>>>?
>>>>>>>>It is incompatible with http basic authentication ? There are only
>>>>>>>>24hours per day and you don't had the time to do it yet ?
>>>>>>>>
>>>>>>>>Do this functionality is planed ?
>>>>>>>>
>>>>>>>>____________________________________________________________________
>>>>>>>>__
>>>>>>>>_
>>>>>>>>_
>>>>>>>>
>>>>>>>>(1) What i can write :
>>>>>>>>
>>>>>>>>[...]
>>>>>>>>
>>>>>>>>
>>>>>>>>QueryEngineHTTP exec = (QueryEngineHTTP)
>>>>>>>>QueryExecutionFactory.createServiceRequest(endpoint_URL, query);
>>>>>>>>exec.setBasicAuthentication(user, password);
>>>>>>>>
>>>>>>>>exec.exec...
>>>>>>>>
>>>>>>>>[...]
>>>>>>>>
>>>>>>>>(2)What I want to write :
>>>>>>>>
>>>>>>>>[...]
>>>>>>>>UpdateProcessRemote exec =
>>>>> (UpdateProcessRemote)
>>>>>>>>UpdateExecutionFactory.createRemote(update, endpoint_URL);
>>>>>>>>exec.setBasicAuthentication(user, password);
>>>>>>>>
>>>>>>>>exec.excute();
>>>>>>>>
>>>>>>>>[...]
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>I tried to custom the UpdateProcessRemote class to allow (2). This
>>>>>>>>currently don't work on my computer, but it seem's to be due to a
>>>>>>>>maven
>>>>>>>>version conflict at level of HttpClient. This class must be
>>>>>>>>compatible
>>>>>>>>with current version of Jena.( I set my modifications in bold ).(
>>>>>>>>also
>>>>>>>>downlodable at : http://arthurvaisse.free.fr/classes/ )
>>>>>>>>
>>>>>>>>Thank you,
>>>>>>>>VAÏSSE-LESTEVEN Arthur.
>>>>>>>>
>>>>>>>>
>>>>>>>>____________________________________________________________________
>>>>>>>>__
>>>>>>>>_
>>>>>>>>_
>>>>>>>>
>>>>>>>>public class UpdateProcessRemote
>>>>> implements UpdateProcessor{
>>>>>>>>
>>>>>>>>    private String user = null ;
>>>>>>>>    private char[] password = null ;
>>>>>>>>
>>>>>>>>    private final UpdateRequest request ;
>>>>>>>>    private final String endpoint ;
>>>>>>>>
>>>>>>>>    public UpdateProcessRemote(UpdateRequest request , String
>>>>>>>>endpoint
>>>>>>>>)
>>>>>>>>    {
>>>>>>>>        this.request = request ;
>>>>>>>>        this.endpoint = endpoint ;
>>>>>>>>
>>>>>>>> }
>>>>>>>>
>>>>>>>>    @Override
>>>>>>>>    public void setInitialBinding(QuerySolution binding)
>>>>>>>>    {
>>>>>>>>        throw new ARQException("Initial bindings
>>>>> for a remote update
>>>>>>>>execution request not supported") ;
>>>>>>>>    }
>>>>>>>>
>>>>>>>>    @Override
>>>>>>>>    public GraphStore getGraphStore()
>>>>>>>>    {
>>>>>>>>        return null ;
>>>>>>>>    }
>>>>>>>>
>>>>>>>>    @Override
>>>>>>>>    public void execute()
>>>>>>>>    {
>>>>>>>>        String reqStr = request.toString() ;
>>>>>>>>      HttpOpCustom.execHttpPost(endpoint,
>>>>>>>>WebContent.contentTypeSPARQLUpdate, reqStr, user, password);
>>>>>>>>    }
>>>>>>>>
>>>>>>>>    //comes from QueryEngineHTTP.
>>>>>>>>    public void
>>>>> setBasicAuthentication(String user, char[] password)
>>>>>>>>
>>>>>>>> {
>>>>>>>>        this.user = user ;
>>>>>>>>        this.password = password ;
>>>>>>>>    }
>>>>>>>>____________________________________________________________________
>>>>>>>>__
>>>>>>>>_
>>>>>>>>_
>>>>>>>>
>>>>>>>>I added this functions to HttpOp to create my custom HttpOp :
>>>>>>>>
>>>>>>>>    //Just added credentials in parameters
>>>>>>>>    public static void execHttpPost(String url, String contentType,
>>>>>>>>String content, String user, char[] password)
>>>>>>>>    {
>>>>>>>>        execHttpPost(url, contentType, content, null, null, user,
>>>>>>>>password) ;
>>>>>>>>
>>>>> }
>>>>>>>>
>>>>>>>>
>>>>>>>>    //Just added credentials in parameters
>>>>>>>>    public static void execHttpPost(String url, String contentType,
>>>>>>>>String content,
>>>>>>>>            String acceptType, Map<String, HttpResponseHandler>
>>>>>>>>handlers,
>>>>>>>>            String user, char[] password)
>>>>>>>>    {
>>>>>>>>        StringEntity e = null ;
>>>>>>>>        try
>>>>>>>>        {
>>>>>>>>            e = new StringEntity(content, "UTF-8") ;
>>>>>>>>
>>>>> e.setContentType(contentType) ;
>>>>>>>>            execHttpPost(url, e, acceptType, handlers, user,
>>>>>>>>password)
>>>>>>>>;
>>>>>>>>        } catch (UnsupportedEncodingException e1)
>>>>>>>>        {
>>>>>>>>            throw new ARQInternalErrorException("Platform does not
>>>>>>>>support required UTF-8") ;
>>>>>>>>        } finally { closeEntity(e) ; }
>>>>>>>>    }
>>>>>>>>
>>>>>>>>
>>>>>>>>    public static void execHttpPost(String url,  HttpEntity
>>>>>>>>provider,
>>>>>>>>            String acceptType, Map<String, HttpResponseHandler>
>>>>> handlers,
>>>>>>>>            String user, char[] password)
>>>>>>>>    {
>>>>>>>>        try {
>>>>>>>>            long id = counter.incrementAndGet() ;
>>>>>>>>            String requestURI = determineBaseIRI(url) ;
>>>>>>>>            String baseIRI = determineBaseIRI(requestURI) ;
>>>>>>>>
>>>>>>>>            HttpPost httppost = new HttpPost(requestURI);
>>>>>>>>
>>>>>>>>            if ( user != null || password !=
>>>>> null){
>>>>>>>>                if(user==null || password == null){
>>>>>>>>                    log.warn("Only one of user/password is set") ;
>>>>>>>>                }
>>>>>>>>                //this code come from httpQuery
>>>>>>>>                StringBuffer x = new StringBuffer() ;
>>>>>>>>                byte b[] =
>>>>>>>>x.append(user).append(":").append(password).toString().getBytes("UTF
>>>>>>>>-8
>>>>>>>>"
>>>>>>>>)
>>>>> ;
>>>>>>>>                String y = Base64.encodeBase64String(b) ;
>>>>>>>>                //this single code line is mine
>>>>>>>>                httppost.addHeader("Authorization", "Basic "+y);
>>>>>>>>            }
>>>>>>>>            if ( log.isDebugEnabled() )
>>>>>>>>                log.debug(format("[%d] %s %s",id
>>>>>>>>,httppost.getMethod(),httppost.getURI().toString())) ;
>>>>>>>>
>>>>>>>>            if (
>>>>> provider.getContentType() == null )
>>>>>>>>                log.debug(format("[%d] No content type")) ;
>>>>>>>>
>>>>>>>>            // Execute
>>>>>>>>            HttpClient httpclient = new DefaultHttpClient();
>>>>>>>>            httppost.setEntity(provider) ;
>>>>>>>>            HttpResponse response = httpclient.execute(httppost) ;
>>>>>>>>            httpResponse(id, response, baseIRI, handlers) ;
>>>>>>>>
>>>>>>>>
>>>>> httpclient.getConnectionManager().shutdown();
>>>>>>>>        } catch (IOException ex)
>>>>>>>>        {
>>>>>>>>            ex.printStackTrace(System.err) ;
>>>>>>>>        }
>>>>>>>>        finally { closeEntity(provider) ; }
>>>>>>>>    }
>

Re: Tr : Basic Authentication for SPARQL Update

Posted by Rob Vesse <rv...@yarcdata.com>.
I added simple basic auth support to Fuseki and wrote unit tests that
verified that authentication is working correctly.

It would be useful to know what error code/messages you get with the
latest SNAPSHOTs?

Is there any HTTP proxying/redirection involved in your setup?

The applyAuthentication() code scopes provided credentials to the given
service URI so if the server is responding with a 401 Unauthorized on a
different URI then the original request then HTTP Client may be failing to
attempt to pass any credentials at all in response to the servers
challenge and simply bailing out and throwing up the 401 error

Rob


On 6/25/13 2:44 AM, "Arthur Vaïsse-Lesteven" <ar...@yahoo.fr> wrote:

>
>Hi again.
>
>It seems that the bug is still present. The HTTPheader not contains
>basicAuthentification informations. What test did you do about the new
>httpOp ? I may doing it in a wrong way :/
>
>After the debugged applyAuthentication in HttpOp, there is the following
>line : "HttpResponse response = httpclient.execute(httppost,
>httpContext);"
>
>And I think that the HttpClient.execute method doesn't use the
>authentication information available in his Credential provider.
>
>Rob : "Don't forget you can always check out and do a mvn install locally"
>Ho yes, I'll do that next time!
>
>VAÏSSE-LESTEVEN Arthur.
>
>
>>Hmmm, that is a little weird
>>
>>I just forced a rebuild and the latest build does have the change in it,
>>not sure what happened there. Sometimes the Apache build servers are
>>just a little flaky.
>>
>>Don't forget you can always check out and do a mvn install locally
>>
>>Rob
>>
>>From: Arthur Vaïsse-Lesteven
>><ar...@yahoo.fr>>
>>Reply-To: "users@jena.apache.org<ma...@jena.apache.org>"
>><us...@jena.apache.org>>, Arthur
>>Vaïsse-Lesteven <ar...@yahoo.fr>>
>>Date: Monday, June 24, 2013 5:26 AM
>>To: "users@jena.apache.org<ma...@jena.apache.org>"
>><us...@jena.apache.org>>
>>Subject: Re: Tr : Basic Authentication for SPARQL Update
>>
>>Hi Rob,
>>
>>It's a little confusing.
>>
>>You modified the HttpOp class in the release number 34 on the maven repo
>>[1], but this modification isn't present in the last version ( 38 ) as
>>you can see in the java file joined to this mail.
>>
>>The add of "client.setCredentialsProvider(provider);" line 400 probably
>>solve the problem but I'm not able to test it as it isn't present in the
>>last released version of ARQ.
>>
>>( The trunk version of your SVN seems to contains this code too ).
>>
>>Thanks for your work.
>>
>>VAISSE-LESTEVEN Arthur.
>>
>>
>>[1] 
>>https://repository.apache.org/content/repositories/snapshots/org/apache/j
>>ena/jena-arq/2.10.2-SNAPSHOT/
>>________________________________
>>De : Rob Vesse <rv...@yarcdata.com>>
>>À : "users@jena.apache.org<ma...@jena.apache.org>"
>><us...@jena.apache.org>>
>>Envoyé le : Vendredi 21 juin 2013 19h35
>>Objet : Re: Tr : Basic Authentication for SPARQL Update
>>
>>The latest SNAPSHOTS now have the fix, you may need to add -U to your mvn
>>calls if you have recently updated SNAPSHOTs to get the very latest
>>
>>Please test and confirm whether this resolves the issue
>>
>>Rob
>>
>>
>>On 6/21/13 9:13 AM, "Rob Vesse"
>><rv...@cray.com>> wrote:
>>
>>>Nice catch
>>>
>>>Yes I appear to have made an error, I never associated the created
>>>credentials provider with the HTTP Client
>>>
>>>Filed as JENA-475 (https://issues.apache.org/jira/browse/JENA-475)
>>>
>>>I will commit a fix ASAP and you should be able to pick up a
>>>2.10.2-SNAPSHOT build in a few hours with the fix, if you can test with
>>>the snapshot and report if this resolves the issue that would be great.
>>>
>>>You can verify whether the fix has gone into the snapshots by looking at
>>>https://builds.apache.org/job/Jena__Development_Test/changes and seeing
>>>if
>>>there is a build listed where the commit messages mention JENA-475
>>>
>>>Rob
>>>
>>>
>>>
>>>On 6/20/13 11:51 PM, "Arthur Vaïsse-Lesteven"
>>><ar...@yahoo.fr>>
>>>wrote:
>>>
>>>>Hi Rob, I'm in trouble with the basic authentication process ( I'm now
>>>>using ARQ 2.10.1 )
>>>>
>>>>
>>>>In one hand the Queries work like this :
>>>>when we calls one of the 4 method execX of a queryExecution, the
>>>>QueryEngineHTTP calls makeHttpQuery, and after few steps this code line
>>>>is executed :
>>>>    httpConnection.setRequestProperty("Authorization", "Basic "+y) ;
>>>>where y contains userName:password 64Bits encrypted.
>>>>
>>>>This make the http request header contains the Key, Value couple :
>>>>"Authorization" "Basic username:password".
>>>>
>>>>I'm OK with this.
>>>>
>>>>In the other hand, the update seem to handle Basic Authentication in a
>>>>different way.
>>>>
>>>>I used this code :
>>>>
>>>>UpdateRequest update =
>>>> UpdateFactory.create(queryString);
>>>>UpdateProcessRemoteForm exec = (UpdateProcessRemoteForm)
>>>>UpdateExecutionFactory.createRemoteForm(update, service);
>>>>exec.setAuthentication("arnaud@gmail.com<ma...@gmail.com>",
>>>>"savaillon".toCharArray());
>>>>
>>>>And I'm unable to retrieve the usename and the password.
>>>>Request contains following fields :
>>>>In headers :
>>>>content-lenght : 273
>>>>content-type : application/x-www-form-urlencoded; charset=UTF-8
>>>>host : localhost:8080
>>>>conection : Keep-Alive
>>>>user-agent: Apache-HttpClient/4.2.3 (java 1.5)
>>>>In params :
>>>>update : my update
>>>>No attribute.
>>>>
>>>>I tried to follow in the ARQ library the path of my username and
>>>>password, and finally they transited to the applyAuthentication in
>>>>HttpOp.
>>>>
>>>>This method create a CredentialsProvider and set the credentials
>>>>username
>>>>and
>>>> password. But this method has a void return type, and I don't see any
>>>>communication point with the rest of the HttpOp code.
>>>>
>>>>Do I missed something ?
>>>>
>>>>VAÏSSE-LESTEVEN Arthur.
>>>>
>>>>
>>>>>I was using the 2.9.2 ARQ version. I'll update to 2.10.1.
>>>>>Thanks for your quick answer and for your work  Rob!
>>>>>
>>>>>VAÏSSE-LESTEVEN Arthur.
>>>>>
>>>>>
>>>>>>What version of ARQ are you using?
>>>>>>
>>>>>>I put changes in place which went into the 2.10.1 release which
>>>>>>should
>>>>>>permit easy HTTP auth on SPARQL updates.  Both
>>>>>>UpdateExecutionFactory.createRemote() and
>>>>>>UpdateExecutionFactory.createRemoteForm() return an instance derived
>>>>>>from
>>>>>>UpdateProcessRemoteBase which has a setAuthentication() method
>>>>>>
>>>>>>If you are using a version of ARQ prior to 2.10.0 there is no common
>>>>>>base
>>>>>>class but both UpdateProcessRemote and UpdateProcessRemoteForm
>>>> would still
>>>>>>have a setHttpContext() method which allows you to pass in a
>>>>>>HttpContext
>>>>>>which can be used to pass in authentication settings using the
>>>>>>HttpClient
>>>>>>APIs.  Even with 2.10.1 you can still choose to use this method
>>>>>>particularly if you need to pass complex credentials.
>>>>>>
>>>>>>Rob
>>>>>>
>>>>>>
>>>>>>On 6/18/13 8:10 AM, "Arthur Vaïsse-Lesteven"
>>>>>><ar...@yahoo.fr>>
>>>>>>wrote:
>>>>>>
>>>>>>>Hi,
>>>>>>>
>>>>>>>
>>>>>>>The remote execution of SPARQL queries offer the
>>>>>>>setBasicAuthentication
>>>>>>>fonctionality(1). I'm using it; and when I tried to use it with
>>>>>>>SPARQL
>>>>>>>Update it appears that SPARQL Update doesn't handle Authentication.
>>>>>>>I would like to know, do it exist any way to do the same thing in
>>>>>>>ARQ
>>>>>>>? I
>>>>>>>writted some code by extending 2 apache classes, but it would be
>>>> better
>>>>>>>to just use the API. Do you intend to not allow
>>>>>>>basicAuthentification
>>>>>>>?
>>>>>>>It is incompatible with http basic authentication ? There are only
>>>>>>>24hours per day and you don't had the time to do it yet ?
>>>>>>>
>>>>>>>Do this functionality is planed ?
>>>>>>>
>>>>>>>____________________________________________________________________
>>>>>>>__
>>>>>>>_
>>>>>>>_
>>>>>>>
>>>>>>>(1) What i can write :
>>>>>>>
>>>>>>>[...]
>>>>>>>
>>>>>>>
>>>>>>>QueryEngineHTTP exec = (QueryEngineHTTP)
>>>>>>>QueryExecutionFactory.createServiceRequest(endpoint_URL, query);
>>>>>>>exec.setBasicAuthentication(user, password);
>>>>>>>
>>>>>>>exec.exec...
>>>>>>>
>>>>>>>[...]
>>>>>>>
>>>>>>>(2)What I want to write :
>>>>>>>
>>>>>>>[...]
>>>>>>>UpdateProcessRemote exec =
>>>> (UpdateProcessRemote)
>>>>>>>UpdateExecutionFactory.createRemote(update, endpoint_URL);
>>>>>>>exec.setBasicAuthentication(user, password);
>>>>>>>
>>>>>>>exec.excute();
>>>>>>>
>>>>>>>[...]
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>I tried to custom the UpdateProcessRemote class to allow (2). This
>>>>>>>currently don't work on my computer, but it seem's to be due to a
>>>>>>>maven
>>>>>>>version conflict at level of HttpClient. This class must be
>>>>>>>compatible
>>>>>>>with current version of Jena.( I set my modifications in bold ).(
>>>>>>>also
>>>>>>>downlodable at : http://arthurvaisse.free.fr/classes/ )
>>>>>>>
>>>>>>>Thank you,
>>>>>>>VAÏSSE-LESTEVEN Arthur.
>>>>>>>
>>>>>>>
>>>>>>>____________________________________________________________________
>>>>>>>__
>>>>>>>_
>>>>>>>_
>>>>>>>
>>>>>>>public class UpdateProcessRemote
>>>> implements UpdateProcessor{
>>>>>>>
>>>>>>>    private String user = null ;
>>>>>>>    private char[] password = null ;
>>>>>>>
>>>>>>>    private final UpdateRequest request ;
>>>>>>>    private final String endpoint ;
>>>>>>>
>>>>>>>    public UpdateProcessRemote(UpdateRequest request , String
>>>>>>>endpoint
>>>>>>>)
>>>>>>>    {
>>>>>>>        this.request = request ;
>>>>>>>        this.endpoint = endpoint ;
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>>    @Override
>>>>>>>    public void setInitialBinding(QuerySolution binding)
>>>>>>>    {
>>>>>>>        throw new ARQException("Initial bindings
>>>> for a remote update
>>>>>>>execution request not supported") ;
>>>>>>>    }
>>>>>>>
>>>>>>>    @Override
>>>>>>>    public GraphStore getGraphStore()
>>>>>>>    {
>>>>>>>        return null ;
>>>>>>>    }
>>>>>>>
>>>>>>>    @Override
>>>>>>>    public void execute()
>>>>>>>    {
>>>>>>>        String reqStr = request.toString() ;
>>>>>>>      HttpOpCustom.execHttpPost(endpoint,
>>>>>>>WebContent.contentTypeSPARQLUpdate, reqStr, user, password);
>>>>>>>    }
>>>>>>>
>>>>>>>    //comes from QueryEngineHTTP.
>>>>>>>    public void
>>>> setBasicAuthentication(String user, char[] password)
>>>>>>>
>>>>>>> {
>>>>>>>        this.user = user ;
>>>>>>>        this.password = password ;
>>>>>>>    }
>>>>>>>____________________________________________________________________
>>>>>>>__
>>>>>>>_
>>>>>>>_
>>>>>>>
>>>>>>>I added this functions to HttpOp to create my custom HttpOp :
>>>>>>>
>>>>>>>    //Just added credentials in parameters
>>>>>>>    public static void execHttpPost(String url, String contentType,
>>>>>>>String content, String user, char[] password)
>>>>>>>    {
>>>>>>>        execHttpPost(url, contentType, content, null, null, user,
>>>>>>>password) ;
>>>>>>>
>>>> }
>>>>>>>
>>>>>>>
>>>>>>>    //Just added credentials in parameters
>>>>>>>    public static void execHttpPost(String url, String contentType,
>>>>>>>String content,
>>>>>>>            String acceptType, Map<String, HttpResponseHandler>
>>>>>>>handlers,
>>>>>>>            String user, char[] password)
>>>>>>>    {
>>>>>>>        StringEntity e = null ;
>>>>>>>        try
>>>>>>>        {
>>>>>>>            e = new StringEntity(content, "UTF-8") ;
>>>>>>>
>>>> e.setContentType(contentType) ;
>>>>>>>            execHttpPost(url, e, acceptType, handlers, user,
>>>>>>>password)
>>>>>>>;
>>>>>>>        } catch (UnsupportedEncodingException e1)
>>>>>>>        {
>>>>>>>            throw new ARQInternalErrorException("Platform does not
>>>>>>>support required UTF-8") ;
>>>>>>>        } finally { closeEntity(e) ; }
>>>>>>>    }
>>>>>>>
>>>>>>>
>>>>>>>    public static void execHttpPost(String url,  HttpEntity
>>>>>>>provider,
>>>>>>>            String acceptType, Map<String, HttpResponseHandler>
>>>> handlers,
>>>>>>>            String user, char[] password)
>>>>>>>    {
>>>>>>>        try {
>>>>>>>            long id = counter.incrementAndGet() ;
>>>>>>>            String requestURI = determineBaseIRI(url) ;
>>>>>>>            String baseIRI = determineBaseIRI(requestURI) ;
>>>>>>>
>>>>>>>            HttpPost httppost = new HttpPost(requestURI);
>>>>>>>
>>>>>>>            if ( user != null || password !=
>>>> null){
>>>>>>>                if(user==null || password == null){
>>>>>>>                    log.warn("Only one of user/password is set") ;
>>>>>>>                }
>>>>>>>                //this code come from httpQuery
>>>>>>>                StringBuffer x = new StringBuffer() ;
>>>>>>>                byte b[] =
>>>>>>>x.append(user).append(":").append(password).toString().getBytes("UTF
>>>>>>>-8
>>>>>>>"
>>>>>>>)
>>>> ;
>>>>>>>                String y = Base64.encodeBase64String(b) ;
>>>>>>>                //this single code line is mine
>>>>>>>                httppost.addHeader("Authorization", "Basic "+y);
>>>>>>>            }
>>>>>>>            if ( log.isDebugEnabled() )
>>>>>>>                log.debug(format("[%d] %s %s",id
>>>>>>>,httppost.getMethod(),httppost.getURI().toString())) ;
>>>>>>>
>>>>>>>            if (
>>>> provider.getContentType() == null )
>>>>>>>                log.debug(format("[%d] No content type")) ;
>>>>>>>
>>>>>>>            // Execute
>>>>>>>            HttpClient httpclient = new DefaultHttpClient();
>>>>>>>            httppost.setEntity(provider) ;
>>>>>>>            HttpResponse response = httpclient.execute(httppost) ;
>>>>>>>            httpResponse(id, response, baseIRI, handlers) ;
>>>>>>>
>>>>>>>
>>>> httpclient.getConnectionManager().shutdown();
>>>>>>>        } catch (IOException ex)
>>>>>>>        {
>>>>>>>            ex.printStackTrace(System.err) ;
>>>>>>>        }
>>>>>>>        finally { closeEntity(provider) ; }
>>>>>>>    }


Re: Tr : Basic Authentication for SPARQL Update

Posted by Arthur Vaïsse-Lesteven <ar...@yahoo.fr>.
Hi again.

It seems that the bug is still present. The HTTPheader not contains basicAuthentification informations. What test did you do about the new httpOp ? I may doing it in a wrong way :/

After the debugged applyAuthentication in HttpOp, there is the following line : "HttpResponse response = httpclient.execute(httppost, httpContext);"

And I think that the HttpClient.execute method doesn't use the authentication information available in his Credential provider.

Rob : "Don't forget you can always check out and do a mvn install locally"
Ho yes, I'll do that next time!

VAÏSSE-LESTEVEN Arthur.


>Hmmm, that is a little weird
>
>I just forced a rebuild and the latest build does have the change in it, not sure what happened there. Sometimes the Apache build servers are just a little flaky.
>
>Don't forget you can always check out and do a mvn install locally
>
>Rob
>
>From: Arthur Vaïsse-Lesteven <ar...@yahoo.fr>>
>Reply-To: "users@jena.apache.org<ma...@jena.apache.org>" <us...@jena.apache.org>>, Arthur Vaïsse-Lesteven <ar...@yahoo.fr>>
>Date: Monday, June 24, 2013 5:26 AM
>To: "users@jena.apache.org<ma...@jena.apache.org>" <us...@jena.apache.org>>
>Subject: Re: Tr : Basic Authentication for SPARQL Update
>
>Hi Rob,
>
>It's a little confusing.
>
>You modified the HttpOp class in the release number 34 on the maven repo [1], but this modification isn't present in the last version ( 38 ) as you can see in the java file joined to this mail.
>
>The add of "client.setCredentialsProvider(provider);" line 400 probably solve the problem but I'm not able to test it as it isn't present in the last released version of ARQ.
>
>( The trunk version of your SVN seems to contains this code too ).
>
>Thanks for your work.
>
>VAISSE-LESTEVEN Arthur.
>
>
>[1] https://repository.apache.org/content/repositories/snapshots/org/apache/jena/jena-arq/2.10.2-SNAPSHOT/
>________________________________
>De : Rob Vesse <rv...@yarcdata.com>>
>À : "users@jena.apache.org<ma...@jena.apache.org>" <us...@jena.apache.org>>
>Envoyé le : Vendredi 21 juin 2013 19h35
>Objet : Re: Tr : Basic Authentication for SPARQL Update
>
>The latest SNAPSHOTS now have the fix, you may need to add -U to your mvn
>calls if you have recently updated SNAPSHOTs to get the very latest
>
>Please test and confirm whether this resolves the issue
>
>Rob
>
>
>On 6/21/13 9:13 AM, "Rob Vesse" <rv...@cray.com>> wrote:
>
>>Nice catch
>>
>>Yes I appear to have made an error, I never associated the created
>>credentials provider with the HTTP Client
>>
>>Filed as JENA-475 (https://issues.apache.org/jira/browse/JENA-475)
>>
>>I will commit a fix ASAP and you should be able to pick up a
>>2.10.2-SNAPSHOT build in a few hours with the fix, if you can test with
>>the snapshot and report if this resolves the issue that would be great.
>>
>>You can verify whether the fix has gone into the snapshots by looking at
>>https://builds.apache.org/job/Jena__Development_Test/changes and seeing if
>>there is a build listed where the commit messages mention JENA-475
>>
>>Rob
>>
>>
>>
>>On 6/20/13 11:51 PM, "Arthur Vaïsse-Lesteven" <ar...@yahoo.fr>>
>>wrote:
>>
>>>Hi Rob, I'm in trouble with the basic authentication process ( I'm now
>>>using ARQ 2.10.1 )
>>>
>>>
>>>In one hand the Queries work like this :
>>>when we calls one of the 4 method execX of a queryExecution, the
>>>QueryEngineHTTP calls makeHttpQuery, and after few steps this code line
>>>is executed :
>>>    httpConnection.setRequestProperty("Authorization", "Basic "+y) ;
>>>where y contains userName:password 64Bits encrypted.
>>>
>>>This make the http request header contains the Key, Value couple :
>>>"Authorization" "Basic username:password".
>>>
>>>I'm OK with this.
>>>
>>>In the other hand, the update seem to handle Basic Authentication in a
>>>different way.
>>>
>>>I used this code :
>>>
>>>UpdateRequest update =
>>> UpdateFactory.create(queryString);
>>>UpdateProcessRemoteForm exec = (UpdateProcessRemoteForm)
>>>UpdateExecutionFactory.createRemoteForm(update, service);
>>>exec.setAuthentication("arnaud@gmail.com<ma...@gmail.com>", "savaillon".toCharArray());
>>>
>>>And I'm unable to retrieve the usename and the password.
>>>Request contains following fields :
>>>In headers :
>>>content-lenght : 273
>>>content-type : application/x-www-form-urlencoded; charset=UTF-8
>>>host : localhost:8080
>>>conection : Keep-Alive
>>>user-agent: Apache-HttpClient/4.2.3 (java 1.5)
>>>In params :
>>>update : my update
>>>No attribute.
>>>
>>>I tried to follow in the ARQ library the path of my username and
>>>password, and finally they transited to the applyAuthentication in
>>>HttpOp.
>>>
>>>This method create a CredentialsProvider and set the credentials username
>>>and
>>> password. But this method has a void return type, and I don't see any
>>>communication point with the rest of the HttpOp code.
>>>
>>>Do I missed something ?
>>>
>>>VAÏSSE-LESTEVEN Arthur.
>>>
>>>
>>>>I was using the 2.9.2 ARQ version. I'll update to 2.10.1.
>>>>Thanks for your quick answer and for your work  Rob!
>>>>
>>>>VAÏSSE-LESTEVEN Arthur.
>>>>
>>>>
>>>>>What version of ARQ are you using?
>>>>>
>>>>>I put changes in place which went into the 2.10.1 release which should
>>>>>permit easy HTTP auth on SPARQL updates.  Both
>>>>>UpdateExecutionFactory.createRemote() and
>>>>>UpdateExecutionFactory.createRemoteForm() return an instance derived
>>>>>from
>>>>>UpdateProcessRemoteBase which has a setAuthentication() method
>>>>>
>>>>>If you are using a version of ARQ prior to 2.10.0 there is no common
>>>>>base
>>>>>class but both UpdateProcessRemote and UpdateProcessRemoteForm
>>> would still
>>>>>have a setHttpContext() method which allows you to pass in a
>>>>>HttpContext
>>>>>which can be used to pass in authentication settings using the
>>>>>HttpClient
>>>>>APIs.  Even with 2.10.1 you can still choose to use this method
>>>>>particularly if you need to pass complex credentials.
>>>>>
>>>>>Rob
>>>>>
>>>>>
>>>>>On 6/18/13 8:10 AM, "Arthur Vaïsse-Lesteven" <ar...@yahoo.fr>>
>>>>>wrote:
>>>>>
>>>>>>Hi,
>>>>>>
>>>>>>
>>>>>>The remote execution of SPARQL queries offer the
>>>>>>setBasicAuthentication
>>>>>>fonctionality(1). I'm using it; and when I tried to use it with SPARQL
>>>>>>Update it appears that SPARQL Update doesn't handle Authentication.
>>>>>>I would like to know, do it exist any way to do the same thing in ARQ
>>>>>>? I
>>>>>>writted some code by extending 2 apache classes, but it would be
>>> better
>>>>>>to just use the API. Do you intend to not allow basicAuthentification
>>>>>>?
>>>>>>It is incompatible with http basic authentication ? There are only
>>>>>>24hours per day and you don't had the time to do it yet ?
>>>>>>
>>>>>>Do this functionality is planed ?
>>>>>>
>>>>>>______________________________________________________________________
>>>>>>_
>>>>>>_
>>>>>>
>>>>>>(1) What i can write :
>>>>>>
>>>>>>[...]
>>>>>>
>>>>>>
>>>>>>QueryEngineHTTP exec = (QueryEngineHTTP)
>>>>>>QueryExecutionFactory.createServiceRequest(endpoint_URL, query);
>>>>>>exec.setBasicAuthentication(user, password);
>>>>>>
>>>>>>exec.exec...
>>>>>>
>>>>>>[...]
>>>>>>
>>>>>>(2)What I want to write :
>>>>>>
>>>>>>[...]
>>>>>>UpdateProcessRemote exec =
>>> (UpdateProcessRemote)
>>>>>>UpdateExecutionFactory.createRemote(update, endpoint_URL);
>>>>>>exec.setBasicAuthentication(user, password);
>>>>>>
>>>>>>exec.excute();
>>>>>>
>>>>>>[...]
>>>>>>
>>>>>>
>>>>>>
>>>>>>I tried to custom the UpdateProcessRemote class to allow (2). This
>>>>>>currently don't work on my computer, but it seem's to be due to a
>>>>>>maven
>>>>>>version conflict at level of HttpClient. This class must be compatible
>>>>>>with current version of Jena.( I set my modifications in bold ).( also
>>>>>>downlodable at : http://arthurvaisse.free.fr/classes/ )
>>>>>>
>>>>>>Thank you,
>>>>>>VAÏSSE-LESTEVEN Arthur.
>>>>>>
>>>>>>
>>>>>>______________________________________________________________________
>>>>>>_
>>>>>>_
>>>>>>
>>>>>>public class UpdateProcessRemote
>>> implements UpdateProcessor{
>>>>>>
>>>>>>    private String user = null ;
>>>>>>    private char[] password = null ;
>>>>>>
>>>>>>    private final UpdateRequest request ;
>>>>>>    private final String endpoint ;
>>>>>>
>>>>>>    public UpdateProcessRemote(UpdateRequest request , String endpoint
>>>>>>)
>>>>>>    {
>>>>>>        this.request = request ;
>>>>>>        this.endpoint = endpoint ;
>>>>>>
>>>>>> }
>>>>>>
>>>>>>    @Override
>>>>>>    public void setInitialBinding(QuerySolution binding)
>>>>>>    {
>>>>>>        throw new ARQException("Initial bindings
>>> for a remote update
>>>>>>execution request not supported") ;
>>>>>>    }
>>>>>>
>>>>>>    @Override
>>>>>>    public GraphStore getGraphStore()
>>>>>>    {
>>>>>>        return null ;
>>>>>>    }
>>>>>>
>>>>>>    @Override
>>>>>>    public void execute()
>>>>>>    {
>>>>>>        String reqStr = request.toString() ;
>>>>>>      HttpOpCustom.execHttpPost(endpoint,
>>>>>>WebContent.contentTypeSPARQLUpdate, reqStr, user, password);
>>>>>>    }
>>>>>>
>>>>>>    //comes from QueryEngineHTTP.
>>>>>>    public void
>>> setBasicAuthentication(String user, char[] password)
>>>>>>
>>>>>> {
>>>>>>        this.user = user ;
>>>>>>        this.password = password ;
>>>>>>    }
>>>>>>______________________________________________________________________
>>>>>>_
>>>>>>_
>>>>>>
>>>>>>I added this functions to HttpOp to create my custom HttpOp :
>>>>>>
>>>>>>    //Just added credentials in parameters
>>>>>>    public static void execHttpPost(String url, String contentType,
>>>>>>String content, String user, char[] password)
>>>>>>    {
>>>>>>        execHttpPost(url, contentType, content, null, null, user,
>>>>>>password) ;
>>>>>>
>>> }
>>>>>>
>>>>>>
>>>>>>    //Just added credentials in parameters
>>>>>>    public static void execHttpPost(String url, String contentType,
>>>>>>String content,
>>>>>>            String acceptType, Map<String, HttpResponseHandler>
>>>>>>handlers,
>>>>>>            String user, char[] password)
>>>>>>    {
>>>>>>        StringEntity e = null ;
>>>>>>        try
>>>>>>        {
>>>>>>            e = new StringEntity(content, "UTF-8") ;
>>>>>>
>>> e.setContentType(contentType) ;
>>>>>>            execHttpPost(url, e, acceptType, handlers, user, password)
>>>>>>;
>>>>>>        } catch (UnsupportedEncodingException e1)
>>>>>>        {
>>>>>>            throw new ARQInternalErrorException("Platform does not
>>>>>>support required UTF-8") ;
>>>>>>        } finally { closeEntity(e) ; }
>>>>>>    }
>>>>>>
>>>>>>
>>>>>>    public static void execHttpPost(String url,  HttpEntity provider,
>>>>>>            String acceptType, Map<String, HttpResponseHandler>
>>> handlers,
>>>>>>            String user, char[] password)
>>>>>>    {
>>>>>>        try {
>>>>>>            long id = counter.incrementAndGet() ;
>>>>>>            String requestURI = determineBaseIRI(url) ;
>>>>>>            String baseIRI = determineBaseIRI(requestURI) ;
>>>>>>
>>>>>>            HttpPost httppost = new HttpPost(requestURI);
>>>>>>
>>>>>>            if ( user != null || password !=
>>> null){
>>>>>>                if(user==null || password == null){
>>>>>>                    log.warn("Only one of user/password is set") ;
>>>>>>                }
>>>>>>                //this code come from httpQuery
>>>>>>                StringBuffer x = new StringBuffer() ;
>>>>>>                byte b[] =
>>>>>>x.append(user).append(":").append(password).toString().getBytes("UTF-8
>>>>>>"
>>>>>>)
>>> ;
>>>>>>                String y = Base64.encodeBase64String(b) ;
>>>>>>                //this single code line is mine
>>>>>>                httppost.addHeader("Authorization", "Basic "+y);
>>>>>>            }
>>>>>>            if ( log.isDebugEnabled() )
>>>>>>                log.debug(format("[%d] %s %s",id
>>>>>>,httppost.getMethod(),httppost.getURI().toString())) ;
>>>>>>
>>>>>>            if (
>>> provider.getContentType() == null )
>>>>>>                log.debug(format("[%d] No content type")) ;
>>>>>>
>>>>>>            // Execute
>>>>>>            HttpClient httpclient = new DefaultHttpClient();
>>>>>>            httppost.setEntity(provider) ;
>>>>>>            HttpResponse response = httpclient.execute(httppost) ;
>>>>>>            httpResponse(id, response, baseIRI, handlers) ;
>>>>>>
>>>>>>
>>> httpclient.getConnectionManager().shutdown();
>>>>>>        } catch (IOException ex)
>>>>>>        {
>>>>>>            ex.printStackTrace(System.err) ;
>>>>>>        }
>>>>>>        finally { closeEntity(provider) ; }
>>>>>>    }

Re: Tr : Basic Authentication for SPARQL Update

Posted by Rob Vesse <rv...@yarcdata.com>.
Hmmm, that is a little weird

I just forced a rebuild and the latest build does have the change in it, not sure what happened there. Sometimes the Apache build servers are just a little flaky.

Don't forget you can always check out and do a mvn install locally

Rob

From: Arthur Vaïsse-Lesteven <ar...@yahoo.fr>>
Reply-To: "users@jena.apache.org<ma...@jena.apache.org>" <us...@jena.apache.org>>, Arthur Vaïsse-Lesteven <ar...@yahoo.fr>>
Date: Monday, June 24, 2013 5:26 AM
To: "users@jena.apache.org<ma...@jena.apache.org>" <us...@jena.apache.org>>
Subject: Re: Tr : Basic Authentication for SPARQL Update

Hi Rob,

It's a little confusing.

You modified the HttpOp class in the release number 34 on the maven repo [1], but this modification isn't present in the last version ( 38 ) as you can see in the java file joined to this mail.

The add of "client.setCredentialsProvider(provider);" line 400 probably solve the problem but I'm not able to test it as it isn't present in the last released version of ARQ.

( The trunk version of your SVN seems to contains this code too ).

Thanks for your work.

VAISSE-LESTEVEN Arthur.


[1] https://repository.apache.org/content/repositories/snapshots/org/apache/jena/jena-arq/2.10.2-SNAPSHOT/
________________________________
De : Rob Vesse <rv...@yarcdata.com>>
À : "users@jena.apache.org<ma...@jena.apache.org>" <us...@jena.apache.org>>
Envoyé le : Vendredi 21 juin 2013 19h35
Objet : Re: Tr : Basic Authentication for SPARQL Update

The latest SNAPSHOTS now have the fix, you may need to add -U to your mvn
calls if you have recently updated SNAPSHOTs to get the very latest

Please test and confirm whether this resolves the issue

Rob


On 6/21/13 9:13 AM, "Rob Vesse" <rv...@cray.com>> wrote:

>Nice catch
>
>Yes I appear to have made an error, I never associated the created
>credentials provider with the HTTP Client
>
>Filed as JENA-475 (https://issues.apache.org/jira/browse/JENA-475)
>
>I will commit a fix ASAP and you should be able to pick up a
>2.10.2-SNAPSHOT build in a few hours with the fix, if you can test with
>the snapshot and report if this resolves the issue that would be great.
>
>You can verify whether the fix has gone into the snapshots by looking at
>https://builds.apache.org/job/Jena__Development_Test/changes and seeing if
>there is a build listed where the commit messages mention JENA-475
>
>Rob
>
>
>
>On 6/20/13 11:51 PM, "Arthur Vaïsse-Lesteven" <ar...@yahoo.fr>>
>wrote:
>
>>Hi Rob, I'm in trouble with the basic authentication process ( I'm now
>>using ARQ 2.10.1 )
>>
>>
>>In one hand the Queries work like this :
>>when we calls one of the 4 method execX of a queryExecution, the
>>QueryEngineHTTP calls makeHttpQuery, and after few steps this code line
>>is executed :
>>    httpConnection.setRequestProperty("Authorization", "Basic "+y) ;
>>where y contains userName:password 64Bits encrypted.
>>
>>This make the http request header contains the Key, Value couple :
>>"Authorization" "Basic username:password".
>>
>>I'm OK with this.
>>
>>In the other hand, the update seem to handle Basic Authentication in a
>>different way.
>>
>>I used this code :
>>
>>UpdateRequest update =
>> UpdateFactory.create(queryString);
>>UpdateProcessRemoteForm exec = (UpdateProcessRemoteForm)
>>UpdateExecutionFactory.createRemoteForm(update, service);
>>exec.setAuthentication("arnaud@gmail.com<ma...@gmail.com>", "savaillon".toCharArray());
>>
>>And I'm unable to retrieve the usename and the password.
>>Request contains following fields :
>>In headers :
>>content-lenght : 273
>>content-type : application/x-www-form-urlencoded; charset=UTF-8
>>host : localhost:8080
>>conection : Keep-Alive
>>user-agent: Apache-HttpClient/4.2.3 (java 1.5)
>>In params :
>>update : my update
>>No attribute.
>>
>>I tried to follow in the ARQ library the path of my username and
>>password, and finally they transited to the applyAuthentication in
>>HttpOp.
>>
>>This method create a CredentialsProvider and set the credentials username
>>and
>> password. But this method has a void return type, and I don't see any
>>communication point with the rest of the HttpOp code.
>>
>>Do I missed something ?
>>
>>VAÏSSE-LESTEVEN Arthur.
>>
>>
>>>I was using the 2.9.2 ARQ version. I'll update to 2.10.1.
>>>Thanks for your quick answer and for your work  Rob!
>>>
>>>VAÏSSE-LESTEVEN Arthur.
>>>
>>>
>>>>What version of ARQ are you using?
>>>>
>>>>I put changes in place which went into the 2.10.1 release which should
>>>>permit easy HTTP auth on SPARQL updates.  Both
>>>>UpdateExecutionFactory.createRemote() and
>>>>UpdateExecutionFactory.createRemoteForm() return an instance derived
>>>>from
>>>>UpdateProcessRemoteBase which has a setAuthentication() method
>>>>
>>>>If you are using a version of ARQ prior to 2.10.0 there is no common
>>>>base
>>>>class but both UpdateProcessRemote and UpdateProcessRemoteForm
>> would still
>>>>have a setHttpContext() method which allows you to pass in a
>>>>HttpContext
>>>>which can be used to pass in authentication settings using the
>>>>HttpClient
>>>>APIs.  Even with 2.10.1 you can still choose to use this method
>>>>particularly if you need to pass complex credentials.
>>>>
>>>>Rob
>>>>
>>>>
>>>>On 6/18/13 8:10 AM, "Arthur Vaïsse-Lesteven" <ar...@yahoo.fr>>
>>>>wrote:
>>>>
>>>>>Hi,
>>>>>
>>>>>
>>>>>The remote execution of SPARQL queries offer the
>>>>>setBasicAuthentication
>>>>>fonctionality(1). I'm using it; and when I tried to use it with SPARQL
>>>>>Update it appears that SPARQL Update doesn't handle Authentication.
>>>>>I would like to know, do it exist any way to do the same thing in ARQ
>>>>>? I
>>>>>writted some code by extending 2 apache classes, but it would be
>> better
>>>>>to just use the API. Do you intend to not allow basicAuthentification
>>>>>?
>>>>>It is incompatible with http basic authentication ? There are only
>>>>>24hours per day and you don't had the time to do it yet ?
>>>>>
>>>>>Do this functionality is planed ?
>>>>>
>>>>>______________________________________________________________________
>>>>>_
>>>>>_
>>>>>
>>>>>(1) What i can write :
>>>>>
>>>>>[...]
>>>>>
>>>>>
>>>>>QueryEngineHTTP exec = (QueryEngineHTTP)
>>>>>QueryExecutionFactory.createServiceRequest(endpoint_URL, query);
>>>>>exec.setBasicAuthentication(user, password);
>>>>>
>>>>>exec.exec...
>>>>>
>>>>>[...]
>>>>>
>>>>>(2)What I want to write :
>>>>>
>>>>>[...]
>>>>>UpdateProcessRemote exec =
>> (UpdateProcessRemote)
>>>>>UpdateExecutionFactory.createRemote(update, endpoint_URL);
>>>>>exec.setBasicAuthentication(user, password);
>>>>>
>>>>>exec.excute();
>>>>>
>>>>>[...]
>>>>>
>>>>>
>>>>>
>>>>>I tried to custom the UpdateProcessRemote class to allow (2). This
>>>>>currently don't work on my computer, but it seem's to be due to a
>>>>>maven
>>>>>version conflict at level of HttpClient. This class must be compatible
>>>>>with current version of Jena.( I set my modifications in bold ).( also
>>>>>downlodable at : http://arthurvaisse.free.fr/classes/ )
>>>>>
>>>>>Thank you,
>>>>>VAÏSSE-LESTEVEN Arthur.
>>>>>
>>>>>
>>>>>______________________________________________________________________
>>>>>_
>>>>>_
>>>>>
>>>>>public class UpdateProcessRemote
>> implements UpdateProcessor{
>>>>>
>>>>>    private String user = null ;
>>>>>    private char[] password = null ;
>>>>>
>>>>>    private final UpdateRequest request ;
>>>>>    private final String endpoint ;
>>>>>
>>>>>    public UpdateProcessRemote(UpdateRequest request , String endpoint
>>>>>)
>>>>>    {
>>>>>        this.request = request ;
>>>>>        this.endpoint = endpoint ;
>>>>>
>>>>> }
>>>>>
>>>>>    @Override
>>>>>    public void setInitialBinding(QuerySolution binding)
>>>>>    {
>>>>>        throw new ARQException("Initial bindings
>> for a remote update
>>>>>execution request not supported") ;
>>>>>    }
>>>>>
>>>>>    @Override
>>>>>    public GraphStore getGraphStore()
>>>>>    {
>>>>>        return null ;
>>>>>    }
>>>>>
>>>>>    @Override
>>>>>    public void execute()
>>>>>    {
>>>>>        String reqStr = request.toString() ;
>>>>>      HttpOpCustom.execHttpPost(endpoint,
>>>>>WebContent.contentTypeSPARQLUpdate, reqStr, user, password);
>>>>>    }
>>>>>
>>>>>    //comes from QueryEngineHTTP.
>>>>>    public void
>> setBasicAuthentication(String user, char[] password)
>>>>>
>>>>> {
>>>>>        this.user = user ;
>>>>>        this.password = password ;
>>>>>    }
>>>>>______________________________________________________________________
>>>>>_
>>>>>_
>>>>>
>>>>>I added this functions to HttpOp to create my custom HttpOp :
>>>>>
>>>>>    //Just added credentials in parameters
>>>>>    public static void execHttpPost(String url, String contentType,
>>>>>String content, String user, char[] password)
>>>>>    {
>>>>>        execHttpPost(url, contentType, content, null, null, user,
>>>>>password) ;
>>>>>
>> }
>>>>>
>>>>>
>>>>>    //Just added credentials in parameters
>>>>>    public static void execHttpPost(String url, String contentType,
>>>>>String content,
>>>>>            String acceptType, Map<String, HttpResponseHandler>
>>>>>handlers,
>>>>>            String user, char[] password)
>>>>>    {
>>>>>        StringEntity e = null ;
>>>>>        try
>>>>>        {
>>>>>            e = new StringEntity(content, "UTF-8") ;
>>>>>
>> e.setContentType(contentType) ;
>>>>>            execHttpPost(url, e, acceptType, handlers, user, password)
>>>>>;
>>>>>        } catch (UnsupportedEncodingException e1)
>>>>>        {
>>>>>            throw new ARQInternalErrorException("Platform does not
>>>>>support required UTF-8") ;
>>>>>        } finally { closeEntity(e) ; }
>>>>>    }
>>>>>
>>>>>
>>>>>    public static void execHttpPost(String url,  HttpEntity provider,
>>>>>            String acceptType, Map<String, HttpResponseHandler>
>> handlers,
>>>>>            String user, char[] password)
>>>>>    {
>>>>>        try {
>>>>>            long id = counter.incrementAndGet() ;
>>>>>            String requestURI = determineBaseIRI(url) ;
>>>>>            String baseIRI = determineBaseIRI(requestURI) ;
>>>>>
>>>>>            HttpPost httppost = new HttpPost(requestURI);
>>>>>
>>>>>            if ( user != null || password !=
>> null){
>>>>>                if(user==null || password == null){
>>>>>                    log.warn("Only one of user/password is set") ;
>>>>>                }
>>>>>                //this code come from httpQuery
>>>>>                StringBuffer x = new StringBuffer() ;
>>>>>                byte b[] =
>>>>>x.append(user).append(":").append(password).toString().getBytes("UTF-8
>>>>>"
>>>>>)
>> ;
>>>>>                String y = Base64.encodeBase64String(b) ;
>>>>>                //this single code line is mine
>>>>>                httppost.addHeader("Authorization", "Basic "+y);
>>>>>            }
>>>>>            if ( log.isDebugEnabled() )
>>>>>                log.debug(format("[%d] %s %s",id
>>>>>,httppost.getMethod(),httppost.getURI().toString())) ;
>>>>>
>>>>>            if (
>> provider.getContentType() == null )
>>>>>                log.debug(format("[%d] No content type")) ;
>>>>>
>>>>>            // Execute
>>>>>            HttpClient httpclient = new DefaultHttpClient();
>>>>>            httppost.setEntity(provider) ;
>>>>>            HttpResponse response = httpclient.execute(httppost) ;
>>>>>            httpResponse(id, response, baseIRI, handlers) ;
>>>>>
>>>>>
>> httpclient.getConnectionManager().shutdown();
>>>>>        } catch (IOException ex)
>>>>>        {
>>>>>            ex.printStackTrace(System.err) ;
>>>>>        }
>>>>>        finally { closeEntity(provider) ; }
>>>>>    }
>



Re: Tr : Basic Authentication for SPARQL Update

Posted by Arthur Vaïsse-Lesteven <ar...@yahoo.fr>.
Hi Rob,

It's a little confusing.

You modified the HttpOp class in the release number 34 on the maven repo [1], but this modification isn't present in the last version ( 38 ) as you can see in the java file joined to this mail.

The add of "client.setCredentialsProvider(provider);" line 400 probably solve the problem but I'm not able to test it as it isn't present in the last released version of ARQ.

( The trunk version of your SVN seems to contains this code too ).

Thanks for your work.

VAISSE-LESTEVEN Arthur.


[1] https://repository.apache.org/content/repositories/snapshots/org/apache/jena/jena-arq/2.10.2-SNAPSHOT/


________________________________
 De : Rob Vesse <rv...@yarcdata.com>
À : "users@jena.apache.org" <us...@jena.apache.org> 
Envoyé le : Vendredi 21 juin 2013 19h35
Objet : Re: Tr : Basic Authentication for SPARQL Update
 

The latest SNAPSHOTS now have the fix, you may need to add -U to your mvn
calls if you have recently updated SNAPSHOTs to get the very latest

Please test and confirm whether this resolves the issue

Rob


On 6/21/13 9:13 AM, "Rob Vesse" <rv...@cray.com> wrote:

>Nice catch
>
>Yes I appear to have made an error, I never associated the created
>credentials provider with the HTTP Client
>
>Filed as JENA-475 (https://issues.apache.org/jira/browse/JENA-475)
>
>I will commit a fix ASAP and you should be able to pick up a
>2.10.2-SNAPSHOT build in a few hours with the fix, if you can test with
>the snapshot and report if this resolves the issue that would be great.
>
>You can verify whether the fix has gone into the snapshots by looking at
>https://builds.apache.org/job/Jena__Development_Test/changes and seeing if
>there is a build listed where the commit messages mention JENA-475
>
>Rob
>
>
>
>On 6/20/13 11:51 PM, "Arthur Vaïsse-Lesteven" <ar...@yahoo.fr>
>wrote:
>
>>Hi Rob, I'm in trouble with the basic authentication process ( I'm now
>>using ARQ 2.10.1 )
>>
>>
>>In one hand the Queries work like this :
>>when we calls one of the 4 method execX of a queryExecution, the
>>QueryEngineHTTP calls makeHttpQuery, and after few steps this code line
>>is executed : 
>>    httpConnection.setRequestProperty("Authorization", "Basic "+y) ;
>>where y contains userName:password 64Bits encrypted.
>>
>>This make the http request header contains the Key, Value couple :
>>"Authorization" "Basic username:password".
>>
>>I'm OK with this.
>>
>>In the other hand, the update seem to handle Basic Authentication in a
>>different way.
>>
>>I used this code :
>>
>>UpdateRequest update =
>> UpdateFactory.create(queryString);
>>UpdateProcessRemoteForm exec = (UpdateProcessRemoteForm)
>>UpdateExecutionFactory.createRemoteForm(update, service);
>>exec.setAuthentication("arnaud@gmail.com", "savaillon".toCharArray());
>>
>>And I'm unable to retrieve the usename and the password.
>>Request contains following fields :
>>In headers : 
>>content-lenght : 273
>>content-type : application/x-www-form-urlencoded; charset=UTF-8
>>host : localhost:8080
>>conection : Keep-Alive
>>user-agent: Apache-HttpClient/4.2.3 (java 1.5)
>>In params : 
>>update : my update
>>No attribute.
>>
>>I tried to follow in the ARQ library the path of my username and
>>password, and finally they transited to the applyAuthentication in
>>HttpOp.
>>
>>This method create a CredentialsProvider and set the credentials username
>>and
>> password. But this method has a void return type, and I don't see any
>>communication point with the rest of the HttpOp code.
>>
>>Do I missed something ?
>>
>>VAÏSSE-LESTEVEN Arthur.
>>
>>
>>>I was using the 2.9.2 ARQ version. I'll update to 2.10.1.
>>>Thanks for your quick answer and for your work  Rob!
>>>
>>>VAÏSSE-LESTEVEN Arthur.
>>>
>>>
>>>>What version of ARQ are you using?
>>>>
>>>>I put changes in place which went into the 2.10.1 release which should
>>>>permit easy HTTP auth on SPARQL updates.  Both
>>>>UpdateExecutionFactory.createRemote() and
>>>>UpdateExecutionFactory.createRemoteForm() return an instance derived
>>>>from
>>>>UpdateProcessRemoteBase which has a setAuthentication() method
>>>>
>>>>If you are using a version of ARQ prior to 2.10.0 there is no common
>>>>base
>>>>class but both UpdateProcessRemote and UpdateProcessRemoteForm
>> would still
>>>>have a setHttpContext() method which allows you to pass in a
>>>>HttpContext
>>>>which can be used to pass in authentication settings using the
>>>>HttpClient
>>>>APIs.  Even with 2.10.1 you can still choose to use this method
>>>>particularly if you need to pass complex credentials.
>>>>
>>>>Rob
>>>>
>>>>
>>>>On 6/18/13 8:10 AM, "Arthur Vaïsse-Lesteven" <ar...@yahoo.fr>
>>>>wrote:
>>>>
>>>>>Hi,
>>>>>
>>>>>
>>>>>The remote execution of SPARQL queries offer the
>>>>>setBasicAuthentication
>>>>>fonctionality(1). I'm using it; and when I tried to use it with SPARQL
>>>>>Update it appears that SPARQL Update doesn't handle Authentication.
>>>>>I would like to know, do it exist any way to do the same thing in ARQ
>>>>>? I
>>>>>writted some code by extending 2 apache classes, but it would be
>> better
>>>>>to just use the API. Do you intend to not allow basicAuthentification
>>>>>?
>>>>>It is incompatible with http basic authentication ? There are only
>>>>>24hours per day and you don't had the time to do it yet ?
>>>>>
>>>>>Do this functionality is planed ?
>>>>>
>>>>>______________________________________________________________________
>>>>>_
>>>>>_
>>>>>
>>>>>(1) What i can write :
>>>>>
>>>>>[...]
>>>>>
>>>>>
>>>>>QueryEngineHTTP exec = (QueryEngineHTTP)
>>>>>QueryExecutionFactory.createServiceRequest(endpoint_URL, query);
>>>>>exec.setBasicAuthentication(user, password);
>>>>>
>>>>>exec.exec...
>>>>>
>>>>>[...]
>>>>>
>>>>>(2)What I want to write :
>>>>>
>>>>>[...]
>>>>>UpdateProcessRemote exec =
>> (UpdateProcessRemote)
>>>>>UpdateExecutionFactory.createRemote(update, endpoint_URL);
>>>>>exec.setBasicAuthentication(user, password);
>>>>>
>>>>>exec.excute();
>>>>>
>>>>>[...]
>>>>>
>>>>>
>>>>>
>>>>>I tried to custom the UpdateProcessRemote class to allow (2). This
>>>>>currently don't work on my computer, but it seem's to be due to a
>>>>>maven
>>>>>version conflict at level of HttpClient. This class must be compatible
>>>>>with current version of Jena.( I set my modifications in bold ).( also
>>>>>downlodable at : http://arthurvaisse.free.fr/classes/ )
>>>>>
>>>>>Thank you,
>>>>>VAÏSSE-LESTEVEN Arthur.
>>>>>
>>>>>
>>>>>______________________________________________________________________
>>>>>_
>>>>>_
>>>>>
>>>>>public class UpdateProcessRemote
>> implements UpdateProcessor{
>>>>>
>>>>>    private String user = null ;
>>>>>    private char[] password = null ;
>>>>>
>>>>>    private final UpdateRequest request ;
>>>>>    private final String endpoint ;
>>>>>
>>>>>    public UpdateProcessRemote(UpdateRequest request , String endpoint
>>>>>)
>>>>>    {
>>>>>        this.request = request ;
>>>>>        this.endpoint = endpoint ;
>>>>>
>>>>> }
>>>>>
>>>>>    @Override
>>>>>    public void setInitialBinding(QuerySolution binding)
>>>>>    {
>>>>>        throw new ARQException("Initial bindings
>> for a remote update
>>>>>execution request not supported") ;
>>>>>    }
>>>>>
>>>>>    @Override
>>>>>    public GraphStore getGraphStore()
>>>>>    {
>>>>>        return null ;
>>>>>    }
>>>>>
>>>>>    @Override
>>>>>    public void execute()
>>>>>    {
>>>>>        String reqStr = request.toString() ;
>>>>>      HttpOpCustom.execHttpPost(endpoint,
>>>>>WebContent.contentTypeSPARQLUpdate, reqStr, user, password);
>>>>>    }
>>>>>
>>>>>    //comes from QueryEngineHTTP.
>>>>>    public void
>> setBasicAuthentication(String user, char[] password)
>>>>>
>>>>> {
>>>>>        this.user = user ;
>>>>>        this.password = password ;
>>>>>    }
>>>>>______________________________________________________________________
>>>>>_
>>>>>_
>>>>>
>>>>>I added this functions to HttpOp to create my custom HttpOp :
>>>>>
>>>>>    //Just added credentials in parameters
>>>>>    public static void execHttpPost(String url, String contentType,
>>>>>String content, String user, char[] password)
>>>>>    {
>>>>>        execHttpPost(url, contentType, content, null, null, user,
>>>>>password) ;
>>>>>  
>> }
>>>>>
>>>>>
>>>>>    //Just added credentials in parameters
>>>>>    public static void execHttpPost(String url, String contentType,
>>>>>String content,
>>>>>            String acceptType, Map<String, HttpResponseHandler>
>>>>>handlers,
>>>>>            String user, char[] password)
>>>>>    {
>>>>>        StringEntity e = null ;
>>>>>        try
>>>>>        {
>>>>>            e = new StringEntity(content, "UTF-8") ;
>>>>>          
>> e.setContentType(contentType) ;
>>>>>            execHttpPost(url, e, acceptType, handlers, user, password)
>>>>>;
>>>>>        } catch (UnsupportedEncodingException e1)
>>>>>        {
>>>>>            throw new ARQInternalErrorException("Platform does not
>>>>>support required UTF-8") ;
>>>>>        } finally { closeEntity(e) ; }
>>>>>    }
>>>>>
>>>>>
>>>>>    public static void execHttpPost(String url,  HttpEntity provider,
>>>>>            String acceptType, Map<String, HttpResponseHandler>
>> handlers,
>>>>>            String user, char[] password)
>>>>>    {
>>>>>        try {
>>>>>            long id = counter.incrementAndGet() ;
>>>>>            String requestURI = determineBaseIRI(url) ;
>>>>>            String baseIRI = determineBaseIRI(requestURI) ;
>>>>>
>>>>>            HttpPost httppost = new HttpPost(requestURI);
>>>>>
>>>>>            if ( user != null || password !=
>> null){
>>>>>                if(user==null || password == null){
>>>>>                    log.warn("Only one of user/password is set") ;
>>>>>                }
>>>>>                //this code come from httpQuery
>>>>>                StringBuffer x = new StringBuffer() ;
>>>>>                byte b[] =
>>>>>x.append(user).append(":").append(password).toString().getBytes("UTF-8
>>>>>"
>>>>>)
>> ;
>>>>>                String y = Base64.encodeBase64String(b) ;
>>>>>                //this single code line is mine
>>>>>                httppost.addHeader("Authorization", "Basic "+y);
>>>>>            }
>>>>>            if ( log.isDebugEnabled() )
>>>>>                log.debug(format("[%d] %s %s",id
>>>>>,httppost.getMethod(),httppost.getURI().toString())) ;
>>>>>
>>>>>            if (
>> provider.getContentType() == null )
>>>>>                log.debug(format("[%d] No content type")) ;
>>>>>
>>>>>            // Execute
>>>>>            HttpClient httpclient = new DefaultHttpClient();
>>>>>            httppost.setEntity(provider) ;
>>>>>            HttpResponse response = httpclient.execute(httppost) ;
>>>>>            httpResponse(id, response, baseIRI, handlers) ;
>>>>>
>>>>>          
>> httpclient.getConnectionManager().shutdown();
>>>>>        } catch (IOException ex)
>>>>>        {
>>>>>            ex.printStackTrace(System.err) ;
>>>>>        }
>>>>>        finally { closeEntity(provider) ; }
>>>>>    }
>

Re: Tr : Basic Authentication for SPARQL Update

Posted by Rob Vesse <rv...@yarcdata.com>.
The latest SNAPSHOTS now have the fix, you may need to add -U to your mvn
calls if you have recently updated SNAPSHOTs to get the very latest

Please test and confirm whether this resolves the issue

Rob


On 6/21/13 9:13 AM, "Rob Vesse" <rv...@cray.com> wrote:

>Nice catch
>
>Yes I appear to have made an error, I never associated the created
>credentials provider with the HTTP Client
>
>Filed as JENA-475 (https://issues.apache.org/jira/browse/JENA-475)
>
>I will commit a fix ASAP and you should be able to pick up a
>2.10.2-SNAPSHOT build in a few hours with the fix, if you can test with
>the snapshot and report if this resolves the issue that would be great.
>
>You can verify whether the fix has gone into the snapshots by looking at
>https://builds.apache.org/job/Jena__Development_Test/changes and seeing if
>there is a build listed where the commit messages mention JENA-475
>
>Rob
>
>
>
>On 6/20/13 11:51 PM, "Arthur Vaïsse-Lesteven" <ar...@yahoo.fr>
>wrote:
>
>>Hi Rob, I'm in trouble with the basic authentication process ( I'm now
>>using ARQ 2.10.1 )
>>
>>
>>In one hand the Queries work like this :
>>when we calls one of the 4 method execX of a queryExecution, the
>>QueryEngineHTTP calls makeHttpQuery, and after few steps this code line
>>is executed : 
>>    httpConnection.setRequestProperty("Authorization", "Basic "+y) ;
>>where y contains userName:password 64Bits encrypted.
>>
>>This make the http request header contains the Key, Value couple :
>>"Authorization" "Basic username:password".
>>
>>I'm OK with this.
>>
>>In the other hand, the update seem to handle Basic Authentication in a
>>different way.
>>
>>I used this code :
>>
>>UpdateRequest update =
>> UpdateFactory.create(queryString);
>>UpdateProcessRemoteForm exec = (UpdateProcessRemoteForm)
>>UpdateExecutionFactory.createRemoteForm(update, service);
>>exec.setAuthentication("arnaud@gmail.com", "savaillon".toCharArray());
>>
>>And I'm unable to retrieve the usename and the password.
>>Request contains following fields :
>>In headers : 
>>content-lenght : 273
>>content-type : application/x-www-form-urlencoded; charset=UTF-8
>>host : localhost:8080
>>conection : Keep-Alive
>>user-agent: Apache-HttpClient/4.2.3 (java 1.5)
>>In params : 
>>update : my update
>>No attribute.
>>
>>I tried to follow in the ARQ library the path of my username and
>>password, and finally they transited to the applyAuthentication in
>>HttpOp.
>>
>>This method create a CredentialsProvider and set the credentials username
>>and
>> password. But this method has a void return type, and I don't see any
>>communication point with the rest of the HttpOp code.
>>
>>Do I missed something ?
>>
>>VAÏSSE-LESTEVEN Arthur.
>>
>>
>>>I was using the 2.9.2 ARQ version. I'll update to 2.10.1.
>>>Thanks for your quick answer and for your work  Rob!
>>>
>>>VAÏSSE-LESTEVEN Arthur.
>>>
>>>
>>>>What version of ARQ are you using?
>>>>
>>>>I put changes in place which went into the 2.10.1 release which should
>>>>permit easy HTTP auth on SPARQL updates.  Both
>>>>UpdateExecutionFactory.createRemote() and
>>>>UpdateExecutionFactory.createRemoteForm() return an instance derived
>>>>from
>>>>UpdateProcessRemoteBase which has a setAuthentication() method
>>>>
>>>>If you are using a version of ARQ prior to 2.10.0 there is no common
>>>>base
>>>>class but both UpdateProcessRemote and UpdateProcessRemoteForm
>> would still
>>>>have a setHttpContext() method which allows you to pass in a
>>>>HttpContext
>>>>which can be used to pass in authentication settings using the
>>>>HttpClient
>>>>APIs.  Even with 2.10.1 you can still choose to use this method
>>>>particularly if you need to pass complex credentials.
>>>>
>>>>Rob
>>>>
>>>>
>>>>On 6/18/13 8:10 AM, "Arthur Vaïsse-Lesteven" <ar...@yahoo.fr>
>>>>wrote:
>>>>
>>>>>Hi,
>>>>>
>>>>>
>>>>>The remote execution of SPARQL queries offer the
>>>>>setBasicAuthentication
>>>>>fonctionality(1). I'm using it; and when I tried to use it with SPARQL
>>>>>Update it appears that SPARQL Update doesn't handle Authentication.
>>>>>I would like to know, do it exist any way to do the same thing in ARQ
>>>>>? I
>>>>>writted some code by extending 2 apache classes, but it would be
>> better
>>>>>to just use the API. Do you intend to not allow basicAuthentification
>>>>>?
>>>>>It is incompatible with http basic authentication ? There are only
>>>>>24hours per day and you don't had the time to do it yet ?
>>>>>
>>>>>Do this functionality is planed ?
>>>>>
>>>>>______________________________________________________________________
>>>>>_
>>>>>_
>>>>>
>>>>>(1) What i can write :
>>>>>
>>>>>[...]
>>>>>
>>>>>
>>>>>QueryEngineHTTP exec = (QueryEngineHTTP)
>>>>>QueryExecutionFactory.createServiceRequest(endpoint_URL, query);
>>>>>exec.setBasicAuthentication(user, password);
>>>>>
>>>>>exec.exec...
>>>>>
>>>>>[...]
>>>>>
>>>>>(2)What I want to write :
>>>>>
>>>>>[...]
>>>>>UpdateProcessRemote exec =
>> (UpdateProcessRemote)
>>>>>UpdateExecutionFactory.createRemote(update, endpoint_URL);
>>>>>exec.setBasicAuthentication(user, password);
>>>>>
>>>>>exec.excute();
>>>>>
>>>>>[...]
>>>>>
>>>>>
>>>>>
>>>>>I tried to custom the UpdateProcessRemote class to allow (2). This
>>>>>currently don't work on my computer, but it seem's to be due to a
>>>>>maven
>>>>>version conflict at level of HttpClient. This class must be compatible
>>>>>with current version of Jena.( I set my modifications in bold ).( also
>>>>>downlodable at : http://arthurvaisse.free.fr/classes/ )
>>>>>
>>>>>Thank you,
>>>>>VAÏSSE-LESTEVEN Arthur.
>>>>>
>>>>>
>>>>>______________________________________________________________________
>>>>>_
>>>>>_
>>>>>
>>>>>public class UpdateProcessRemote
>> implements UpdateProcessor{
>>>>>
>>>>>    private String user = null ;
>>>>>    private char[] password = null ;
>>>>>
>>>>>    private final UpdateRequest request ;
>>>>>    private final String endpoint ;
>>>>>
>>>>>    public UpdateProcessRemote(UpdateRequest request , String endpoint
>>>>>)
>>>>>    {
>>>>>        this.request = request ;
>>>>>        this.endpoint = endpoint ;
>>>>>
>>>>> }
>>>>>
>>>>>    @Override
>>>>>    public void setInitialBinding(QuerySolution binding)
>>>>>    {
>>>>>        throw new ARQException("Initial bindings
>> for a remote update
>>>>>execution request not supported") ;
>>>>>    }
>>>>>
>>>>>    @Override
>>>>>    public GraphStore getGraphStore()
>>>>>    {
>>>>>        return null ;
>>>>>    }
>>>>>
>>>>>    @Override
>>>>>    public void execute()
>>>>>    {
>>>>>        String reqStr = request.toString() ;
>>>>>      HttpOpCustom.execHttpPost(endpoint,
>>>>>WebContent.contentTypeSPARQLUpdate, reqStr, user, password);
>>>>>    }
>>>>>
>>>>>    //comes from QueryEngineHTTP.
>>>>>    public void
>> setBasicAuthentication(String user, char[] password)
>>>>>
>>>>> {
>>>>>        this.user = user ;
>>>>>        this.password = password ;
>>>>>    }
>>>>>______________________________________________________________________
>>>>>_
>>>>>_
>>>>>
>>>>>I added this functions to HttpOp to create my custom HttpOp :
>>>>>
>>>>>    //Just added credentials in parameters
>>>>>    public static void execHttpPost(String url, String contentType,
>>>>>String content, String user, char[] password)
>>>>>    {
>>>>>        execHttpPost(url, contentType, content, null, null, user,
>>>>>password) ;
>>>>>   
>> }
>>>>>
>>>>>
>>>>>    //Just added credentials in parameters
>>>>>    public static void execHttpPost(String url, String contentType,
>>>>>String content,
>>>>>            String acceptType, Map<String, HttpResponseHandler>
>>>>>handlers,
>>>>>            String user, char[] password)
>>>>>    {
>>>>>        StringEntity e = null ;
>>>>>        try
>>>>>        {
>>>>>            e = new StringEntity(content, "UTF-8") ;
>>>>>           
>> e.setContentType(contentType) ;
>>>>>            execHttpPost(url, e, acceptType, handlers, user, password)
>>>>>;
>>>>>        } catch (UnsupportedEncodingException e1)
>>>>>        {
>>>>>            throw new ARQInternalErrorException("Platform does not
>>>>>support required UTF-8") ;
>>>>>        } finally { closeEntity(e) ; }
>>>>>    }
>>>>>
>>>>>
>>>>>    public static void execHttpPost(String url,  HttpEntity provider,
>>>>>            String acceptType, Map<String, HttpResponseHandler>
>> handlers,
>>>>>            String user, char[] password)
>>>>>    {
>>>>>        try {
>>>>>            long id = counter.incrementAndGet() ;
>>>>>            String requestURI = determineBaseIRI(url) ;
>>>>>            String baseIRI = determineBaseIRI(requestURI) ;
>>>>>
>>>>>            HttpPost httppost = new HttpPost(requestURI);
>>>>>
>>>>>            if ( user != null || password !=
>> null){
>>>>>                if(user==null || password == null){
>>>>>                    log.warn("Only one of user/password is set") ;
>>>>>                }
>>>>>                //this code come from httpQuery
>>>>>                StringBuffer x = new StringBuffer() ;
>>>>>                byte b[] =
>>>>>x.append(user).append(":").append(password).toString().getBytes("UTF-8
>>>>>"
>>>>>)
>> ;
>>>>>                String y = Base64.encodeBase64String(b) ;
>>>>>                //this single code line is mine
>>>>>                httppost.addHeader("Authorization", "Basic "+y);
>>>>>            }
>>>>>            if ( log.isDebugEnabled() )
>>>>>                log.debug(format("[%d] %s %s",id
>>>>>,httppost.getMethod(),httppost.getURI().toString())) ;
>>>>>
>>>>>            if (
>> provider.getContentType() == null )
>>>>>                log.debug(format("[%d] No content type")) ;
>>>>>
>>>>>            // Execute
>>>>>            HttpClient httpclient = new DefaultHttpClient();
>>>>>            httppost.setEntity(provider) ;
>>>>>            HttpResponse response = httpclient.execute(httppost) ;
>>>>>            httpResponse(id, response, baseIRI, handlers) ;
>>>>>
>>>>>           
>> httpclient.getConnectionManager().shutdown();
>>>>>        } catch (IOException ex)
>>>>>        {
>>>>>            ex.printStackTrace(System.err) ;
>>>>>        }
>>>>>        finally { closeEntity(provider) ; }
>>>>>    }
>


Re: Tr : Basic Authentication for SPARQL Update

Posted by Rob Vesse <rv...@yarcdata.com>.
Nice catch

Yes I appear to have made an error, I never associated the created
credentials provider with the HTTP Client

Filed as JENA-475 (https://issues.apache.org/jira/browse/JENA-475)

I will commit a fix ASAP and you should be able to pick up a
2.10.2-SNAPSHOT build in a few hours with the fix, if you can test with
the snapshot and report if this resolves the issue that would be great.

You can verify whether the fix has gone into the snapshots by looking at
https://builds.apache.org/job/Jena__Development_Test/changes and seeing if
there is a build listed where the commit messages mention JENA-475

Rob



On 6/20/13 11:51 PM, "Arthur Vaïsse-Lesteven" <ar...@yahoo.fr>
wrote:

>Hi Rob, I'm in trouble with the basic authentication process ( I'm now
>using ARQ 2.10.1 )
>
>
>In one hand the Queries work like this :
>when we calls one of the 4 method execX of a queryExecution, the
>QueryEngineHTTP calls makeHttpQuery, and after few steps this code line
>is executed : 
>    httpConnection.setRequestProperty("Authorization", "Basic "+y) ;
>where y contains userName:password 64Bits encrypted.
>
>This make the http request header contains the Key, Value couple :
>"Authorization" "Basic username:password".
>
>I'm OK with this.
>
>In the other hand, the update seem to handle Basic Authentication in a
>different way.
>
>I used this code :
>
>UpdateRequest update =
> UpdateFactory.create(queryString);
>UpdateProcessRemoteForm exec = (UpdateProcessRemoteForm)
>UpdateExecutionFactory.createRemoteForm(update, service);
>exec.setAuthentication("arnaud@gmail.com", "savaillon".toCharArray());
>
>And I'm unable to retrieve the usename and the password.
>Request contains following fields :
>In headers : 
>content-lenght : 273
>content-type : application/x-www-form-urlencoded; charset=UTF-8
>host : localhost:8080
>conection : Keep-Alive
>user-agent: Apache-HttpClient/4.2.3 (java 1.5)
>In params : 
>update : my update
>No attribute.
>
>I tried to follow in the ARQ library the path of my username and
>password, and finally they transited to the applyAuthentication in HttpOp.
>
>This method create a CredentialsProvider and set the credentials username
>and
> password. But this method has a void return type, and I don't see any
>communication point with the rest of the HttpOp code.
>
>Do I missed something ?
>
>VAÏSSE-LESTEVEN Arthur.
>
>
>>I was using the 2.9.2 ARQ version. I'll update to 2.10.1.
>>Thanks for your quick answer and for your work  Rob!
>>
>>VAÏSSE-LESTEVEN Arthur.
>>
>>
>>>What version of ARQ are you using?
>>>
>>>I put changes in place which went into the 2.10.1 release which should
>>>permit easy HTTP auth on SPARQL updates.  Both
>>>UpdateExecutionFactory.createRemote() and
>>>UpdateExecutionFactory.createRemoteForm() return an instance derived
>>>from
>>>UpdateProcessRemoteBase which has a setAuthentication() method
>>>
>>>If you are using a version of ARQ prior to 2.10.0 there is no common
>>>base
>>>class but both UpdateProcessRemote and UpdateProcessRemoteForm
> would still
>>>have a setHttpContext() method which allows you to pass in a HttpContext
>>>which can be used to pass in authentication settings using the
>>>HttpClient
>>>APIs.  Even with 2.10.1 you can still choose to use this method
>>>particularly if you need to pass complex credentials.
>>>
>>>Rob
>>>
>>>
>>>On 6/18/13 8:10 AM, "Arthur Vaïsse-Lesteven" <ar...@yahoo.fr>
>>>wrote:
>>>
>>>>Hi,
>>>>
>>>>
>>>>The remote execution of SPARQL queries offer the setBasicAuthentication
>>>>fonctionality(1). I'm using it; and when I tried to use it with SPARQL
>>>>Update it appears that SPARQL Update doesn't handle Authentication.
>>>>I would like to know, do it exist any way to do the same thing in ARQ
>>>>? I
>>>>writted some code by extending 2 apache classes, but it would be
> better
>>>>to just use the API. Do you intend to not allow basicAuthentification ?
>>>>It is incompatible with http basic authentication ? There are only
>>>>24hours per day and you don't had the time to do it yet ?
>>>>
>>>>Do this functionality is planed ?
>>>>
>>>>_______________________________________________________________________
>>>>_
>>>>
>>>>(1) What i can write :
>>>>
>>>>[...]
>>>>
>>>>
>>>>QueryEngineHTTP exec = (QueryEngineHTTP)
>>>>QueryExecutionFactory.createServiceRequest(endpoint_URL, query);
>>>>exec.setBasicAuthentication(user, password);
>>>>
>>>>exec.exec...
>>>>
>>>>[...]
>>>>
>>>>(2)What I want to write :
>>>>
>>>>[...]
>>>>UpdateProcessRemote exec =
> (UpdateProcessRemote)
>>>>UpdateExecutionFactory.createRemote(update, endpoint_URL);
>>>>exec.setBasicAuthentication(user, password);
>>>>
>>>>exec.excute();
>>>>
>>>>[...]
>>>>
>>>>
>>>>
>>>>I tried to custom the UpdateProcessRemote class to allow (2). This
>>>>currently don't work on my computer, but it seem's to be due to a maven
>>>>version conflict at level of HttpClient. This class must be compatible
>>>>with current version of Jena.( I set my modifications in bold ).( also
>>>>downlodable at : http://arthurvaisse.free.fr/classes/ )
>>>>
>>>>Thank you,
>>>>VAÏSSE-LESTEVEN Arthur.
>>>>
>>>>
>>>>_______________________________________________________________________
>>>>_
>>>>
>>>>public class UpdateProcessRemote
> implements UpdateProcessor{
>>>>
>>>>    private String user = null ;
>>>>    private char[] password = null ;
>>>>
>>>>    private final UpdateRequest request ;
>>>>    private final String endpoint ;
>>>>
>>>>    public UpdateProcessRemote(UpdateRequest request , String endpoint
>>>>)
>>>>    {
>>>>        this.request = request ;
>>>>        this.endpoint = endpoint ;
>>>>
>>>> }
>>>>
>>>>    @Override
>>>>    public void setInitialBinding(QuerySolution binding)
>>>>    {
>>>>        throw new ARQException("Initial bindings
> for a remote update
>>>>execution request not supported") ;
>>>>    }
>>>>
>>>>    @Override
>>>>    public GraphStore getGraphStore()
>>>>    {
>>>>        return null ;
>>>>    }
>>>>
>>>>    @Override
>>>>    public void execute()
>>>>    {
>>>>        String reqStr = request.toString() ;
>>>>      HttpOpCustom.execHttpPost(endpoint,
>>>>WebContent.contentTypeSPARQLUpdate, reqStr, user, password);
>>>>    }
>>>>
>>>>    //comes from QueryEngineHTTP.
>>>>    public void
> setBasicAuthentication(String user, char[] password)
>>>>
>>>> {
>>>>        this.user = user ;
>>>>        this.password = password ;
>>>>    }
>>>>_______________________________________________________________________
>>>>_
>>>>
>>>>I added this functions to HttpOp to create my custom HttpOp :
>>>>
>>>>    //Just added credentials in parameters
>>>>    public static void execHttpPost(String url, String contentType,
>>>>String content, String user, char[] password)
>>>>    {
>>>>        execHttpPost(url, contentType, content, null, null, user,
>>>>password) ;
>>>>   
> }
>>>>
>>>>
>>>>    //Just added credentials in parameters
>>>>    public static void execHttpPost(String url, String contentType,
>>>>String content,
>>>>            String acceptType, Map<String, HttpResponseHandler>
>>>>handlers,
>>>>            String user, char[] password)
>>>>    {
>>>>        StringEntity e = null ;
>>>>        try
>>>>        {
>>>>            e = new StringEntity(content, "UTF-8") ;
>>>>           
> e.setContentType(contentType) ;
>>>>            execHttpPost(url, e, acceptType, handlers, user, password)
>>>>;
>>>>        } catch (UnsupportedEncodingException e1)
>>>>        {
>>>>            throw new ARQInternalErrorException("Platform does not
>>>>support required UTF-8") ;
>>>>        } finally { closeEntity(e) ; }
>>>>    }
>>>>
>>>>
>>>>    public static void execHttpPost(String url,  HttpEntity provider,
>>>>            String acceptType, Map<String, HttpResponseHandler>
> handlers,
>>>>            String user, char[] password)
>>>>    {
>>>>        try {
>>>>            long id = counter.incrementAndGet() ;
>>>>            String requestURI = determineBaseIRI(url) ;
>>>>            String baseIRI = determineBaseIRI(requestURI) ;
>>>>
>>>>            HttpPost httppost = new HttpPost(requestURI);
>>>>
>>>>            if ( user != null || password !=
> null){
>>>>                if(user==null || password == null){
>>>>                    log.warn("Only one of user/password is set") ;
>>>>                }
>>>>                //this code come from httpQuery
>>>>                StringBuffer x = new StringBuffer() ;
>>>>                byte b[] =
>>>>x.append(user).append(":").append(password).toString().getBytes("UTF-8"
>>>>)
> ;
>>>>                String y = Base64.encodeBase64String(b) ;
>>>>                //this single code line is mine
>>>>                httppost.addHeader("Authorization", "Basic "+y);
>>>>            }
>>>>            if ( log.isDebugEnabled() )
>>>>                log.debug(format("[%d] %s %s",id
>>>>,httppost.getMethod(),httppost.getURI().toString())) ;
>>>>
>>>>            if (
> provider.getContentType() == null )
>>>>                log.debug(format("[%d] No content type")) ;
>>>>
>>>>            // Execute
>>>>            HttpClient httpclient = new DefaultHttpClient();
>>>>            httppost.setEntity(provider) ;
>>>>            HttpResponse response = httpclient.execute(httppost) ;
>>>>            httpResponse(id, response, baseIRI, handlers) ;
>>>>
>>>>           
> httpclient.getConnectionManager().shutdown();
>>>>        } catch (IOException ex)
>>>>        {
>>>>            ex.printStackTrace(System.err) ;
>>>>        }
>>>>        finally { closeEntity(provider) ; }
>>>>    }