代码审计-JAX-RS与Jersey

前几天代码审计看见有一个系统用了JAX-RX,所以特地学一下

简介

  • 概念: JAX-RS是Java编程中用于开发 RESTful 风格 Web 服务的一套官方标准规范, 一般通过各种框架进行实现
  • 特点: 基于注解来定义API接口
  • 框架: Jersey RESTEasy ApacheCXF

-- Jersey --

基础

  • 概念: Jersey时JAX-RS的官方参考实现框架
  • 运行: Jersey通常需要一个容器来运行(如Tomcat/Jetty)
  • 资源方法/类: JAX-RS中用于解析请求和响应的方法叫资源方法吗,资源方法所在的类叫资源类, 资源方法需要是公共方法 当用户访问了对应的URI时, 会自动创建对应资源类的实例, 然后调用该实例上的对应方法, 默认一个请求对应一个实例 创建资源类的实例时, Jersey会自动调用 参数最多的可用构造函数 来创建资源类
  • 依赖: Jersey2.x+Tomcat
    注: Jersey 2.x(及 JDK 8/Java EE 8)使用javax.ws.rs.*包名, Jersey3.x(及 JDK 17+/Jakarta EE 9/10/11)必须使用jakarta.ws.rs.*包名
-- 引入依赖(pom.xml) --
<dependencies>
    <!-- Jersey 容器核心 (基于 Servlet) -->
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
        <version>2.35</version>
    </dependency>
    <!-- JSON 支持 (Jackson/FastJSON等) - 必选,否则无法自动转 JSON -->
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.35</version>
    </dependency>
    <!-- 如果你需要手动注入 Dependency Injection -->
    <dependency>
        <groupId>org.glassfish.jersey.inject</groupId>
        <artifactId>jersey-hk2</artifactId>
        <version>2.35</version>
    </dependency>
</dependencies>

-- 配置入口(web.xml) --
<servlet>
    <servlet-name>JerseyWebApi</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <!-- 指定你的资源包路径,Jersey 会扫描这里的类 -->
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>com.example.myproject.resources</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>JerseyWebApi</servlet-name>
    <url-pattern>/api/*</url-pattern>
</servlet-mapping>

注解

资源类/方法注解

  • @Path("<路由>")
    作用: 定义资源的基础 URI 路径, 标注在资源类上(定义根路径)或资源方法上(定义子路径)
  • @Produces("<Content-Type>")
    作用: 标注在方法上, 指定其响应返回的MIME类型
  • @Consumes("<Content-Type>")
    作用: 标注在方法上, 指定其可以接受的请求体MIME类型
  • @GET/@POST/@PUT/@DELETE/@PATCH/@OPTIONS/@HEAD
    作用: 标注在方法上, 指定其可以接受的请求方法

参数注解

  • 使用地点:
    • 资源方法的形参: 当调用对应的资源方法时会自动传入对应值, 最常用
    • BeanParam类字段/Setter方法: 使用@BeanParam并触发时, 会自动传入BeanParam类中 并传入对应值
    • 资源类的字段: 当创建对应资源类时会自动将字段赋予对应值, 仅适用于非单例模式
    • 构造函数的形参: 会通过调用构造函数并传入对应值来创建资源类
    • 资源类的Setter方法: 当创建对应资源类后会自动调用并传入对应值
  • @PathParam("<参数名>")
    作用: 获取@Path中用{}定义的路径参数值
  • @QueryParam("<参数名>")
    作用: 获取URL查询参数值
  • @FormParam("<参数名>")
    作用: 获取HTML表单(application/x-www-form-urlencoded)提交的参数
  • @HeaderParam("<请求头>")
    作用: 获取请求头值
  • @CookieParam("<Cookie>")
    作用: 获取Cookie值
  • @BeanParam
    作用:

    • 将多个分散的请求参数封装到一个JavaBean中, 在JavaBean中使用各种参数注解
    • 当触发时 自动传入参数注解对应的值 并创建JavaBean实例, 然后将实例传入@BeanParam标注的参数,
    • 以防止在资源方法中要使用大量参数注解导致的参数列表冗杂 及减少多个资源方法需要使用的参数注解相同但仍需重复定义的情况 注: 使用的JavaBean通过 @BeanParam标注的参数的数据类型 来指定
  • @Context
    作用: 将JAX-RS的预定义对象注入到参数中

Context可注入对象

  • 注意: 以下若为Jersey 3.x, 则对应包名不为javax, 而是jakarta
  • UriInfo接口
    • 特点: javax.ws.rs.core.UriInfo 作用: 提供有关当前HTTP请求的URI的丰富信息
-- 实例方法 --
= 路径信息 =
URI getAbsolutePath()
作用:获取请求的绝对路径(不包含查询参数,即 协议+host:port+ContextPath+ServletPath+ResourcePath),
例:例如http://localhost:8080/shop-app/rest/products/iphone15

URI getBaseUri()
作用:获取应用程序的基础URI(即 协议+host:port+ContextPath+ServletPath)
例:例如http://localhost:8080/shop-app/rest/

String getPath()
作用:获取资源路径(@Path匹配的部分),
例:例如products/iphone15

= 参数获取 =
MultivaluedMap<String, String> getPathParameters()
作用:获取所有的路径参数(即@Path中{}部分)的Map集合
注:MultivaluedMap允许一个Key对应多个Value

MultivaluedMap<String, String> getQueryParameters()
作用:获取所有的查询参数(即URI中?后面的部分)的Map集合

= 构造器 =
UriBuilder getAbsolutePathBuilder()
作用:获取一个以当前绝对路径为基础的UriBuilder,用于构建新的URI
  • HttpHeaders接口
    • 特点: javax.ws.rs.core.HttpHeaders
    • 作用: 提供对HTTP请求头信息的访问, 解析所有的Header和Cookie
-- 实例方法 --
= Header获取 =
List<String> getRequestHeader(String name)
作用:获取指定名称的Header值列表(HTTP协议允许同名Header)

String getHeaderString(String name)
作用:获取指定名称的Header值,如果存在多个值,则以逗号分隔返回一个字符串

MultivaluedMap<String, String> getRequestHeaders()
作用:获取请求中所有Header的只读Map视图

MediaType getMediaType()
作用:获取请求体的内容类型(Content-Type),若未指定则返回null

List<MediaType> getAcceptableMediaTypes()
作用:获取客户端可接受的媒体类型列表(Accept Header),并按质量因子(q-value)排序

= Cookie获取 =
Map<String, Cookie> getCookies()
作用:获取请求中携带的所有Cookie的Map集合,Key为Cookie名称
  • SecurityContext接口
    • 特点: javax.ws.rs.core.SecurityContext
    • 作用: 提供请求的安全上下文信息, 用于访问控制和身份验证状态检查
-- 实例方法 --
Principal getUserPrincipal()
作用:获取当前经过身份验证的用户主体(Principal对象),若未认证通常返回null

boolean isUserInRole(String role)
作用:判断当前用户是否具备指定的角色(role),常用于基于角色的权限控制

boolean isSecure()
作用:判断当前请求是否通过安全通道(如HTTPS)传输

String getAuthenticationScheme()
作用:获取用于保护资源的认证方案名称(如 "BASIC", "DIGEST", "FORM" 等)
  • HttpServletRequest 接口
    • 特点: javax.servlet.http.HttpServletRequest
    • 作用: 提供对底层 HTTP 请求的完整控制
    • 注意: 仅当 JAX-RS 运行在Servlet容器(如Tomcat, Jetty)时可用, 纯Netty或其他非Servlet环境可能无法注入
-- 实例方法 --
= 网络信息 =
String getRemoteAddr()
作用:获取发送请求的客户端IP地址

String getMethod()
作用:获取HTTP动作名称(GET, POST等)

= 会话管理 =
HttpSession getSession()
作用:获取当前请求关联的Session对象,若不存在则创建

HttpSession getSession(boolean create)
作用:获取当前Session, create为false时若不存在则返回null

= 输入流 =
ServletInputStream getInputStream()
作用:获取原始的请求体二进制流(注意:可能与JAX-RS的Entity读取冲突,慎用)
  • HttpServletResponse 接口
    • 特点: javax.servlet.http.HttpServletResponse (Servlet API 标准)
    • 作用: 提供对底层 HTTP 响应的完整控制
-- 实例方法 --
= 状态与头 =
void setStatus(int sc)
作用:设置HTTP响应状态码

void addHeader(String name, String value)
作用:添加响应头(允许同名)

void setHeader(String name, String value)
作用:设置响应头(覆盖同名)

= 输出 =
PrintWriter getWriter()
作用:获取字符输出流,用于向客户端发送文本响应

void sendRedirect(String location)
作用:发送临时重定向响应到指定地址
  • Application 类
    • 特点: javax.ws.rs.core.Application
    • 作用: JAX-RS 应用程序的配置根类, 用于定义应用包含哪些组件(资源类、Provider)
-- 实例方法 --
Set<Class<?>> getClasses()
作用:返回一组根资源类和Provider类的Class对象,运行时将扫描这些类

Set<Object> getSingletons()
作用:返回一组单例的资源对象或Provider对象(由应用自己实例化),运行时将直接使用这些实例

Map<String, Object> getProperties()
作用:获取应用程序的自定义配置属性Map
  • Providers 接口
    • 特点: javax.ws.rs.ext.Providers
    • 作用: 运行时查找辅助接口, 用于动态检索已注册的MessageBodyReaderMessageBodyWriterExceptionMapperContextResolver
-- 实例方法 --
<T> MessageBodyReader<T> getMessageBodyReader(Class<T> type, Type genericType, Annotation[] annotations, MediaType mediaType)
作用:查找适用于指定类型和媒体类型的消息体读取器(将请求体转为Java对象)

<T> MessageBodyWriter<T> getMessageBodyWriter(Class<T> type, Type genericType, Annotation[] annotations, MediaType mediaType)
作用:查找适用于指定类型和媒体类型的消息体写入器(将Java对象转为响应体)

<T extends Throwable> ExceptionMapper<T> getExceptionMapper(Class<T> type)
作用:查找能够处理指定异常类型的异常映射器
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇