1.写一个自定义注解(功能类似于spring security的@PreAuthorize)
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 {// 登录了检查,方法上只是@Auth,表示只要求登录就能通过.@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; } }处理controller的@RequestMapping方法(这里的处理直接通过response处理,spring security先抛异常,然后再统一处理异常):
@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"; } }