[ https://issues.apache.org/jira/browse/DRILL-5726?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16143983#comment-16143983 ]
ASF GitHub Bot commented on DRILL-5726: --------------------------------------- Github user arina-ielchiieva commented on a diff in the pull request: https://github.com/apache/drill/pull/910#discussion_r135571777 --- Diff: exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRestServer.java --- @@ -230,6 +230,27 @@ public WebUserConnection provide() { public void dispose(WebUserConnection instance) { } + + /** + * Creates session user principal. If impersonation is enabled without authentication and User-Name header is present and valid, + * will create session user principal with provided user name, otherwise anonymous user name will be used. + * In both cases session user principal will have admin rights. + * + * @param config drill config + * @param request client request + * @return session user principal + */ + private Principal createSessionUserPrincipal(DrillConfig config, HttpServletRequest request) { + final boolean checkForUserName = !config.getBoolean(ExecConstants.USER_AUTHENTICATION_ENABLED) && config.getBoolean(ExecConstants.IMPERSONATION_ENABLED); + if (checkForUserName) { --- End diff -- We should not require `User-Name` for each request since it is needed only when we need to query the data. I will leave this method but also add `UserNameFilter` that would be applied to all `/query` and `/query.json` requests and check if header is provided, i.e. we would allow using `anonymous` user if `User-Name` is not provided since we'll know that `UserNameFilter` will filter out request where `User-Name` is required but not set. > 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)