一个项目的使用权限我们在前端做了一定限制,限制了用户可以看到的菜单栏;但是在后端并没有做太多限制,用户可以调所有接口,不管能不能看见这个界面。所以我们要在后端对用户拥有的界面权限做接口限制。
这个注解可以作用于类上:对于该controller里的所有接口都做统一权限判断;作用于接口上:对该接口单独做判断。
对于不需要做验证的接口可以使用ignore忽视。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MenuAuth {String value() default "";boolean ignore() default false;
}
value:菜单名称,用菜单名称做权限校验,获取用户拥有的菜单列表,判断是否包含这个接口的注解value值,从而判断用户是否可以调用此接口。
ignore:是否忽略注解,若忽略则无需判断。
重点在这里:
import cn.chinatelecom.dxsc.park.authorization.properties.AuthConfigProperties;
import cn.chinatelecom.dxsc.park.authorization.remote.LoginUserClientFeign;
import cn.chinatelecom.dxsc.park.entity.R;
import cn.chinatelecom.dxsc.park.entity.center.MenuTree;
import cn.chinatelecom.dxsc.park.entity.model.LoginHelper;
import cn.chinatelecom.park.schedule.common.annotation.MenuAuth;
import com.alibaba.spring.web.servlet.handler.AnnotatedHandlerMethodHandlerInterceptorAdapter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.method.HandlerMethod;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashSet;
import java.util.List;
import java.util.Set;@Component
public class MenuAuthVerifyInterceptor extends AnnotatedHandlerMethodHandlerInterceptorAdapter<MenuAuth> {@Autowiredprivate LoginUserClientFeign loginUserClientFeign;@Autowiredprivate AuthConfigProperties authConfigProperties;@Overrideprotected boolean preHandle(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod, MenuAuth menuAuth) throws Exception {if (StringUtils.isBlank(request.getHeader("Authorization")))return true;if (menuAuth.ignore())return true;R<List<MenuTree>> userMenus = loginUserClientFeign.getUserMenus(LoginHelper.getLoginUser().getToken(), this.authConfigProperties.getClientId(), true);List<MenuTree> menuTrees = userMenus.getData();Set<String> menuNameSet = new HashSet<>();if (!CollectionUtils.isEmpty(menuTrees)) {menuTrees.forEach(menuTree -> addMenus(menuNameSet, menuTree));}//获取注解属性String menuName = menuAuth.value();if (!menuNameSet.contains(menuName)) {throw new Exception("用户无对应权限");}return true;}private void addMenus(Set<String> menuName, MenuTree menuTree) {menuName.add(menuTree.getName());if (!CollectionUtils.isEmpty(menuTree.getChildren())) {menuTree.getChildren().forEach(m -> {addMenus(menuName, m);});}}
}
在使用用户中心bean时,应该注意注入顺序,拦截器应该在用户中心后面,以免使用不了用户中心接口,获取不到用户的菜单列表。
首先,要验证是否携带token,该接口是否选择忽视。然后获取该token所拥有的菜单列表,获取注解value,判断菜单列表是否包含注解value。
然后拦截器主要注入(拦截顺序在用户中心后面):
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class MenuAuthVerifyInterceptorConfig implements WebMvcConfigurer {@AutowiredMenuAuthVerifyInterceptor menuAuthVerifyInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(menuAuthVerifyInterceptor).order(1);}
}
添加注解:
<dependency><groupId>com.alibaba.spring</groupId><artifactId>spring-webmvc-support</artifactId><version>1.0.1</version></dependency>
如何使用:

该controller中的所有接口都会在“班次管理”这个菜单中,所以可以做统一鉴权。若其中的接口无需鉴权,则在其中的接口上单独添加@MenuAuth(ignore = true)即可。
简易的鉴权就做好了。
一个集坚强与自信于一身的菇凉。