SpringBoot的创建
创建项目
新建项目–>选择maven项目–>更改服务器url(https://start.aliyun.com/):
选择下一步–>选择版本2.x的即可–>在web下勾选Spring Web–>点击创建即可
点击编辑配置:
最终:
其中目录结构为:
C:.
├─.idea
├─src
│ ├─main
│ │ ├─java
│ │ │ └─org
│ │ │ └─example
│ │ │ └─javaweb_02
│ │ └─resources
│ │ └─static //这里会存放一些静态的页面
│ └─test
│ └─java
│ └─org
│ └─example
│ └─javaweb_02
└─target
├─classes
│ ├─org
│ │ └─example
│ │ └─javaweb_02
│ │ └─demos
│ │ └─web
│ └─static
├─generated-sources
│ └─annotations
├─generated-test-sources
│ └─test-annotations
├─maven-archiver
├─maven-status
│ └─maven-compiler-plugin
│ ├─compile
│ │ └─default-compile
│ └─testCompile
│ └─default-testCompile
├─surefire-reports
└─test-classes
└─org
└─example
└─javaweb_02
以下三个的文件是aliyun镜像创建的可以删除
创建application.yml
它的作用和application.properties类似是配置文件,优先级是application.properties高于application.yml
开启项目的样子:
报错页面:
创建文件:
即在当前的文件夹下创建cn.Controller
现在创建spring文件:
写上注解:@RestController
index代码如下:
package org.example.javaweb_02.cn.Controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController //这个文件表示的是Controller 并且可以返回页面信息 @RestController = @ResponseBody + @Controller
public class index {
@RequestMapping("/index") //类似路由
public String index() {
return "我是index方法";
}
}
访问后如下:127.0.0.1:port/index
参数可控问题:
package org.example.javaweb_02.cn.Controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@RestController //这个文件表示的是Controller 并且可以返回页面信息 @RestController = @ResponseBody + @Controller
// springboot会融合ssm-->spring servlet mybit
public class index {
@RequestMapping("/index") //类似路由
// 原始的spring的写法:
public String index(String name) {
return name; //参数名即为可控的参数
}
// public String index(HttpServletRequest req) { // 做参数可控,利用servlet的方式
//
// return "我是index方法";
//
// return req.getParameter("name"); //这个语句是可以在项目中看到的spring+servlet
//}
//
//关于在springboot中区别get和post的请求
// post
@PostMapping("/test01")
public String post() {
return "这里进行了post请求";
}
@GetMapping("/test02")
public String get() {
return "这里进行了get方式的请求";
}
@RequestMapping(value = "/test03",method = RequestMethod.HEAD) //类似路由
public String head() {
return "我是head方法";
}
}
绑定参数传参:
@RequestMapping("/abc/{id}/{name}")
public String hello(@PathVariable("id") int id,@PathVariable("name")String name){
return "name:"+name+"id:"+id;
}
像这样的情况可能会出现xss反射,默认情况下 springboot不解析jsp
小结
package org.example.javaweb_02.cn.Controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@RestController //这个文件表示的是Controller 并且可以返回页面信息 @RestController = @ResponseBody + @Controller
// springboot会融合ssm-->spring servlet mybit
//@RequestMapping("/api") 如果存在这句话在前面然后再写@RequestMapping("/index")访问路径即为:ip:port/api/index
public class index {
@RequestMapping("/index") //类似路由
// 原始的spring的写法:
public String index(String name,int age) {
return name+age; //参数名即为可控的参数
}
// public String index(HttpServletRequest req) { // 做参数可控,利用servlet的方式
//
// return "我是index方法";
//
// return req.getParameter("name"); //这个语句是可以在项目中看到的spring+servlet
//}
//
//关于在springboot中区别get和post的请求
// post
@PostMapping("/test01")
public String post() {
return "这里进行了post请求";
}
@GetMapping("/test02")
public String get() {
return "这里进行了get方式的请求";
}
@RequestMapping(value = "/test03",method = RequestMethod.HEAD) //类似路由
public String head() {
return "我是head方法";
}
}
SpringBoot过滤器拦截器&Shiro机制
过滤器
先启动spring项目:
新建一个java类,然后实现这个接口implements Filter:
之后再进行实现这个方法(快捷键是ctrl+i):
package Filter;
import javax.servlet.*;
import java.io.IOException;
public class check_user implements Filter { //进行实现过滤器 extends Filter
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
}
}
拦截器
做两个文件为check.user:
package check;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class user implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //preHandle类似doFilter 返回值不一样
System.out.println("我是方法preHandle");
return true; //true表示放行 false表示拦截下来
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("我是方法postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("我是方法afterCompletion");
}
}
一个为config.webconfig:
package config;
import check.user;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class webconfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new user()).addPathPatterns("/**").excludePathPatterns("/index/aaa"); //addPathPatterns后面括号的内容就是拦截的内容,excludePathPatterns意思/index后的aaa不会去触发拦截器
}
}
Shiro
shiro更好的做权限的划分
代码示例
package com.example.demo.Config;
import com.example.demo.relm.userrelm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.swing.*;
import java.util.HashMap;
@Configuration
public class ShiroConfig {
//跟下面那个玩意绑定并且设置安全管理器
public ShiroFilterFactoryBean
getShiroFilterFactoryBean(@Qualifier("setSecurityManager")
DefaultWebSecurityManager getDefaultWebSecurityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new
ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(getDefaultWebSecurityManager);
//开始设置过滤器
//anon:无需认证
//authc 必须认证了才能访问
//user 必须拥有 记住我功能才可以使用
//perms 拥有对某个资源的的权限才可以访问
//role 拥有对某个角色的权限才可以访问
HashMap<String, String> FilterChainDefinitionMap = new HashMap<>();
FilterChainDefinitionMap.put("/index","authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(FilterChainDefinitionMap);
return shiroFilterFactoryBean;
}
//跟下面那个玩意绑定
@Bean(name = "setSecurityManager")
public DefaultWebSecurityManager
getDefaultWebSecurityManager(@Qualifier("userrelm") userrelm userrelm){
DefaultWebSecurityManager defaultWebSecurityManager = new
DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(userrelm);
return defaultWebSecurityManager;
}
//创建ream对象,自定义类
@Bean
public userrelm userrelm(){
return new userrelm();
}
}
java鉴权
一般拦截器不好绕过但是过滤器会更好绕过,权限绕过的文章参考:
filter绕过
获取url的几种方法:
String requestURI = request.getRequestURI(); // 获取整个URL
System.out.println("1:我是getRequestURI"+requestURI);
StringBuffer requestURL = request.getRequestURL(); //获取url
System.out.println("2:我是getRequestURl"+requestURI);
String servletPath = request.getServletPath(); //获取Servlet的路径
System.out.println("3:我是getServletPath"+requestURI);
先准备两个文件,代码如下:
admin文件(servlet文件)
package Controller;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet(name="admin",urlPatterns="/admin")
public class admin extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// HttpServletRequest request1 = request;
PrintWriter out = response.getWriter();
out.println("This is admin");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}
filter文件:
package Filter;
import javax.servlet.*;
import javax.servlet.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@WebFilter(filterName = "filter01") // 设置一个非空的 filterName
public class filter01 implements Filter {
public void init(FilterConfig config) throws ServletException {
}
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request; //该行代码是为了将通用的 ServletRequest 对象转型为 HttpServletRequest 对象,以便能够访问HTTP特定的请求信息。
String uri = httpServletRequest.getRequestURI(); //获取当前的url
if (uri.endsWith(".css")) { //判断是否为css结尾的文件
chain.doFilter(request, response);
}
else {
System.out.println("不能访问此处");
}
// chain.doFilter(request, response);
}
}
相关效果:
测试相关的Payload绕过
payload | getRequestURL | getRequestURI | getServletPath |
---|---|---|---|
/index | http://127.0.0.1:8081/index | /index | /index |
/./index | http://127.0.0.1:8081/./index | /./index | /index |
/.;/index | http://127.0.0.1:8081/.;/index | /.;/index | /index |
/a/…/index | http://127.0.0.1:8081/a/…/index | /a/…/index | /index |
/a/…;/index | http://127.0.0.1:8081/a/…;/index | /a/…;/index | /index |
/;/index | http://127.0.0.1:8081/;/index | /;/index | /index |
/;a/index | http://127.0.0.1:8081/;a/index | /;a/index | /index |
/%2e/index | http://127.0.0.1:8081/%2e/index | /%2e/index | /index |
/inde%78 | http://127.0.0.1:8081/inde%78 | /inde%78 | /index |
那么即为上述问题,可以看到不同的获取URL的方法,对于结果并不一样。
并且可以发现getServletPath 会对获取到的字符进行解码
可以看出来,其中两个方法:
getRequestURL方法
getRequestURI方法
例子:
如下图绕过