用过了Spring Security,一般都不会采用这种简单的自定义方式.自定义当然灵活自由,越要完善,也就意味做的工作越多.使用框架,别人考虑得相对周到,比如spring security的防止攻击就有session fixation, clickjacking, cross site request forgery.以下的简单实现的权限控制虽然可以去实现这样的功能,但就没必要了.当然这个模型是包含认证和授权.
?
1.写一个自定义注解(功能类似于spring [email protected])
?
- package?org.exam.auth;??
- import?java.lang.annotation.ElementType;??
- import?java.lang.annotation.Retention;??
- import?java.lang.annotation.RetentionPolicy;??
- import?java.lang.annotation.Target;??
- @Retention(RetentionPolicy.RUNTIME)??
- @Target(ElementType.METHOD)??
- public?@interface?Auth?{??
- ????String?value()?default?"";??
- ????String?name()?default?"";??
- }??
2.写一个拦截器.
- package?org.exam.auth;??
- import?org.springframework.http.HttpStatus;??
- import?org.springframework.web.method.HandlerMethod;??
- import?org.springframework.web.servlet.handler.HandlerInterceptorAdapter;??
- import?javax.servlet.http.HttpServletRequest;??
- import?javax.servlet.http.HttpServletResponse;??
- import?java.io.PrintWriter;??
- import?java.util.Set;??
- public?class?AuthInterceptor?extends?HandlerInterceptorAdapter?{??
- ????public?static?final?String?SESSION_USERID?=?"kUSERID";??
- ????public?static?final?String?SESSION_AUTHS?=?"kAUTHS";??
- ????@Override??
- ????public?boolean?preHandle(HttpServletRequest?request,??
- ????????????HttpServletResponse?response,?Object?handler)?throws?Exception?{??
- ????????boolean?flag?=?true;??
- ????????if?(handler?instanceof?HandlerMethod)?{??
- ????????????Auth?auth?=?((HandlerMethod)?handler).getMethod().getAnnotation(Auth.class);??
- ????????????if?(auth?!=?null)?{//?有权限控制的就要检查??
- ????????????????if?(request.getSession().getAttribute(SESSION_USERID)?==?null)?{//?没登录就要求登录??
- ????????????????????response.setStatus(HttpStatus.FORBIDDEN.value());??
- ????????????????????response.setContentType("text/html;?charset=UTF-8");??
- ????????????????????PrintWriter?out=response.getWriter();??
- ????????????????????out.write("{\"type\":\"nosignin\",\"msg\":\"请您先登录!\"}");??
- ????????????????????out.flush();??
- ????????????????????out.close();??
- ????????????????????flag?=?false;??
- ????????????????}?else?{//?登录了检查,[email protected],表示只要求登录就能通过.@Auth("authority")这类型,验证用户权限??
- ????????????????????if?(!"".equals(auth.value()))?{??
- ????????????????????????Set<String>?auths?=?(Set<String>)?request.getSession().getAttribute(SESSION_AUTHS);??
- ????????????????????????if?(!auths.contains(auth.value()))?{//?提示用户没权限??
- ????????????????????????????response.setStatus(HttpStatus.FORBIDDEN.value());??
- ????????????????????????????response.setContentType("text/html;?charset=UTF-8");??
- ????????????????????????????PrintWriter?out=response.getWriter();??
- ????????????????????????????out.write("{\"type\":\"noauth\",\"msg\":\"您没有"+auth.name()+"权限!\"}");??
- ????????????????????????????out.flush();??
- ????????????????????????????out.close();??
- ????????????????????????????flag?=?false;??
- ????????????????????????}??
- ????????????????????}??
- ????????????????}??
- ????????????}??
- ????????}??
- ????????return?flag;??
- ????}??
- }??
[email protected](这里的处理直接通过response处理,spring security先抛异常,然后再统一处理异常):
a.如果这个方法没有使用Auth注解,会认为没有作权限控制,任何人可以访问.
[email protected],如果用户没登录,会返回一个403,并提示用户登录.
c.如果这个方法标注了具体需要某种权限,[email protected]("authority"),就要求用户必须有这种权限,否则返回403,并提示用户没有权限,这里相当于实现授权,并且授权之前先认证.
3.让拦截器起作用.重写org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter#addInterceptors方法
- @Configuration??
- @ComponentScan(basePackages={"org.exam.web"})??
- @EnableWebMvc??
- public?class?MvcConfig?extends?WebMvcConfigurerAdapter{??
- ????@Override??
- ????public?void?addInterceptors(InterceptorRegistry?registry)?{??
- ????????registry.addInterceptor(new?AuthInterceptor());??
- ????}??
- ????//其它略...??
- }??
4.用户登录(只做了一个模拟登录)和具体使用,剩下的就可以测试了.
- @Controller??
- @RequestMapping("/user")??
- public?class?UserController?{??
- ????@RequestMapping("/login")??
- ????@ResponseBody??
- ????public?boolean?login(HttpSession?session,User?user){??
- ????????boolean?result=false;??
- ????????//模拟从数据库查出存在这样的用户??
- ????????Long?userId=user.getId();??
- ????????if(userId!=null&&userId>0){??
- ????????????session.setAttribute(AuthInterceptor.SESSION_USERID,?userId);??
- ????????????session.setAttribute(AuthInterceptor.SESSION_AUTHS,?new?HashSet<String>(Arrays.asList("user_list",?"user_query",?"user_save")));??
- ????????????result=true;??
- ????????}??
- ????????return?result;??
- ????}??
- ????@Auth("user_queryXXXX")??
- ????@RequestMapping("/query")??
- ????@ResponseBody??
- ????public?String?query(){??
- ????????System.out.println("query");??
- ????????return?getClass().toString();??
- ????}??
- ????@Auth("user_list")??
- ????@RequestMapping("/list")??
- ????@ResponseBody??
- ????public?String?list(){??
- ????????System.out.println("list");??
- ????????return?getClass().toString();??
- ????}??
- ????@Auth("user_save")??
- ????@RequestMapping("/add")??
- ????public?String?add(User?user){??
- ????????System.out.println("add:"+user);??
- ????????return?"user/add";??
- ????}??
- } ?