关于MVC3,从客户端(userName="<hr />")中检测到有潜在危险的 Request.Form 值的错误

本文讨论了在MVC3提交过程中遇到的潜在危险输入问题,包括从客户端接收包含HTML标签的数据时引发的安全警告。文章提供了通过修改HTTP运行时配置和禁用请求验证来解决这一问题的方法,并强调了在应用输入验证的重要性。

MVC3提交是句的时候,值含有Html标签往往会报这个错误  从客户端(userName="<hr />")中检测到有潜在危险的 Request.Form 值 解决方案网上有很多种说法,微软官方给出的合MVC

说明: 请求验证过程检测到有潜在危险的客户端输入值,对请求的处理已经中止。该值可能指示存在危及应用程序安全的尝试,如跨站点脚本攻击。若要允许页面重写应用程序请求验证设置,请将 httpRuntime 配置节中的 requestValidationMode 特性设置为 requestValidationMode="2.0"。示例: <httpRuntime requestValidationMode="2.0" />。设置此值后,可通过在 Page 指令或 <pages> 配置节中设置 validateRequest="false" 禁用请求验证。但是,在这种情况下,强烈建议应用程序显式检查所有输入。

如:<httpRuntime requestValidationMode="2.0" />,在配置文件加上这句,运行还是会报错,最后还需要在Controller的action上加上这个标签[ValidateInput(false)]

例:[ValidateInput(false)]
        public ActionResult LogOn(LogOnModel model, string returnUrl)

之后就可以运行了

从客户端(userName="<hr />")中检测到有潜在危险的 Request.Form

(一)项目构建 使用 Maven 构建项目,在pom.xml中引入 Spring MVC 相关依赖,如spring - webmvc,配置 Servlet、JSP 等相关依赖,确保项目具备 Spring MVC 运行环境 。示例关键依赖配置: <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring - webmvc</artifactId> <version>5.3.18</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet - api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp - api</artifactId> <version>2.3.3</version> <scope>provided</scope> </dependency> <!-- 其他如JSTL等依赖按需添加 --> </dependencies> (二)Spring MVC 配置 DispatcherServlet 配置:在 Web.xml(或 Servlet 3.0 + 环境下用 Java 配置)中配置 DispatcherServlet,指定 Spring MVC 配置文件位置,使其能拦截处理请求 。示例 Web.xml 配置: <servlet> <servlet - name>springmvc</servlet - name> <servlet - class>org.springframework.web.servlet.DispatcherServlet</servlet - class> <init - param> <param - name>contextConfigLocation</param - name> <param - value>classpath:springmvc - servlet.xml</param - value> </init - param> <load - on - startup>1</load - on - startup> </servlet> <servlet - mapping> <servlet - name>springmvc</servlet - name> <url - pattern>/</url - pattern> </servlet - mapping> Spring MVC 配置文件(springmvc - servlet.xml):开启组件扫描(扫描控制器等组件)、视图解析器(配置前缀后缀,解析 JSP 视图)、开启注解驱动等 。示例: <context:component - scan base - package="com.example.controller"/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB - INF/views/"/> <property name="suffix" value=".jsp"/> </bean> <mvc:annotation - driven/> 三)功能模块实现 1. 用户登录验证 o 控制器(Controller):创建LoginController,编写方法处理/login请求(对应login.jsp表单提交),接收用户名、密码参数(可通过@RequestParam注解),进行简单验证(如硬编码用户名 “admin”、密码 “123” 模拟,实际可连数据库查询),验证成功用return "redirect:/main";重定向到主页控制器方法,失败则带错误信息(通过model.addAttribute)返回login视图(即login.jsp )。示例代码: package com.example.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller public class LoginController { @RequestMapping("/login") public String login(@RequestParam("username") String username, @RequestParam("password") String password, Model model) { if ("admin".equals(username) && "123".equals(password)) { return "redirect:/main"; } else { model.addAttribute("error", "用户名或密码错误"); return "login"; } } 2. 登录页面(login.jsp):使用 Spring 表单标签库(需引入相关标签库)或普通 HTML 表单,提交到/login,显示错误信息(通过 EL 表达式${error} )。示例关键代码: <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> <html> <body> <form:form action="/login" method="post"> 用户名:<form:input path="username"/><br> 密码:<form:password path="password"/><br> <input type="submit" value="登录"> </form:form> <c:if test="${not empty error}"> <p style="color:red">${error}</p> </c:if> </body> </html> 3. 访问控制(拦截器实现) o 创建拦截器类:实现HandlerInterceptor接口,在preHandle方法中检查会话是否有用户登录标识(如session.getAttribute("user") ,假设登录成功时在会话存user对象),无则redirect到/login并返回false拦截,有则返回true放行 。示例: package com.example.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Object user = request.getSession().getAttribute("user"); if (user == null) { response.sendRedirect(request.getContextPath() + "/login"); return false; } return true; } } 4. 配置拦截器:在 Spring MVC 配置文件(springmvc - servlet.xml)中注册拦截器,指定拦截路径(如/main )。示例: <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/main"/> <bean class="com.example.interceptor.LoginInterceptor"/> </mvc:interceptor> </mvc:interceptors> 5. 会话管理(登出功能) o 控制器方法:在MainController中编写处理登出的方法,调用session.invalidate()销毁会话,然后redirect到登录页 。示例: package com.example.controller; import javax.servlet.http.HttpSession; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class MainController { @RequestMapping("/main") public String main() { return "main"; } @RequestMapping("/logout") public String logout(HttpSession session) { session.invalidate(); return "redirect:/login"; } } 6. 主页(main.jsp):添加 “退出” 链接, href 指向/logout 。示例: <html> <body> <h1>欢迎访问主页</h1> <a href="${pageContext.request.contextPath}/logout">退出</a> </body> </html>
06-05
package com.hnkj.webdemo.controller; public class AuthController { } package com.hnkj.webdemo.entity; public class User { } package com.hnkj.webdemo.repository; public class UserRepository { } package com.hnkj.webdemo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class WebdemoApplication { public static void main(String[] args) { SpringApplication.run(WebdemoApplication.class, args); } } spring.application.name=webdemo spring.datasource.url=jdbc:mysql://localhost:3306/sale_manager_system?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver package com.hnkj.webdemo; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class WebdemoApplicationTests { @Test void contextLoads() { } } <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.18</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.hnkj</groupId> <artifactId>webdemo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>webdemo</name> <description>Demo project for Spring Boot</description> <url/> <licenses> <license/> </licenses> <developers> <developer/> </developers> <scm> <connection/> <developerConnection/> <tag/> <url/> </scm> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>管理员登录界面</title> <!-- 外链式引入css样式 --> <link rel="stylesheet" href="css/login.css" /> </head> <body> <div id="login"> <h2 class="login-title">用户登录</h2> <form id="loginform" name="loginform"> <div class="loginFunc"> <span class="loginFuncApp">二维码登录</span> <span class="loginFuncNormal">账号登录</span> </div> <input type="text" placeholder="账号" class="userName" name="userName" /> <input type="password" placeholder="密码" class="password" name="password" /> <p class="info"> <input type="radio" value="1" name="role" checked /> <span>管理员</span> <input type="radio" value="2" name="role" /> <span>用户</span> <span class="help"><a href="#">忘记密码?</a></span> </p> <input type="submit" value="登 录" class="submit" /> <input type="button" value="注 册" class="button" onclick="register()" /> </form> <div id="loginError" style="color: red; margin-bottom: 10px; text-align: center;"></div> </div> <!-- 确保 DOM 加载完成后再绑定事件监听器 --> <script> document.getElementById(&#39;loginform&#39;).addEventListener(&#39;submit&#39;, function (e) { e.preventDefault(); // 阻止表单默认提交行为 // 获取输入的账号和密码 const userName = document.querySelector(&#39;.userName&#39;).value; const password = document.querySelector(&#39;.password&#39;).value; const loginError = document.getElementById(&#39;loginError&#39;); // 清除之前的错误信息 loginError.textContent = &#39;&#39;; // 进行登录校验 if (userName.trim() === &#39;&#39;) { loginError.textContent = &#39;账号不能为空&#39;; return; } if (password.trim() === &#39;&#39;) { loginError.textContent = &#39;密码不能为空&#39;; return; } // 如果需要更复杂的校验,可以添加更多规则,例如密码长度等 if (password.length < 6) { loginError.textContent = &#39;密码长度不能少于6位&#39;; return; } // 获取表单数据 const formData = new FormData(this); const data = Object.fromEntries(formData.entries()); console.log(&#39;登录数据:&#39;, data); // 发送AJAX请求 fetch(&#39;http://localhost:8080/api/auth/login&#39;, { method: &#39;POST&#39;, headers: { &#39;Content-Type&#39;: &#39;application/x-www-form-urlencoded&#39; }, body: new URLSearchParams(data) }) .then(response => { console.log(&#39;登录响应:&#39;, response); return response.json(); }) .then(result => { console.log(&#39;登录成功:&#39;, result); if (result.success) { // 根据表单选择的角色跳转 const role = data.role; // 获取表单中的角色 const redirectPath = role === &#39;1&#39; ? &#39;AdminSystem/adminHome.html&#39; : &#39;UserSystem/userHome.html&#39;; window.location.href = redirectPath; } else { // 登录失败,显示错误信息 alert(result.message); } }) .catch(error => { console.error(&#39;登录请求出错:&#39;, error); alert(&#39;登录请求失败,请重试&#39;); }); }); function register() { window.location.href = "register.html"; } </script> </body> </html> 通过这几段代码能否找到问题所在
06-05
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html lang="zh-CN" class="bootstrap-admin-vertical-centered"> <head> <meta charset="UTF-8"> <title>图书馆管理系统</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link rel="stylesheet" href="static/css/bootstrap.min.css"> <link rel="stylesheet" href="static/css/bootstrap-theme.min.css"> <link rel="stylesheet" href="static/css/bootstrap-admin-theme.css"> <link rel="stylesheet" href="static/css/bootstrap-admin-theme.css"> <script src="static/js/bootstrap.min.js"></script> <script src="static/jQuery/jquery-3.1.1.min.js"></script> <script src="static/ajax-lib/ajaxutils.js"></script> <script src="static/js/login.js"></script> </head> <style type="text/css"> .alert{ margin: 0 auto 20px; text-align: center; } </style> <script src="static/js/jquery.min.js"></script> <script src="static/js/bootstrap.min.js"></script> <body class="bootstrap-admin-without-padding"> 池州学院 230312242 杨洪博 课设 <div style="background-image: url(&#39;/books/WebContent/2.png&#39;); background-size: cover; background-repeat: no-repeat; background-position: center;"></div> <div class="col-lg-12"> <div class="alert alert-info"> <a class="close" data-dismiss="alert" href="#">×</a> 欢迎登录图书馆管理系统 </div> <form class="bootstrap-admin-login-form" method="post" action="/books/LoginServlet"> <% String state = (String)session.getAttribute("state"); session.removeAttribute("state"); if(state!=null){ %> <label class="control-label" for="username">密码错误</label> <%}%> <div class="form-group"> <label class="control-label" for="username">账 号</label> <input type="text" class="form-control" id="username" name="username" required="required" placeholder="学号"/> <label class="control-label" for="username" style="display:none;"></label> </div> <div class="form-group"> <label class="control-label" for="password">密 码</label> <input type="password" class="form-control" id="password" name="password" required="required" placeholder="密码"/> <label class="control-label" for="username" style="display:none;"></label> </div> <label class="control-label" for="password">没有账号请<a href="/books/register.jsp" style="color:blue;">注册</a></label> <br> <input type="submit" class="btn btn-lg btn-primary" value="登    录"/> </form> </div> </div> </div> <div class="modal fade" id="modal_info" tabindex="-1" role="dialog" aria-labelledby="addModalLabel"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title" id="infoModalLabel">提示</h4> </div> <div class="modal-body"> <div class="row"> <div class="col-lg-12" id="div_info"></div> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" id="btn_info_close" data-dismiss="modal">关闭</button> </div> </div> </div> </div> </body> </html> 图片不显示 是哪里出了问题
06-22
实验09 SpringBoot 用户管理实战(JPA) 【实验目的及要求】 1. 掌握 Spring Boot 整合JPA 实现数据 CRUD(增删改查); 2. 掌握 MVC 分层架构(Controller→Service→Mapper) 3. 学会前后端数据交互:Thymeleaf 模板 4. 掌握密码加密等基础安全处理 5. 要求所有回答的文本格式:五号,宋体、1.5倍行距,保留段单元格背景。 【实验步骤】 1、 导入jpademo项目框架,添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.23</version> <!-- 使用最新的版本号 --> </dependency> <!-- Spring Boot Starter Data JPA --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> 2、 实体类 package com.example.demo.entity; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.Table; @Entity @Table(name="user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private int age; // 构造函数、getter和setter public User() {} public User(String name, int age) { this.name = name; this.age = age; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } 3、 Repository package com.example.demo.repository; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; import com.example.demo.entity.User; public interface UserRepository extends JpaRepository<User, Long> { List<User> findByName(String name); } 4、 Controller package com.example.demo.controller; import java.util.List; import java.util.Optional; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import com.example.demo.entity.User; import com.example.demo.repository.UserRepository; @Controller public class UserController { private final UserRepository userRepository; public UserController(UserRepository userRepository) { this.userRepository = userRepository; } @GetMapping("/users") public String listUsers(Model model) { List<User> users = userRepository.findAll(); model.addAttribute("users", users); return "users"; } @GetMapping("/users/new") public String showCreateForm(Model model) { model.addAttribute("user", new User()); return "create_user"; } @PostMapping("/users") public String createUser(@ModelAttribute User user) { userRepository.save(user); return "redirect:/users"; } @GetMapping("/users/{id}/edit") public String showEditForm(@PathVariable Long id, Model model) { Optional<User> userOptional = userRepository.findById(id); if (userOptional.isPresent()) { model.addAttribute("user", userOptional.get()); return "edit_user"; } else { return "redirect:/users"; } } @PostMapping("/users/{id}") public String updateUser(@PathVariable Long id, @ModelAttribute User user) { user.setId(id); userRepository.save(user); return "redirect:/users"; } @GetMapping("/users/{id}/delete") public String deleteUser(@PathVariable Long id) { userRepository.deleteById(id); return "redirect:/users"; } @GetMapping("/findbyname") public String findbyname(@RequestParam(name = "nameToFind", required = false) String name, Model model) { System.out.println("received query:" + name); List<User> users = userRepository.findByName(name); model.addAttribute("users", users); return "findbyname"; } @GetMapping("/findbyname2/{name}") public String findbyname2(@PathVariable String name, Model model) { System.out.println("received query2:" + name); List<User> users = userRepository.findByName(name); model.addAttribute("users", users); return "findbyname"; } } 5、 前端页面 增加用户: <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Create User</title> </head> <body> <h1>Create New User</h1> <form action="/users" method="post"> <label for="name">Name:</label> <input type="text" id="name" name="name" required><br> <label for="age">Age:</label> <input type="number" id="age" name="age" required><br> <input type="submit" value="Create User"> </form> </body> </html> 编辑用户: <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Edit User</title> </head> <body> <h1>Edit User</h1> <form action="/users/{id}" th:action="@{&#39;/users/&#39; + ${user.id}}" method="post"> <input type="hidden" name="id" th:value="${user.id}"> <label for="name">Name:</label> <input type="text" id="name" name="name" th:value="${user.name}" required><br> <label for="age">Age:</label> <input type="number" id="age" name="age" th:value="${user.age}" required><br> <input type="submit" value="Update User"> </form> </body> </html> 列出所有用户: <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>User List</title> </head> <body> <h1>User List</h1> <table border="1"> <thead> <tr> <th>ID</th> <th>Name</th> <th>Age</th> <th>Actions</th> </tr> </thead> <tbody> <tr th:each="user : ${users}"> <td th:text="${user.id}"></td> <td th:text="${user.name}"></td> <td th:text="${user.age}"></td> <td> <a th:href="@{/users/{id}/edit(id=${user.id})}">Edit</a> <a th:href="@{/users/{id}/delete(id=${user.id})}" onclick="return confirm(&#39;Are you sure you want to delete this user?&#39;)">Delete</a> </td> </tr> </tbody> </table> <a href="/users/new">Create New User</a> <form action="/findbyname" method="get"> <label for="nameToFind"> Find By Name:</label> <input type="text" id="nameToFind" name="nameToFind" required><br> <input type="submit" value="FindByname"> </form> </body> </html> 按名字查找: <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>findbyname list</title> </head> <body> <h1>User List</h1> <ul> <li th:each="user:${users}"> Name:<span th:text="${user.name}"></span>,Age:<span th:text="${user.age}"></span> </li> </ul> <form action="/users" method="get"> <input type="submit" value="Back to List User"> </form> </body> </html> 6、 SQL脚本 -- Server version 8.0.41 drop database if exists userdb; create database if not exists userdb; use userdb; DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` bigint NOT NULL AUTO_INCREMENT, `age` int NOT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; insert into user(age,name) values(21,&#39;Bob&#39;); insert into user(age,name) values(22,&#39;James&#39;); insert into user(age,name) values(38,&#39;张三&#39;); insert into user(age,name) values(45,&#39;李四&#39;); insert into user(age,name) values(29,&#39;Eileen&#39;); 7、 测试结果截图输出 (1)列出用户清单,截图: (2)修改用户信息,截图: (3)删除用户,截图: (4)扩展功能:为用户表添加 “性别、邮箱、手机号,角色” 字段,实现新增和编辑功能,采用Lombok自动添加getter和setter方法: 修改的代码: 运行截图:
最新发布
11-28
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值