springmvc简单实现权限控制

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

 

1.写一个自定义注解(功能类似于spring security的@PreAuthorize)

 

[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 {// 登录了检查,方法上只是@Auth,表示只要求登录就能通过.@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. }  

处理controller的@RequestMapping方法(这里的处理直接通过response处理,spring security先抛异常,然后再统一处理异常):
a.如果这个方法没有使用Auth注解,会认为没有作权限控制,任何人可以访问.
b.如果这个方法只标注了@Auth,如果用户没登录,会返回一个403,并提示用户登录.
c.如果这个方法标注了具体需要某种权限,如@Auth("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. }  

猜你喜欢

转载自mawj0326-163-com.iteye.com/blog/2283344