Signed-off-by: Eric Zhao <sczyh16@gmail.com>master
@@ -21,14 +21,27 @@ import java.lang.annotation.Retention; | |||
import java.lang.annotation.RetentionPolicy; | |||
import java.lang.annotation.Target; | |||
/** | |||
* @author lkxiaolou | |||
* @since 1.7.1 | |||
*/ | |||
@Retention(RetentionPolicy.RUNTIME) | |||
@Documented | |||
@Target({ElementType.METHOD}) | |||
public @interface AuthAction { | |||
/** | |||
* @return the privilege type | |||
*/ | |||
AuthService.PrivilegeType value(); | |||
/** | |||
* @return the target name to control | |||
*/ | |||
String targetName() default "app"; | |||
String message() default "No privilege"; | |||
/** | |||
* @return the message when permission is denied | |||
*/ | |||
String message() default "Permission denied"; | |||
} |
@@ -27,8 +27,14 @@ import javax.servlet.http.HttpServletResponse; | |||
import java.io.IOException; | |||
import java.lang.reflect.Method; | |||
/** | |||
* The web interceptor for privilege-based authorization. | |||
* | |||
* @author lkxiaolou | |||
* @since 1.7.1 | |||
*/ | |||
@Component | |||
public class AuthInterceptor implements HandlerInterceptor { | |||
public class AuthorizationInterceptor implements HandlerInterceptor { | |||
@Autowired | |||
private AuthService<HttpServletRequest> authService; |
@@ -13,9 +13,8 @@ | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
*/ | |||
package com.alibaba.csp.sentinel.dashboard.filter; | |||
package com.alibaba.csp.sentinel.dashboard.auth; | |||
import com.alibaba.csp.sentinel.dashboard.auth.AuthService; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.beans.factory.annotation.Value; | |||
@@ -30,39 +29,46 @@ import javax.servlet.ServletRequest; | |||
import javax.servlet.ServletResponse; | |||
import javax.servlet.http.HttpServletRequest; | |||
import javax.servlet.http.HttpServletResponse; | |||
import java.io.IOException; | |||
import java.util.List; | |||
/** | |||
* Servlet Filter that authenticate requests. | |||
* | |||
* Note: | |||
* Some urls are excluded as they needn't auth, such as: | |||
* <p>The Servlet filter for authentication.</p> | |||
* | |||
* Index url: / | |||
* Authentication request url: /login,logout | |||
* Used for client: /registry/machine | |||
* Static resources: htm,html,js and so on. | |||
* <p>Note: some urls are excluded as they needn't auth, such as:</p> | |||
* <ul> | |||
* <li>index url: {@code /}</li> | |||
* <li>authentication request url: {@code /login}, {@code /logout}</li> | |||
* <li>machine registry: {@code /registry/machine}</li> | |||
* <li>static resources</li> | |||
* </ul> | |||
* | |||
* The excluded urls and urlSuffixes are configured in application.properties | |||
* The excluded urls and urlSuffixes could be configured in {@code application.properties} file. | |||
* | |||
* @author cdfive | |||
* @since 1.6.0 | |||
*/ | |||
@Component | |||
public class AuthFilter implements Filter { | |||
public class LoginAuthenticationFilter implements Filter { | |||
private static final String URL_SUFFIX_DOT = "."; | |||
/**Some urls which needn't auth, such as /auth/login,/registry/machine and so on*/ | |||
/** | |||
* Some urls which needn't auth, such as /auth/login, /registry/machine and so on. | |||
*/ | |||
@Value("#{'${auth.filter.exclude-urls}'.split(',')}") | |||
private List<String> authFilterExcludeUrls; | |||
/**Some urls with suffixes which needn't auth, such as htm,html,js and so on*/ | |||
/** | |||
* Some urls with suffixes which needn't auth, such as htm, html, js and so on. | |||
*/ | |||
@Value("#{'${auth.filter.exclude-url-suffixes}'.split(',')}") | |||
private List<String> authFilterExcludeUrlSuffixes; | |||
/**Authentication using AuthService interface*/ | |||
/** | |||
* Authentication using AuthService interface. | |||
*/ | |||
@Autowired | |||
private AuthService<HttpServletRequest> authService; | |||
@@ -72,7 +78,8 @@ public class AuthFilter implements Filter { | |||
} | |||
@Override | |||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { | |||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) | |||
throws IOException, ServletException { | |||
HttpServletRequest httpRequest = (HttpServletRequest) request; | |||
String servletPath = httpRequest.getServletPath(); |
@@ -16,8 +16,11 @@ | |||
package com.alibaba.csp.sentinel.dashboard.config; | |||
import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter; | |||
import com.alibaba.csp.sentinel.dashboard.auth.AuthInterceptor; | |||
import com.alibaba.csp.sentinel.dashboard.filter.AuthFilter; | |||
import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager; | |||
import com.alibaba.csp.sentinel.dashboard.auth.AuthorizationInterceptor; | |||
import com.alibaba.csp.sentinel.dashboard.auth.LoginAuthenticationFilter; | |||
import com.alibaba.csp.sentinel.util.StringUtil; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
@@ -29,6 +32,7 @@ import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry | |||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; | |||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | |||
import javax.annotation.PostConstruct; | |||
import javax.servlet.Filter; | |||
/** | |||
@@ -40,14 +44,14 @@ public class WebConfig implements WebMvcConfigurer { | |||
private final Logger logger = LoggerFactory.getLogger(WebConfig.class); | |||
@Autowired | |||
private AuthFilter authFilter; | |||
private LoginAuthenticationFilter loginAuthenticationFilter; | |||
@Autowired | |||
private AuthInterceptor authInterceptor; | |||
private AuthorizationInterceptor authorizationInterceptor; | |||
@Override | |||
public void addInterceptors(InterceptorRegistry registry) { | |||
registry.addInterceptor(authInterceptor).addPathPatterns("/**"); | |||
registry.addInterceptor(authorizationInterceptor).addPathPatterns("/**"); | |||
} | |||
@Override | |||
@@ -77,10 +81,24 @@ public class WebConfig implements WebMvcConfigurer { | |||
return registration; | |||
} | |||
@PostConstruct | |||
public void doInit() { | |||
// Example: register a UrlCleaner to exclude URLs of common static resources. | |||
WebCallbackManager.setUrlCleaner(url -> { | |||
if (StringUtil.isEmpty(url)) { | |||
return url; | |||
} | |||
if (url.endsWith(".js") || url.endsWith(".css") || url.endsWith("html")) { | |||
return null; | |||
} | |||
return url; | |||
}); | |||
} | |||
@Bean | |||
public FilterRegistrationBean authenticationFilterRegistration() { | |||
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>(); | |||
registration.setFilter(authFilter); | |||
registration.setFilter(loginAuthenticationFilter); | |||
registration.addUrlPatterns("/*"); | |||
registration.setName("authenticationFilter"); | |||
registration.setOrder(0); | |||
@@ -15,7 +15,7 @@ | |||
*/ | |||
package com.alibaba.csp.sentinel.dashboard.controller.gateway; | |||
import com.alibaba.csp.sentinel.dashboard.auth.AuthInterceptor; | |||
import com.alibaba.csp.sentinel.dashboard.auth.AuthorizationInterceptor; | |||
import com.alibaba.csp.sentinel.dashboard.auth.FakeAuthServiceImpl; | |||
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient; | |||
import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.ApiDefinitionEntity; | |||
@@ -61,7 +61,7 @@ import static org.mockito.BDDMockito.*; | |||
*/ | |||
@RunWith(SpringRunner.class) | |||
@WebMvcTest(GatewayApiController.class) | |||
@Import({FakeAuthServiceImpl.class, InMemApiDefinitionStore.class, AppManagement.class, SimpleMachineDiscovery.class, AuthInterceptor.class}) | |||
@Import({FakeAuthServiceImpl.class, InMemApiDefinitionStore.class, AppManagement.class, SimpleMachineDiscovery.class, AuthorizationInterceptor.class}) | |||
public class GatewayApiControllerTest { | |||
private static final String TEST_APP = "test_app"; | |||
@@ -15,7 +15,7 @@ | |||
*/ | |||
package com.alibaba.csp.sentinel.dashboard.controller.gateway; | |||
import com.alibaba.csp.sentinel.dashboard.auth.AuthInterceptor; | |||
import com.alibaba.csp.sentinel.dashboard.auth.AuthorizationInterceptor; | |||
import com.alibaba.csp.sentinel.dashboard.auth.FakeAuthServiceImpl; | |||
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient; | |||
import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayFlowRuleEntity; | |||
@@ -65,7 +65,7 @@ import static org.mockito.BDDMockito.*; | |||
@RunWith(SpringRunner.class) | |||
@WebMvcTest(GatewayFlowRuleController.class) | |||
@Import({FakeAuthServiceImpl.class, InMemGatewayFlowRuleStore.class, AppManagement.class, SimpleMachineDiscovery.class, | |||
AuthInterceptor.class }) | |||
AuthorizationInterceptor.class }) | |||
public class GatewayFlowRuleControllerTest { | |||
private static final String TEST_APP = "test_app"; | |||