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

6 篇文章 0 订阅

一、权限验证

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

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 屏蔽部分字段时,通过修改表单可以强改信息

新注册一个用户
注册
数据库在注册后如图所示
注册数据库激活后修改资料
资料修改前
修改表单为下图所示,模拟攻击——利用工具修改了username并添加了id字段
资料修改

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值