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/18 17:10:03 UTC

Re: Basic Authentification for SPARQL update.

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: Basic Authentification for SPARQL update.

Posted by Rob Vesse <rv...@yarcdata.com>.
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) ; }
>    }