当前位置: 代码迷 >> VC/MFC >> springmvc容易实现权限控制
  详细解决方案

springmvc容易实现权限控制

热度:211   发布时间:2016-05-02 03:16:46.0
springmvc简单实现权限控制

用过了Spring Security,一般都不会采用这种简单的自定义方式.自定义当然灵活自由,越要完善,也就意味做的工作越多.使用框架,别人考虑得相对周到,比如spring security的防止攻击就有session fixation, clickjacking, cross site request forgery.以下的简单实现的权限控制虽然可以去实现这样的功能,但就没必要了.当然这个模型是包含认证和授权.

?

1.写一个自定义注解(功能类似于spring [email protected])

?

[java]?view plain
  1. package?org.exam.auth;??
  2. import?java.lang.annotation.ElementType;??
  3. import?java.lang.annotation.Retention;??
  4. import?java.lang.annotation.RetentionPolicy;??
  5. import?java.lang.annotation.Target;??
  6. @Retention(RetentionPolicy.RUNTIME)??
  7. @Target(ElementType.METHOD)??
  8. public?@interface?Auth?{??
  9. ????String?value()?default?"";??
  10. ????String?name()?default?"";??
  11. }??

2.写一个拦截器.

[java]?view plain
  1. package?org.exam.auth;??
  2. import?org.springframework.http.HttpStatus;??
  3. import?org.springframework.web.method.HandlerMethod;??
  4. import?org.springframework.web.servlet.handler.HandlerInterceptorAdapter;??
  5. import?javax.servlet.http.HttpServletRequest;??
  6. import?javax.servlet.http.HttpServletResponse;??
  7. import?java.io.PrintWriter;??
  8. import?java.util.Set;??
  9. public?class?AuthInterceptor?extends?HandlerInterceptorAdapter?{??
  10. ????public?static?final?String?SESSION_USERID?=?"kUSERID";??
  11. ????public?static?final?String?SESSION_AUTHS?=?"kAUTHS";??
  12. ????@Override??
  13. ????public?boolean?preHandle(HttpServletRequest?request,??
  14. ????????????HttpServletResponse?response,?Object?handler)?throws?Exception?{??
  15. ????????boolean?flag?=?true;??
  16. ????????if?(handler?instanceof?HandlerMethod)?{??
  17. ????????????Auth?auth?=?((HandlerMethod)?handler).getMethod().getAnnotation(Auth.class);??
  18. ????????????if?(auth?!=?null)?{//?有权限控制的就要检查??
  19. ????????????????if?(request.getSession().getAttribute(SESSION_USERID)?==?null)?{//?没登录就要求登录??
  20. ????????????????????response.setStatus(HttpStatus.FORBIDDEN.value());??
  21. ????????????????????response.setContentType("text/html;?charset=UTF-8");??
  22. ????????????????????PrintWriter?out=response.getWriter();??
  23. ????????????????????out.write("{\"type\":\"nosignin\",\"msg\":\"请您先登录!\"}");??
  24. ????????????????????out.flush();??
  25. ????????????????????out.close();??
  26. ????????????????????flag?=?false;??
  27. ????????????????}?else?{//?登录了检查,[email protected],表示只要求登录就能通过.@Auth("authority")这类型,验证用户权限??
  28. ????????????????????if?(!"".equals(auth.value()))?{??
  29. ????????????????????????Set<String>?auths?=?(Set<String>)?request.getSession().getAttribute(SESSION_AUTHS);??
  30. ????????????????????????if?(!auths.contains(auth.value()))?{//?提示用户没权限??
  31. ????????????????????????????response.setStatus(HttpStatus.FORBIDDEN.value());??
  32. ????????????????????????????response.setContentType("text/html;?charset=UTF-8");??
  33. ????????????????????????????PrintWriter?out=response.getWriter();??
  34. ????????????????????????????out.write("{\"type\":\"noauth\",\"msg\":\"您没有"+auth.name()+"权限!\"}");??
  35. ????????????????????????????out.flush();??
  36. ????????????????????????????out.close();??
  37. ????????????????????????????flag?=?false;??
  38. ????????????????????????}??
  39. ????????????????????}??
  40. ????????????????}??
  41. ????????????}??
  42. ????????}??
  43. ????????return?flag;??
  44. ????}??
  45. }??

[email protected](这里的处理直接通过response处理,spring security先抛异常,然后再统一处理异常):
a.如果这个方法没有使用Auth注解,会认为没有作权限控制,任何人可以访问.
[email protected],如果用户没登录,会返回一个403,并提示用户登录.
c.如果这个方法标注了具体需要某种权限,[email protected]("authority"),就要求用户必须有这种权限,否则返回403,并提示用户没有权限,这里相当于实现授权,并且授权之前先认证.


3.让拦截器起作用.重写org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter#addInterceptors方法

[java]?view plain
  1. @Configuration??
  2. @ComponentScan(basePackages={"org.exam.web"})??
  3. @EnableWebMvc??
  4. public?class?MvcConfig?extends?WebMvcConfigurerAdapter{??
  5. ????@Override??
  6. ????public?void?addInterceptors(InterceptorRegistry?registry)?{??
  7. ????????registry.addInterceptor(new?AuthInterceptor());??
  8. ????}??
  9. ????//其它略...??
  10. }??

4.用户登录(只做了一个模拟登录)和具体使用,剩下的就可以测试了.

[java]?view plain
  1. @Controller??
  2. @RequestMapping("/user")??
  3. public?class?UserController?{??
  4. ????@RequestMapping("/login")??
  5. ????@ResponseBody??
  6. ????public?boolean?login(HttpSession?session,User?user){??
  7. ????????boolean?result=false;??
  8. ????????//模拟从数据库查出存在这样的用户??
  9. ????????Long?userId=user.getId();??
  10. ????????if(userId!=null&&userId>0){??
  11. ????????????session.setAttribute(AuthInterceptor.SESSION_USERID,?userId);??
  12. ????????????session.setAttribute(AuthInterceptor.SESSION_AUTHS,?new?HashSet<String>(Arrays.asList("user_list",?"user_query",?"user_save")));??
  13. ????????????result=true;??
  14. ????????}??
  15. ????????return?result;??
  16. ????}??
  17. ????@Auth("user_queryXXXX")??
  18. ????@RequestMapping("/query")??
  19. ????@ResponseBody??
  20. ????public?String?query(){??
  21. ????????System.out.println("query");??
  22. ????????return?getClass().toString();??
  23. ????}??
  24. ????@Auth("user_list")??
  25. ????@RequestMapping("/list")??
  26. ????@ResponseBody??
  27. ????public?String?list(){??
  28. ????????System.out.println("list");??
  29. ????????return?getClass().toString();??
  30. ????}??
  31. ????@Auth("user_save")??
  32. ????@RequestMapping("/add")??
  33. ????public?String?add(User?user){??
  34. ????????System.out.println("add:"+user);??
  35. ????????return?"user/add";??
  36. ????}??
  37. } ?
  相关解决方案