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" <[email protected]>
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("[email protected]", "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" <[email protected]>
>>>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) ; }
>>>>    }

Reply via email to