[ 
https://issues.apache.org/jira/browse/DRILL-5726?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Arina Ielchiieva updated DRILL-5726:
------------------------------------
    Description: 
Today if a user is not authenticated via REST API then there is no way to 
provide a user name for executing queries. It will by default be executed as 
"anonymous" user. This doesn't work when impersonation without authentication 
is enabled on Drill server side, since anonymous user doesn't exist the query 
will fail. We need a way to provide a user name when impersonation is enabled 
on Drill side and query is executed from REST API.

There are two approaches to achieve that:
*1. Use form-based authentication*
On Web UI user will be prompted to enter only login, then session for that user 
will be created, user will be treated as admin. Form-based authentication will 
cache user information, so user won't need to set user name each time he / she 
wants to execute the query. Log in / out options will be also available. 
Example screenshot of login page is attached (login_page.JPG).
>From the programmatic perspective, user would need first to authenticate and 
>use cookie to get query result.

*2. Use {{User-Name}} header in request*
On Web UI on Query page additional input field will appear. User would need to 
enter user name before issuing the query. Example screenshot of query page is 
attached (query_page_with_user_name.JPG). Under the hood with user name would 
be added to client request as request header. On server side this header would 
be used to create user session principal. From the programmatic perspective, 
user would need to add header when issuing the request.

>From the two above options second was chosen as it would ease REST API usage 
>from the programmatic perspective, plus using form-based authentication may 
>lead to false assumption that user is authenticated which is in reality is not 
>true. 

*Implementation details of the second approach:*
_Note: the below implementation will take affect only if authentication is 
disabled and impersonation is enabled. By means of freemarker page won't 
include js lib and script if condition is not met._
On the client side additional input field was added to the query page. When 
client is submitting the query, request would be changed using ajax to add 
{{User-Name}} header which would be taken from the new input field. On the 
server side, this header would be used to create session principal with 
provided user name and admin rights. If user name header was not provided (null 
or empty), the default anonymous principal will be used.

*Adding user name header approaches:*
_Web UI_ 
enter user name in the User Name input field on Query page before submiiting 
the query (query_page_with_user_name.JPG)
_sqlline_
{code}./drill-localhost -n user1{code}
_curl_ 
{code} curl -v -H "Content-Type: application/json" -H "User-Name: user1" -d 
'{"queryType":"SQL", "query": "select * from sys.version"}' 
http://localhost:8047/query.json {code}
_Java way_
{code}
    String url = "http://localhost:8047/query.json";;
    URLConnection connection = new URL(url).openConnection();
    connection.setDoOutput(true); // Triggers POST.
    connection.addRequestProperty("User-Name", "user1");
    connection.setRequestProperty("Content-Type", "application/json");

    String data = "{\"queryType\":\"SQL\", \"query\": \"select * from 
sys.version\"}";
    try (OutputStream output = connection.getOutputStream()) {
      output.write(data.getBytes(StandardCharsets.UTF_8.name()));
    }

    try (InputStream response = connection.getInputStream()) {
      String result = IOUtils.toString(response);
      System.out.println(result);
    }
{code}
Note: {{Apache HttpClient}} can be used as well.

  was:
Today if a user is not authenticated via REST API then there is no way to 
provide a user name for executing queries. It will by default be executed as 
"anonymous" user. This doesn't work when impersonation without authentication 
is enabled on Drill server side, since anonymous user doesn't exist the query 
will fail. We need a way to provide a user name when impersonation is enabled 
on Drill side and query is executed from REST API.

_Implementation details:_
When only impersonation is enabled form-based authentication will be used.
On Web UI user will be prompted to enter only login, then session for that user 
will be created, user will be treated as admin. Form-based authentication will 
cache user information, so user won't need to set username each time he / she 
wants to execute the query. Log in / out options will be also available. 
Screenshot of login page is attached.


> Support Impersonation without authentication for REST API
> ---------------------------------------------------------
>
>                 Key: DRILL-5726
>                 URL: https://issues.apache.org/jira/browse/DRILL-5726
>             Project: Apache Drill
>          Issue Type: Improvement
>    Affects Versions: 1.11.0
>            Reporter: Arina Ielchiieva
>            Assignee: Arina Ielchiieva
>             Fix For: 1.12.0
>
>         Attachments: login_page.JPG, query_page_with_user_name.JPG
>
>
> Today if a user is not authenticated via REST API then there is no way to 
> provide a user name for executing queries. It will by default be executed as 
> "anonymous" user. This doesn't work when impersonation without authentication 
> is enabled on Drill server side, since anonymous user doesn't exist the query 
> will fail. We need a way to provide a user name when impersonation is enabled 
> on Drill side and query is executed from REST API.
> There are two approaches to achieve that:
> *1. Use form-based authentication*
> On Web UI user will be prompted to enter only login, then session for that 
> user will be created, user will be treated as admin. Form-based 
> authentication will cache user information, so user won't need to set user 
> name each time he / she wants to execute the query. Log in / out options will 
> be also available. Example screenshot of login page is attached 
> (login_page.JPG).
> From the programmatic perspective, user would need first to authenticate and 
> use cookie to get query result.
> *2. Use {{User-Name}} header in request*
> On Web UI on Query page additional input field will appear. User would need 
> to enter user name before issuing the query. Example screenshot of query page 
> is attached (query_page_with_user_name.JPG). Under the hood with user name 
> would be added to client request as request header. On server side this 
> header would be used to create user session principal. From the programmatic 
> perspective, user would need to add header when issuing the request.
> From the two above options second was chosen as it would ease REST API usage 
> from the programmatic perspective, plus using form-based authentication may 
> lead to false assumption that user is authenticated which is in reality is 
> not true. 
> *Implementation details of the second approach:*
> _Note: the below implementation will take affect only if authentication is 
> disabled and impersonation is enabled. By means of freemarker page won't 
> include js lib and script if condition is not met._
> On the client side additional input field was added to the query page. When 
> client is submitting the query, request would be changed using ajax to add 
> {{User-Name}} header which would be taken from the new input field. On the 
> server side, this header would be used to create session principal with 
> provided user name and admin rights. If user name header was not provided 
> (null or empty), the default anonymous principal will be used.
> *Adding user name header approaches:*
> _Web UI_ 
> enter user name in the User Name input field on Query page before submiiting 
> the query (query_page_with_user_name.JPG)
> _sqlline_
> {code}./drill-localhost -n user1{code}
> _curl_ 
> {code} curl -v -H "Content-Type: application/json" -H "User-Name: user1" -d 
> '{"queryType":"SQL", "query": "select * from sys.version"}' 
> http://localhost:8047/query.json {code}
> _Java way_
> {code}
>     String url = "http://localhost:8047/query.json";;
>     URLConnection connection = new URL(url).openConnection();
>     connection.setDoOutput(true); // Triggers POST.
>     connection.addRequestProperty("User-Name", "user1");
>     connection.setRequestProperty("Content-Type", "application/json");
>     String data = "{\"queryType\":\"SQL\", \"query\": \"select * from 
> sys.version\"}";
>     try (OutputStream output = connection.getOutputStream()) {
>       output.write(data.getBytes(StandardCharsets.UTF_8.name()));
>     }
>     try (InputStream response = connection.getInputStream()) {
>       String result = IOUtils.toString(response);
>       System.out.println(result);
>     }
> {code}
> Note: {{Apache HttpClient}} can be used as well.



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to