springmvc简单实现权限控制

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


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




  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值