jerryshao commented on code in PR #13057:
URL: https://github.com/apache/gravitino/pull/13057#discussion_r4002079208
##########
server-common/src/main/java/org/apache/gravitino/server/authentication/AuthenticationFilter.java:
##########
@@ -207,4 +182,88 @@ protected boolean isHealthCheckRequest(ServletRequest
request) {
@Override
public void destroy() {}
+
+ private Principal authenticate(HttpServletRequest request) {
+ return applyActiveRoles(request, resolvePrincipal(request));
+ }
+
+ private Principal resolvePrincipal(HttpServletRequest request) {
+ byte[] authData = authorizationData(request);
+ Principal principal = null;
+ // If token is supported by multiple authenticators, use the first by
default.
+ for (Authenticator authenticator : authenticators()) {
+ if (authenticator.supportsToken(authData) &&
authenticator.isDataFromToken()) {
+ principal = authenticator.authenticateToken(authData);
+ if (principal != null) {
+ break;
+ }
+ }
+ }
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(
+ "uri={} hasAuthHeader={} principal={}",
+ request.getRequestURI(),
+ authData != null,
+ principal == null ? "null" : principal.getName());
+ }
+ if (principal == null) {
+ throw new UnauthorizedException("The provided credentials did not
support");
+ }
+ return principal;
+ }
+
+ private List<Authenticator> authenticators() {
+ if (filterAuthenticators == null || filterAuthenticators.isEmpty()) {
+ return ServerAuthenticator.getInstance().authenticators();
+ }
+ return filterAuthenticators;
+ }
+
+ private static byte[] authorizationData(HttpServletRequest request) {
+ Enumeration<String> headerData =
request.getHeaders(AuthConstants.HTTP_HEADER_AUTHORIZATION);
+ return headerData.hasMoreElements()
+ ? headerData.nextElement().getBytes(StandardCharsets.UTF_8)
+ : null;
+ }
+
+ // Role assumption: parse the header (syntactic only; malformed -> 400) and,
only when narrowed,
+ // attach the roles to the principal. Membership 403 is checked later.
+ private static Principal applyActiveRoles(HttpServletRequest request,
Principal principal) {
+ ActiveRoles activeRoles =
+
ActiveRolesParser.parse(request.getHeader(AuthConstants.X_GRAVITINO_ACTIVE_ROLES_HEADER));
+ if (!activeRoles.isAll() && principal instanceof UserPrincipal) {
+ return ((UserPrincipal) principal).withActiveRoles(activeRoles);
+ }
+ return principal;
+ }
+
+ private static void runAsPrincipal(
+ Principal principal,
+ HttpServletRequest request,
+ HttpServletResponse response,
+ FilterChain chain)
+ throws Exception {
+ // Publish the finalized principal (already carrying any narrowed roles)
so downstream
+ // re-binds from the attribute (e.g. Utils.doAs) see the same identity and
roles.
+ request.setAttribute(AuthConstants.AUTHENTICATED_PRINCIPAL_ATTRIBUTE_NAME,
principal);
+ PrincipalUtils.doAs(
+ principal,
+ () -> {
+ chain.doFilter(request, response);
+ return null;
+ });
+ }
+
+ private void sendUnauthorizedResponse(HttpServletResponse response,
UnauthorizedException ue)
+ throws IOException {
+ // For some authentication, HTTP response can provide some challenge
information
+ // to let client to create correct authenticated request.
+ // Refer to
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/WWW-Authenticate
+ for (String challenge : ue.getChallenges()) {
+ if (!challenge.toLowerCase().startsWith("basic")) {
+ response.setHeader(AuthConstants.HTTP_CHALLENGE_HEADER, challenge);
+ }
+ }
+ sendAuthErrorResponse(response, ue);
+ }
Review Comment:
@roryqi can you please review this part?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]