From 2d38bd95f4b598949efc7c1c2a2d2a5b558ff767 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8D=A3=E7=87=8A?= <757230079@qq.com> Date: Wed, 8 Sep 2021 12:45:17 +0800 Subject: [PATCH] For #756 --- .../InterceptorAuthentication.java | 34 +++++++++++ .../authentication/impl/DefaultPreHandle.java | 58 +++++++++++++++++++ .../admin/interceptor/AuthInterceptor.java | 51 ++++++---------- ...n.authentication.InterceptorAuthentication | 1 + 4 files changed, 111 insertions(+), 33 deletions(-) create mode 100644 dubbo-admin-server/src/main/java/org/apache/dubbo/admin/authentication/InterceptorAuthentication.java create mode 100644 dubbo-admin-server/src/main/java/org/apache/dubbo/admin/authentication/impl/DefaultPreHandle.java create mode 100644 dubbo-admin-server/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.admin.authentication.InterceptorAuthentication diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/authentication/InterceptorAuthentication.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/authentication/InterceptorAuthentication.java new file mode 100644 index 000000000..bb468c074 --- /dev/null +++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/authentication/InterceptorAuthentication.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dubbo.admin.authentication; + +import org.apache.dubbo.common.extension.SPI; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Permission interception validation + * + */ +@SPI +public interface InterceptorAuthentication { + + boolean authentication(HttpServletRequest request, HttpServletResponse response, Object handler); + +} diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/authentication/impl/DefaultPreHandle.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/authentication/impl/DefaultPreHandle.java new file mode 100644 index 000000000..bb05c8e41 --- /dev/null +++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/authentication/impl/DefaultPreHandle.java @@ -0,0 +1,58 @@ +package org.apache.dubbo.admin.authentication.impl; + +import org.apache.dubbo.admin.annotation.Authority; +import org.apache.dubbo.admin.authentication.InterceptorAuthentication; +import org.apache.dubbo.admin.controller.UserController; +import org.apache.dubbo.admin.interceptor.AuthInterceptor; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.util.StringUtils; +import org.springframework.web.method.HandlerMethod; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.lang.reflect.Method; + + +public class DefaultPreHandle implements InterceptorAuthentication { + //make session timeout configurable + //default to be an hour:1000 * 60 * 60 + @Value("${admin.check.sessionTimeoutMilli:3600000}") + private long sessionTimeoutMilli; + + private AuthInterceptor authInterceptor = new AuthInterceptor(); + + @Override + public boolean authentication(HttpServletRequest request, HttpServletResponse response, Object handler) { + HandlerMethod handlerMethod = (HandlerMethod) handler; + Method method = handlerMethod.getMethod(); + Authority authority = method.getDeclaredAnnotation(Authority.class); + if (null == authority) { + authority = method.getDeclaringClass().getDeclaredAnnotation(Authority.class); + } + + String authorization = request.getHeader("Authorization"); + if (null != authority && authority.needLogin()) { + //check if 'authorization' is empty to prevent NullPointException + //since UserController.tokenMap is an instance of ConcurrentHashMap. + if (StringUtils.isEmpty(authorization)) { + //While authentication is required and 'Authorization' string is missing in the request headers, + //reject this request(http403). + authInterceptor.rejectedResponse(response); + return false; + } + + UserController.User user = UserController.tokenMap.get(authorization); + if (null != user && System.currentTimeMillis() - user.getLastUpdateTime() <= sessionTimeoutMilli) { + user.setLastUpdateTime(System.currentTimeMillis()); + return true; + } + + //while user not found, or session timeout, reject this request(http403). + authInterceptor.rejectedResponse(response); + return false; + } else { + return true; + } + } +} diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/interceptor/AuthInterceptor.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/interceptor/AuthInterceptor.java index ecc6e57f7..6c218819f 100644 --- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/interceptor/AuthInterceptor.java +++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/interceptor/AuthInterceptor.java @@ -16,20 +16,22 @@ */ package org.apache.dubbo.admin.interceptor; -import org.apache.dubbo.admin.annotation.Authority; -import org.apache.dubbo.admin.controller.UserController; +import org.apache.dubbo.admin.authentication.InterceptorAuthentication; +import org.apache.dubbo.admin.authentication.LoginAuthentication; + +import org.apache.dubbo.common.extension.ExtensionLoader; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.validation.constraints.NotNull; -import java.lang.reflect.Method; +import java.util.Iterator; +import java.util.Set; @Component public class AuthInterceptor extends HandlerInterceptorAdapter { @@ -45,39 +47,22 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons if (!(handler instanceof HandlerMethod) || !checkAuthority) { return true; } - HandlerMethod handlerMethod = (HandlerMethod) handler; - Method method = handlerMethod.getMethod(); - Authority authority = method.getDeclaredAnnotation(Authority.class); - if (null == authority) { - authority = method.getDeclaringClass().getDeclaredAnnotation(Authority.class); - } - - String authorization = request.getHeader("Authorization"); - if (null != authority && authority.needLogin()) { - //check if 'authorization' is empty to prevent NullPointException - //since UserController.tokenMap is an instance of ConcurrentHashMap. - if (StringUtils.isEmpty(authorization)) { - //While authentication is required and 'Authorization' string is missing in the request headers, - //reject this request(http403). - rejectedResponse(response); - return false; + ExtensionLoader extensionLoader = ExtensionLoader.getExtensionLoader(InterceptorAuthentication.class); + Set supportedExtensionInstances = extensionLoader.getSupportedExtensionInstances(); + Iterator iterator = supportedExtensionInstances.iterator(); + boolean flag = true; + while (iterator.hasNext()) { + InterceptorAuthentication interceptorAuthentication = iterator.next(); + boolean b = interceptorAuthentication.authentication(request, response, handler); + flag = b & flag; + if (flag == false) { + break; } - - UserController.User user = UserController.tokenMap.get(authorization); - if (null != user && System.currentTimeMillis() - user.getLastUpdateTime() <= sessionTimeoutMilli) { - user.setLastUpdateTime(System.currentTimeMillis()); - return true; - } - - //while user not found, or session timeout, reject this request(http403). - rejectedResponse(response); - return false; - } else { - return true; } + return flag; } - private static void rejectedResponse(@NotNull HttpServletResponse response) { + public static void rejectedResponse(@NotNull HttpServletResponse response) { response.setStatus(HttpStatus.UNAUTHORIZED.value()); } } diff --git a/dubbo-admin-server/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.admin.authentication.InterceptorAuthentication b/dubbo-admin-server/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.admin.authentication.InterceptorAuthentication new file mode 100644 index 000000000..ef91a43cd --- /dev/null +++ b/dubbo-admin-server/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.admin.authentication.InterceptorAuthentication @@ -0,0 +1 @@ +defaultHandle=org.apache.dubbo.admin.authentication.impl.DefaultPreHandle \ No newline at end of file