spring - 如何限制对 Spring MVC 控制器的访问
问题描述
我正在编写带有授权和注册表单的 Web 服务。有两种类型的用户:普通用户和管理员。有一个控制器发送到给定 URL 的管理页面:
@Controller
public class ViewPageController {
@RequestMapping(value = "/admin", method = RequestMethod.GET)
public String sendAdminPage(){
return "AdminPage";
}
}
但是普通用户也可以访问这个页面。只有那些以管理员身份登录的人才能进入管理页面。有如何组织这方面的选择?也许将登录用户保存在会话中?(最好没有 Spring Security)
解决方案
定义一个方面和一个注释的简单方法。像这样的一些代码
@Inherited
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Authorize {
//
String[] value() default {};
}
授权方面.java
@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class AuthorizationAspect {
private final AuthorizationService authorizationService;
private final CacheUtil cacheUtil;
private static final String PRE = "AUTH";
@Before("@annotation(com.jin.learn.config.security.Authorize)")
public void checkPermission(JoinPoint joinPoint) {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
Long accountId = JWTUtil.getUserIdFromRequest(request);
Set<String> authorization = cacheUtil.getAllSet(PRE + accountId);
if(authorization==null){
authorization = authorizationService.findByAccountId(accountId);
cacheUtil.save(PRE + accountId, authorization);
}
Authorize authorize = ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(Authorize.class);
String[] needAuthorization = authorize.value();
if (needAuthorization.length == 0) return;
if (authorization!=null && !authorization.isEmpty()) {
if (!authorization.containsAll(Arrays.asList(needAuthorization))){
throw new SystemException(ExceptionCode.NO_PERMISSION);
}
} else {
throw new SystemException(ExceptionCode.NO_PERMISSION);
}
}
}
像这样使用
@Authorize(value="needRight")
@RequestMapping(value = "/admin", method = RequestMethod.GET)
public String sendAdminPage(){
return "AdminPage";
}
此外,还有一些安全框架shiro和spring-security
推荐阅读
- python - 以格式化字符串打印一维数组的所有元素
- excel - 将word文档问卷中的数据抓取到Excel中
- android - 在Android中将两个按钮放在ActionBar的左侧
- gradle - IntelliJ 和 Gradle 出错,无法使用 main
- python - 如何在 tkinter 上使输入文本区域更大?
- sql - 通过查询 Windows 搜索索引获取文件的全部内容
- mysql - MATCH AGAINST 全文 MariaDB 中的连字符
- javascript - 如何将 React faq 组件与来自 API 的数据一起使用
- javascript - 使用磁盘上的文件夹的项目
- swift - 多点触控操作的多线程 Coregraphics 绘图,Swift