授权
- 要区分请求是不是需要权限控制,比如查看商品的请求就是不需要授权的;
- 没有权限的时候,要返回 403;
- 403 的返回也要被记录,记录是谁在访问没有权限访问的东西;
401 vs 403
- 被返回 401 的用户,通过调整 HTTP Header 中的信息,是可以请求到业务方法的;
- 被返回 403 的用户,是无法通过调整 HTTP Header 中的信息,访问到业务方法的;
访问控制的实现方式
ACL | Access Control Lists
- 简单易用,实现容易;
- 无法满足复杂的业务需求,不易管理;
RBAC | Role Based Access Control
- 引入角色概念,简化管理;
- 开发起来相对 ACL 复杂;
ACL 的简单实现
package com.lixinlei.security.api.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.lixinlei.security.api.vo.UserInfo;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
@Component
public class AclInterceptor extends HandlerInterceptorAdapter {
private String[] permitUrls = new String[] {"/users/login"};
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println(4);
boolean result = true;
if( !ArrayUtils.contains(permitUrls, request.getRequestURI()) ) {
UserInfo user = (UserInfo) request.getSession().getAttribute("user");
if(user == null) {
// 没有通过认证
response.setContentType("text/plain");
response.getWriter().write("need authentication");
response.setStatus(HttpStatus.UNAUTHORIZED.value());
result = false;
} else {
String method = request.getMethod();
// 用户的 permission 字段中,是否有请求的方法
if(!user.hasPermission(method)) {
response.setContentType("text/plain");
response.getWriter().write("forbidden");
response.setStatus(HttpStatus.FORBIDDEN.value());
result = false;
}
}
}
return result;
}
}
网友评论