You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GlassFish 4.1.2中Jersey 2.2的PUT/DELETE请求403错误求助

解决GlassFish+Jersey环境下PUT/DELETE请求403 Forbidden问题

看起来你遇到的PUT/DELETE请求返回403的问题,在GlassFish结合Jersey开发REST服务的场景里很常见,核心原因通常是CSRF防护拦截或者安全约束配置不全,下面是几个针对性的解决步骤:

1. 临时禁用GlassFish的CSRF防护(测试环境快速验证)

GlassFish在启用FORM认证(你的web.xml里配置了<login-config>使用FORM认证)后,默认会拦截PUT/DELETE这类非安全HTTP方法,要求请求携带CSRF令牌。如果是测试环境,可以先禁用这个防护来验证:

方式一:通过GlassFish管理控制台

  • 打开GlassFish管理后台(默认地址:http://localhost:4848)
  • 依次进入 Configurations > server-config > Security > CSRF Protection
  • 将Enabled选项改为false,保存后重启GlassFish服务器

方式二:通过web.xml配置

在你的web.xml中添加以下上下文参数:

<context-param>
    <param-name>com.sun.faces.enableCrossSiteProtection</param-name>
    <param-value>false</param-value>
</context-param>

2. 为PUT/DELETE请求添加CSRF令牌(生产环境推荐)

如果需要保留CSRF防护(生产环境必须),则需要在请求中携带CSRF令牌:

  • 首先在前端页面(如果是JSF页面)获取CSRF令牌:
<script type="text/javascript">
    const csrfToken = '#{request.session.getAttribute("com.sun.faces.csrf.token")}';
</script>
  • 发送PUT/DELETE请求时,添加X-CSRF-Token请求头:
// 示例:用fetch发送DELETE请求
fetch('/your-rest-path/remove/123', {
    method: 'DELETE',
    headers: {
        'X-CSRF-Token': csrfToken,
        'Content-Type': 'application/json'
    }
});

3. 完善web.xml的安全约束配置

你的web.xml中定义了<login-config>和<security-role>,但缺少对应的<security-constraint>来授权PUT/DELETE方法访问REST资源。如果你的REST服务需要认证用户访问,添加以下配置:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>REST API Access</web-resource-name>
        <url-pattern>/api/*</url-pattern> <!-- 替换为你的Jersey服务基础路径 -->
        <http-method>GET</http-method>
        <http-method>POST</http-method>
        <http-method>PUT</http-method>
        <http-method>DELETE</http-method>
    </web-resource-collection>
    <auth-constraint>
        <role-name>admin</role-name> <!-- 对应你定义的安全角色 -->
    </auth-constraint>
</security-constraint>

注意:/api/*需要替换为你的Jersey服务实际的基础路径(比如你的REST应用类用@ApplicationPath("/api")注解,就用这个路径)。

4. 确认Jersey的Servlet映射配置

虽然你的GET/POST请求能正常工作,但还是要确认Jersey的配置是否完整:
如果是使用注解式配置,你的REST应用类应该有@ApplicationPath注解:

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/api") // 匹配你的REST请求路径前缀
public class RestApplication extends Application {
    // 无需额外代码,Jersey会自动扫描包下的REST资源
}

如果是使用web.xml配置,需要添加Jersey的Servlet定义:

<servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>com.yourpackage.rest</param-value> <!-- 替换为你的REST类所在包 -->
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/api/*</url-pattern>
</servlet-mapping>

5. 检查GlassFish安全域的用户角色映射

你的login-config使用了admin-realm,需要确认该安全域下的用户是否被分配了admin角色:

  • 进入GlassFish管理控制台 Security > Realms > admin-realm
  • 查看用户列表,确保测试用户的角色包含admin

内容的提问来源于stack exchange,提问作者ack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:18:46