dashboard: Add interface of authentication/authorization and provide a default stub implementation (#503)

Signed-off-by: Carpenter Lee <hooleeucas@163.com>
This commit is contained in:
Carpenter Lee 2019-03-14 10:03:03 +08:00 committed by Eric Zhao
parent 4b1ccd93e2
commit 3c52bbc3c8
9 changed files with 375 additions and 30 deletions

View File

@ -15,12 +15,24 @@
*/
package com.alibaba.csp.sentinel.dashboard.config;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter;
import com.alibaba.csp.sentinel.dashboard.service.AuthService;
import com.alibaba.csp.sentinel.dashboard.service.AuthService.AuthUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -35,6 +47,8 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
public class WebConfig implements WebMvcConfigurer {
private final Logger logger = LoggerFactory.getLogger(WebConfig.class);
@Autowired
private AuthService<HttpServletRequest> authService;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
@ -62,4 +76,36 @@ public class WebConfig implements WebMvcConfigurer {
return registration;
}
@Bean
public FilterRegistrationBean authenticationFilterRegistration() {
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
registration.setFilter(new Filter() {
@Override
public void init(FilterConfig filterConfig) throws ServletException { }
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)servletRequest;
AuthUser authUser = authService.getAuthUser(request);
// authentication fail
if (authUser == null) {
PrintWriter writer = servletResponse.getWriter();
writer.append("login needed");
writer.flush();
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
}
@Override
public void destroy() { }
});
registration.addUrlPatterns("/*");
registration.setName("authenticationFilter");
registration.setOrder(0);
return registration;
}
}

View File

@ -18,14 +18,20 @@ package com.alibaba.csp.sentinel.dashboard.controller;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
import com.alibaba.csp.sentinel.dashboard.service.AuthService;
import com.alibaba.csp.sentinel.dashboard.service.AuthService.AuthUser;
import com.alibaba.csp.sentinel.dashboard.service.AuthService.PrivilegeType;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.AuthorityRuleEntity;
import com.alibaba.csp.sentinel.dashboard.domain.Result;
import com.alibaba.csp.sentinel.dashboard.repository.rule.RuleRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -54,10 +60,16 @@ public class AuthorityRuleController {
@Autowired
private RuleRepository<AuthorityRuleEntity, Long> repository;
@Autowired
private AuthService<HttpServletRequest> authService;
@GetMapping("/rules")
public Result<List<AuthorityRuleEntity>> apiQueryAllRulesForMachine(@RequestParam String app,
public Result<List<AuthorityRuleEntity>> apiQueryAllRulesForMachine(HttpServletRequest request,
@RequestParam String app,
@RequestParam String ip,
@RequestParam Integer port) {
AuthUser authUser = authService.getAuthUser(request);
authUser.authTarget(app, PrivilegeType.READ_RULE);
if (StringUtil.isEmpty(app)) {
return Result.ofFail(-1, "app cannot be null or empty");
}
@ -107,7 +119,10 @@ public class AuthorityRuleController {
}
@PostMapping("/rule")
public Result<AuthorityRuleEntity> apiAddAuthorityRule(@RequestBody AuthorityRuleEntity entity) {
public Result<AuthorityRuleEntity> apiAddAuthorityRule(HttpServletRequest request,
@RequestBody AuthorityRuleEntity entity) {
AuthUser authUser = authService.getAuthUser(request);
authUser.authTarget(entity.getApp(), PrivilegeType.WRITE_RULE);
Result<AuthorityRuleEntity> checkResult = checkEntityInternal(entity);
if (checkResult != null) {
return checkResult;
@ -129,8 +144,11 @@ public class AuthorityRuleController {
}
@PutMapping("/rule/{id}")
public Result<AuthorityRuleEntity> apiUpdateParamFlowRule(@PathVariable("id") Long id,
public Result<AuthorityRuleEntity> apiUpdateParamFlowRule(HttpServletRequest request,
@PathVariable("id") Long id,
@RequestBody AuthorityRuleEntity entity) {
AuthUser authUser = authService.getAuthUser(request);
authUser.authTarget(entity.getApp(), PrivilegeType.WRITE_RULE);
if (id == null || id <= 0) {
return Result.ofFail(-1, "Invalid id");
}
@ -158,7 +176,8 @@ public class AuthorityRuleController {
}
@DeleteMapping("/rule/{id}")
public Result<Long> apiDeleteRule(@PathVariable("id") Long id) {
public Result<Long> apiDeleteRule(HttpServletRequest request, @PathVariable("id") Long id) {
AuthUser authUser = authService.getAuthUser(request);
if (id == null) {
return Result.ofFail(-1, "id cannot be null");
}
@ -166,6 +185,7 @@ public class AuthorityRuleController {
if (oldEntity == null) {
return Result.ofSuccess(null);
}
authUser.authTarget(oldEntity.getApp(), PrivilegeType.DELETE_RULE);
try {
repository.delete(id);
} catch (Exception e) {

View File

@ -18,14 +18,20 @@ package com.alibaba.csp.sentinel.dashboard.controller;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
import com.alibaba.csp.sentinel.dashboard.service.AuthService;
import com.alibaba.csp.sentinel.dashboard.service.AuthService.AuthUser;
import com.alibaba.csp.sentinel.dashboard.service.AuthService.PrivilegeType;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.DegradeRuleEntity;
import com.alibaba.csp.sentinel.dashboard.domain.Result;
import com.alibaba.csp.sentinel.dashboard.repository.rule.InMemDegradeRuleStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -48,9 +54,15 @@ public class DegradeController {
@Autowired
private SentinelApiClient sentinelApiClient;
@Autowired
private AuthService<HttpServletRequest> authService;
@ResponseBody
@RequestMapping("/rules.json")
public Result<List<DegradeRuleEntity>> queryMachineRules(String app, String ip, Integer port) {
public Result<List<DegradeRuleEntity>> queryMachineRules(HttpServletRequest request, String app, String ip, Integer port) {
AuthUser authUser = authService.getAuthUser(request);
authUser.authTarget(app, PrivilegeType.READ_RULE);
if (StringUtil.isEmpty(app)) {
return Result.ofFail(-1, "app can't be null or empty");
}
@ -72,8 +84,12 @@ public class DegradeController {
@ResponseBody
@RequestMapping("/new.json")
public Result<DegradeRuleEntity> add(String app, String ip, Integer port, String limitApp, String resource,
Double count, Integer timeWindow, Integer grade) {
public Result<DegradeRuleEntity> add(HttpServletRequest request,
String app, String ip, Integer port, String limitApp, String resource,
Double count, Integer timeWindow, Integer grade) {
AuthUser authUser = authService.getAuthUser(request);
authUser.authTarget(app, PrivilegeType.WRITE_RULE);
if (StringUtil.isBlank(app)) {
return Result.ofFail(-1, "app can't be null or empty");
}
@ -127,8 +143,10 @@ public class DegradeController {
@ResponseBody
@RequestMapping("/save.json")
public Result<DegradeRuleEntity> updateIfNotNull(Long id, String app, String limitApp, String resource,
Double count, Integer timeWindow, Integer grade) {
public Result<DegradeRuleEntity> updateIfNotNull(HttpServletRequest request,
Long id, String app, String limitApp, String resource,
Double count, Integer timeWindow, Integer grade) {
AuthUser authUser = authService.getAuthUser(request);
if (id == null) {
return Result.ofFail(-1, "id can't be null");
}
@ -141,6 +159,7 @@ public class DegradeController {
if (entity == null) {
return Result.ofFail(-1, "id " + id + " dose not exist");
}
authUser.authTarget(entity.getApp(), PrivilegeType.WRITE_RULE);
if (StringUtil.isNotBlank(app)) {
entity.setApp(app.trim());
}
@ -176,7 +195,8 @@ public class DegradeController {
@ResponseBody
@RequestMapping("/delete.json")
public Result<Long> delete(Long id) {
public Result<Long> delete(HttpServletRequest request, Long id) {
AuthUser authUser = authService.getAuthUser(request);
if (id == null) {
return Result.ofFail(-1, "id can't be null");
}
@ -185,6 +205,7 @@ public class DegradeController {
if (oldEntity == null) {
return Result.ofSuccess(null);
}
authUser.authTarget(oldEntity.getApp(), PrivilegeType.DELETE_RULE);
try {
repository.delete(id);
} catch (Throwable throwable) {

View File

@ -18,6 +18,11 @@ package com.alibaba.csp.sentinel.dashboard.controller;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.csp.sentinel.dashboard.service.AuthService;
import com.alibaba.csp.sentinel.dashboard.service.AuthService.AuthUser;
import com.alibaba.csp.sentinel.dashboard.service.AuthService.PrivilegeType;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
@ -25,6 +30,7 @@ import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
import com.alibaba.csp.sentinel.dashboard.domain.Result;
import com.alibaba.csp.sentinel.dashboard.repository.rule.InMemoryRuleRepositoryAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -51,14 +57,20 @@ public class FlowControllerV1 {
@Autowired
private InMemoryRuleRepositoryAdapter<FlowRuleEntity> repository;
@Autowired
private AuthService<HttpServletRequest> authService;
@Autowired
private SentinelApiClient sentinelApiClient;
@GetMapping("/rules")
public Result<List<FlowRuleEntity>> apiQueryMachineRules(@RequestParam String app,
public Result<List<FlowRuleEntity>> apiQueryMachineRules(HttpServletRequest request,
@RequestParam String app,
@RequestParam String ip,
@RequestParam Integer port) {
AuthUser authUser = authService.getAuthUser(request);
authUser.authTarget(app, PrivilegeType.READ_RULE);
if (StringUtil.isEmpty(app)) {
return Result.ofFail(-1, "app can't be null or empty");
}
@ -126,7 +138,10 @@ public class FlowControllerV1 {
}
@PostMapping("/rule")
public Result<FlowRuleEntity> apiAddFlowRule(@RequestBody FlowRuleEntity entity) {
public Result<FlowRuleEntity> apiAddFlowRule(HttpServletRequest request, @RequestBody FlowRuleEntity entity) {
AuthUser authUser = authService.getAuthUser(request);
authUser.authTarget(entity.getApp(), PrivilegeType.WRITE_RULE);
Result<FlowRuleEntity> checkResult = checkEntityInternal(entity);
if (checkResult != null) {
return checkResult;
@ -150,10 +165,14 @@ public class FlowControllerV1 {
}
@PutMapping("/save.json")
public Result<FlowRuleEntity> updateIfNotNull(Long id, String app,
String limitApp, String resource, Integer grade,
Double count, Integer strategy, String refResource,
Integer controlBehavior, Integer warmUpPeriodSec, Integer maxQueueingTimeMs) {
public Result<FlowRuleEntity> updateIfNotNull(HttpServletRequest request, Long id, String app,
String limitApp, String resource, Integer grade,
Double count, Integer strategy, String refResource,
Integer controlBehavior, Integer warmUpPeriodSec,
Integer maxQueueingTimeMs) {
AuthUser authUser = authService.getAuthUser(request);
authUser.authTarget(app, PrivilegeType.WRITE_RULE);
if (id == null) {
return Result.ofFail(-1, "id can't be null");
}
@ -227,7 +246,8 @@ public class FlowControllerV1 {
}
@DeleteMapping("/delete.json")
public Result<Long> delete(Long id) {
public Result<Long> delete(HttpServletRequest request, Long id) {
AuthUser authUser = authService.getAuthUser(request);
if (id == null) {
return Result.ofFail(-1, "id can't be null");
}
@ -235,6 +255,7 @@ public class FlowControllerV1 {
if (oldEntity == null) {
return Result.ofSuccess(null);
}
authUser.authTarget(oldEntity.getApp(), PrivilegeType.DELETE_RULE);
try {
repository.delete(id);
} catch (Exception e) {

View File

@ -21,10 +21,15 @@ import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.csp.sentinel.dashboard.client.CommandNotFoundException;
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
import com.alibaba.csp.sentinel.dashboard.discovery.AppManagement;
import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
import com.alibaba.csp.sentinel.dashboard.service.AuthService;
import com.alibaba.csp.sentinel.dashboard.service.AuthService.AuthUser;
import com.alibaba.csp.sentinel.dashboard.service.AuthService.PrivilegeType;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.util.StringUtil;
@ -33,6 +38,7 @@ import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.ParamFlowRuleEn
import com.alibaba.csp.sentinel.dashboard.domain.Result;
import com.alibaba.csp.sentinel.dashboard.repository.rule.RuleRepository;
import com.alibaba.csp.sentinel.dashboard.util.VersionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -63,6 +69,9 @@ public class ParamFlowRuleController {
@Autowired
private RuleRepository<ParamFlowRuleEntity, Long> repository;
@Autowired
private AuthService<HttpServletRequest> authService;
private boolean checkIfSupported(String app, String ip, int port) {
try {
return Optional.ofNullable(appManagement.getDetailApp(app))
@ -77,9 +86,12 @@ public class ParamFlowRuleController {
}
@GetMapping("/rules")
public Result<List<ParamFlowRuleEntity>> apiQueryAllRulesForMachine(@RequestParam String app,
public Result<List<ParamFlowRuleEntity>> apiQueryAllRulesForMachine(HttpServletRequest request,
@RequestParam String app,
@RequestParam String ip,
@RequestParam Integer port) {
AuthUser authUser = authService.getAuthUser(request);
authUser.authTarget(app, PrivilegeType.READ_RULE);
if (StringUtil.isEmpty(app)) {
return Result.ofFail(-1, "app cannot be null or empty");
}
@ -115,7 +127,10 @@ public class ParamFlowRuleController {
}
@PostMapping("/rule")
public Result<ParamFlowRuleEntity> apiAddParamFlowRule(@RequestBody ParamFlowRuleEntity entity) {
public Result<ParamFlowRuleEntity> apiAddParamFlowRule(HttpServletRequest request,
@RequestBody ParamFlowRuleEntity entity) {
AuthUser authUser = authService.getAuthUser(request);
authUser.authTarget(entity.getApp(), PrivilegeType.WRITE_RULE);
Result<ParamFlowRuleEntity> checkResult = checkEntityInternal(entity);
if (checkResult != null) {
return checkResult;
@ -177,7 +192,10 @@ public class ParamFlowRuleController {
}
@PutMapping("/rule/{id}")
public Result<ParamFlowRuleEntity> apiUpdateParamFlowRule(@PathVariable("id") Long id, @RequestBody ParamFlowRuleEntity entity) {
public Result<ParamFlowRuleEntity> apiUpdateParamFlowRule(HttpServletRequest request,
@PathVariable("id") Long id,
@RequestBody ParamFlowRuleEntity entity) {
AuthUser authUser = authService.getAuthUser(request);
if (id == null || id <= 0) {
return Result.ofFail(-1, "Invalid id");
}
@ -185,6 +203,7 @@ public class ParamFlowRuleController {
if (oldEntity == null) {
return Result.ofFail(-1, "id " + id + " does not exist");
}
authUser.authTarget(oldEntity.getApp(), PrivilegeType.WRITE_RULE);
Result<ParamFlowRuleEntity> checkResult = checkEntityInternal(entity);
if (checkResult != null) {
return checkResult;
@ -214,7 +233,8 @@ public class ParamFlowRuleController {
}
@DeleteMapping("/rule/{id}")
public Result<Long> apiDeleteRule(@PathVariable("id") Long id) {
public Result<Long> apiDeleteRule(HttpServletRequest request, @PathVariable("id") Long id) {
AuthUser authUser = authService.getAuthUser(request);
if (id == null) {
return Result.ofFail(-1, "id cannot be null");
}
@ -222,6 +242,7 @@ public class ParamFlowRuleController {
if (oldEntity == null) {
return Result.ofSuccess(null);
}
authUser.authTarget(oldEntity.getApp(), PrivilegeType.DELETE_RULE);
try {
repository.delete(id);
publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort()).get();
@ -245,7 +266,8 @@ public class ParamFlowRuleController {
}
private <R> Result<R> unsupportedVersion() {
return Result.ofFail(4041, "Sentinel client not supported for parameter flow control (unsupported version or dependency absent)");
return Result.ofFail(4041,
"Sentinel client not supported for parameter flow control (unsupported version or dependency absent)");
}
private final SentinelVersion version020 = new SentinelVersion().setMinorVersion(2);

View File

@ -18,6 +18,11 @@ package com.alibaba.csp.sentinel.dashboard.controller;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.csp.sentinel.dashboard.service.AuthService;
import com.alibaba.csp.sentinel.dashboard.service.AuthService.AuthUser;
import com.alibaba.csp.sentinel.dashboard.service.AuthService.PrivilegeType;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.SystemRuleEntity;
@ -25,6 +30,7 @@ import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
import com.alibaba.csp.sentinel.dashboard.domain.Result;
import com.alibaba.csp.sentinel.dashboard.repository.rule.InMemSystemRuleStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -45,10 +51,14 @@ public class SystemController {
private InMemSystemRuleStore repository;
@Autowired
private SentinelApiClient sentinelApiClient;
@Autowired
private AuthService<HttpServletRequest> authService;
@ResponseBody
@RequestMapping("/rules.json")
Result<List<SystemRuleEntity>> queryMachineRules(String app, String ip, Integer port) {
Result<List<SystemRuleEntity>> queryMachineRules(HttpServletRequest request, String app, String ip, Integer port) {
AuthUser authUser = authService.getAuthUser(request);
authUser.authTarget(app, PrivilegeType.READ_RULE);
if (StringUtil.isEmpty(app)) {
return Result.ofFail(-1, "app can't be null or empty");
}
@ -80,7 +90,10 @@ public class SystemController {
@ResponseBody
@RequestMapping("/new.json")
Result<?> add(String app, String ip, Integer port, Double avgLoad, Long avgRt, Long maxThread, Double qps) {
Result<?> add(HttpServletRequest request,
String app, String ip, Integer port, Double avgLoad, Long avgRt, Long maxThread, Double qps) {
AuthUser authUser = authService.getAuthUser(request);
authUser.authTarget(app, PrivilegeType.WRITE_RULE);
if (StringUtil.isBlank(app)) {
return Result.ofFail(-1, "app can't be null or empty");
}
@ -137,7 +150,9 @@ public class SystemController {
@ResponseBody
@RequestMapping("/save.json")
Result<?> updateIfNotNull(Long id, String app, Double avgLoad, Long avgRt, Long maxThread, Double qps) {
Result<?> updateIfNotNull(HttpServletRequest request,
Long id, String app, Double avgLoad, Long avgRt, Long maxThread, Double qps) {
AuthUser authUser = authService.getAuthUser(request);
if (id == null) {
return Result.ofFail(-1, "id can't be null");
}
@ -145,6 +160,7 @@ public class SystemController {
if (entity == null) {
return Result.ofFail(-1, "id " + id + " dose not exist");
}
authUser.authTarget(entity.getApp(), PrivilegeType.WRITE_RULE);
if (StringUtil.isNotBlank(app)) {
entity.setApp(app.trim());
}
@ -188,7 +204,8 @@ public class SystemController {
@ResponseBody
@RequestMapping("/delete.json")
Result<?> delete(Long id) {
Result<?> delete(HttpServletRequest request, Long id) {
AuthUser authUser = authService.getAuthUser(request);
if (id == null) {
return Result.ofFail(-1, "id can't be null");
}
@ -196,6 +213,7 @@ public class SystemController {
if (oldEntity == null) {
return Result.ofSuccess(null);
}
authUser.authTarget(oldEntity.getApp(), PrivilegeType.DELETE_RULE);
try {
repository.delete(id);
} catch (Throwable throwable) {

View File

@ -18,6 +18,11 @@ package com.alibaba.csp.sentinel.dashboard.controller.v2;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.csp.sentinel.dashboard.service.AuthService;
import com.alibaba.csp.sentinel.dashboard.service.AuthService.AuthUser;
import com.alibaba.csp.sentinel.dashboard.service.AuthService.PrivilegeType;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
@ -25,6 +30,7 @@ import com.alibaba.csp.sentinel.dashboard.repository.rule.InMemoryRuleRepository
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.dashboard.domain.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -61,8 +67,14 @@ public class FlowControllerV2 {
@Qualifier("flowRuleDefaultPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;
@Autowired
private AuthService<HttpServletRequest> authService;
@GetMapping("/rules")
public Result<List<FlowRuleEntity>> apiQueryMachineRules(@RequestParam String app) {
public Result<List<FlowRuleEntity>> apiQueryMachineRules(HttpServletRequest request, @RequestParam String app) {
AuthUser authUser = authService.getAuthUser(request);
authUser.authTarget(app, PrivilegeType.READ_RULE);
if (StringUtil.isEmpty(app)) {
return Result.ofFail(-1, "app can't be null or empty");
}
@ -129,7 +141,10 @@ public class FlowControllerV2 {
}
@PostMapping("/rule")
public Result<FlowRuleEntity> apiAddFlowRule(@RequestBody FlowRuleEntity entity) {
public Result<FlowRuleEntity> apiAddFlowRule(HttpServletRequest request, @RequestBody FlowRuleEntity entity) {
AuthUser authUser = authService.getAuthUser(request);
authUser.authTarget(entity.getApp(), PrivilegeType.WRITE_RULE);
Result<FlowRuleEntity> checkResult = checkEntityInternal(entity);
if (checkResult != null) {
return checkResult;
@ -151,7 +166,10 @@ public class FlowControllerV2 {
}
@PutMapping("/rule/{id}")
public Result<FlowRuleEntity> apiUpdateFlowRule(@PathVariable("id") Long id, @RequestBody FlowRuleEntity entity) {
public Result<FlowRuleEntity> apiUpdateFlowRule(HttpServletRequest request,
@PathVariable("id") Long id,
@RequestBody FlowRuleEntity entity) {
AuthUser authUser = authService.getAuthUser(request);
if (id == null || id <= 0) {
return Result.ofFail(-1, "Invalid id");
}
@ -162,6 +180,8 @@ public class FlowControllerV2 {
if (entity == null) {
return Result.ofFail(-1, "invalid body");
}
authUser.authTarget(oldEntity.getApp(), PrivilegeType.WRITE_RULE);
entity.setApp(oldEntity.getApp());
entity.setIp(oldEntity.getIp());
entity.setPort(oldEntity.getPort());
@ -188,7 +208,8 @@ public class FlowControllerV2 {
}
@DeleteMapping("/rule/{id}")
public Result<Long> apiDeleteRule(@PathVariable("id") Long id) {
public Result<Long> apiDeleteRule(HttpServletRequest request, @PathVariable("id") Long id) {
AuthUser authUser = authService.getAuthUser(request);
if (id == null || id <= 0) {
return Result.ofFail(-1, "Invalid id");
}
@ -196,6 +217,7 @@ public class FlowControllerV2 {
if (oldEntity == null) {
return Result.ofSuccess(null);
}
authUser.authTarget(oldEntity.getApp(), PrivilegeType.DELETE_RULE);
try {
repository.delete(id);
publishRules(oldEntity.getApp());

View File

@ -0,0 +1,111 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.csp.sentinel.dashboard.service;
/**
* Interface about authentication and authorization
*
* @author Carpenter Lee
*/
public interface AuthService<R> {
/**
* Get the authentication user.
*
* @param request the request contains the user information
* @return the auth user represent the current user, when the user is illegal, a null value will return.
*/
AuthUser getAuthUser(R request);
/**
* privilege type.
*/
enum PrivilegeType {
/**
* read rule
*/
READ_RULE,
/**
* create or modify rule
*/
WRITE_RULE,
/**
* delete rule
*/
DELETE_RULE,
/**
* read metrics
*/
READ_METRIC,
/**
* add machine
*/
ADD_MACHINE,
/**
* equals all privileges above
*/
ALL
}
/**
* entity represents the current user
*/
interface AuthUser {
/**
* query whether current user has the specific privilege to the target, the target
* may be an app name or an ip address, or other destination.
* <p>
* This method will use return value to represent whether user has the specific
* privileges to the target, but to throw a RuntimeException to represent no auth
* is also a good way.
* </p>
*
* @param target the target to check
* @param privilegeType the privilege type to check
* @return if current user has the specific privileges to the target, return true,
* otherwise return false.
*/
boolean authTarget(String target, PrivilegeType privilegeType);
/**
* check whether current user is super user
*
* @return if current user is super user return true, else return false.
*/
boolean isSuperUser();
/**
* get current user's nick name.
*
* @return current user's nick name.
*/
String getNickName();
/**
* get current user's login name.
*
* @return current user's login name.
*/
String getLoginName();
/**
* get current user's employ id.
*
* @return current user's employ id.
*/
String getEmpId();
}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.csp.sentinel.dashboard.service;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;
/**
* A fake AuthService implementation, which will pass all user auth checking.
*
* @author Carpenter Lee
*/
@Component
public class FakeAuthServiceImpl implements AuthService<HttpServletRequest> {
@Override
public AuthUser getAuthUser(HttpServletRequest request) {
return new AuthUserImpl();
}
static final class AuthUserImpl implements AuthUser {
@Override
public boolean authTarget(String target, PrivilegeType privilegeType) {
// fake implementation, always return true
return true;
}
@Override
public boolean isSuperUser() {
// fake implementation, always return true
return true;
}
@Override
public String getNickName() {
return "FAKE_NICK_NAME";
}
@Override
public String getLoginName() {
return "FAKE_LOGIN_NAME";
}
@Override
public String getEmpId() {
return "FAKE_EMP_ID";
}
}
}