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
相关产品推荐
相关产品推荐

