使用SSM重构Bookstoe——修改用户资料

一、权限验证

要修改用户资料首先需要用户登录,有两种方法进行权限验证

Servlet的过滤器 Filter

package com.bookstore.Filter;

import com.bookstore.Domain.User;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@WebFilter(urlPatterns = {"/myAccount"})   //到底要不要加@Component,不加也能工作
public class RequiredLoginFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        try {
            User user = (User) req.getSession().getAttribute("user"); //对null强转也不会出错 
            System.out.println("RequiredLoging filter working" + user);
            if(user == null)throw new ClassCastException();
            chain.doFilter(req, response);
        } catch (ClassCastException e) {
        	String returnURL = request.getMethod().equalsIgnoreCase("POST") ? request.getHeader("Referer") : request.getRequestURL().toString();  //根据方法不同选择不同跳转地址
            req.setAttribute("message", "您还未登录#登录页面#login?returnURL=" + returnURL);  //方便在登录后跳转回原页面,还需相应改动login的handler部分,请参考前文
            req.getRequestDispatcher("/WEB-INF/views/message.jsp").forward(req, response);
        }
    }
}

Spring MVC的拦截器 Interceptor

package com.bookstore.Interceptor;

import com.bookstore.Domain.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class RequiredLoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        User user = (User) request.getSession().getAttribute("user");
        if(user == null){
        	String returnURL = request.getMethod().equalsIgnoreCase("POST") ? request.getHeader("Referer") : request.getRequestURL().toString();
            request.setAttribute("message", "您还未登录#登录页面#login?returnURL=" + returnURL);  //方便在登录后跳转回原页面,还需相应改动login的handler部分,请参考前文
            request.getRequestDispatcher("/WEB-INF/views/message.jsp").forward(request,response);   //以contextroot为根目录
            return false;  //我挺好奇的不加这个跳转后怎么执行
        }
        return true;
    }
}

使用拦截器还需要在SpringMVC的配置文件添加设置

<mvc:interceptors>
	<mvc:interceptor>
		<mvc:mapping path="/myAccount"/>
		<bean class="com.bookstore.Interceptor.RequiredLoginInterceptor" />
	mvc:interceptor>
mvc:interceptors>

二、修改用户资料实现代码

UserController.java

@GetMapping("/myaccount")
public String myAccount() {
	return "myAccount";
}

@GetMapping("/modifyuserinfo")
public String modifyUserInfo() {
	return "modifyuserinfo";
}

@InitBinder
public void disallowFileds(WebDataBinder binder) {
	binder.setDisallowedFields("id", "activecode", "role", "state"); // 用于防范攻击,可以看看下面的发现,不知道还有没有更好的方法
}

@PostMapping("/modifyuserinfo")
public String modifyUserInfo(User modifiedUser, Model model, HttpSession session) throws UserException {
    //修改资料
	modifiedUser.setId(((User) session.getAttribute("user")).getId());   //通过initBinder禁止,即使没有设置攻击也不会成功
	// modifiedUser.setUsername(((User) session.getAttribute("user")).getUsername());
	userService.modifyUserInfo(modifiedUser);
    //重载sesssion中的user信息
	modifiedUser = userService.getUserByID(modifiedUser.getId());
	session.setAttribute("user", modifiedUser);
	model.addAttribute("message", "资料更新成功");
	return "message";
}

UserService.java

@Transactional
public void modifyUserInfo(User modifiedUser) throws UserException {
	int result = userDao.updateByPrimaryKeySelective(modifiedUser);
	if(result != 1){
		throw new UserException("资料更新失败#-1");
	}
}

public User getUserByID(String id) {
	return userDao.selectByPrimaryKey(id);
}

三、有趣发现

在不添加InitBinder 屏蔽部分字段时,通过修改表单可以强改信息

新注册一个用户
使用SSM重构Bookstoe——修改用户资料_第1张图片
数据库在注册后如图所示
注册数据库激活后修改资料
使用SSM重构Bookstoe——修改用户资料_第2张图片
修改表单为下图所示,模拟攻击——利用工具修改了username并添加了id字段
使用SSM重构Bookstoe——修改用户资料_第3张图片

MyBatis更新语句 —— 用户名强改成功,但id没有被修改
使用SSM重构Bookstoe——修改用户资料_第4张图片
数据库中保存结果
资料修改后数据库
注意比较——莫名其妙少了一天,搜索了下看起来与时区设置有关
使用SSM重构Bookstoe——修改用户资料_第5张图片
补充下——用role字段来模拟攻击,可以看到其被initBinder给屏蔽了没有产生效果:
使用SSM重构Bookstoe——修改用户资料_第6张图片使用SSM重构Bookstoe——修改用户资料_第7张图片

你可能感兴趣的:(JAVA,Spring)