java - 使用全局方法安全,拒绝访问错误作为 HTTP 500 错误返回

标签 java spring security methods annotations

我正在尝试使用 Spring Security Annotations 来确保安全,而不是在 XML 中定义规则。它似乎有效,但是当我遇到访问被拒绝错误时,我返回了 500 的 HTTP 状态代码。我在我的 tomcat 日志文件中没有看到任何异常。当执行到达我的 AuthenticationEntryPoint 时,响应被提交。

如果我恢复使用 XML 中的规则并收到拒绝访问错误,我将返回 401 的 HTTP 状态代码。

方法用@PreAuthorize注解

@GET
@Produces(MediaType.APPLICATION_JSON)
@PreAuthorize("hasRole('user')")
public String list() throws IOException 

这是我的XML(之前的XML规则被注释掉了)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:security="http://www.springframework.org/schema/security"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd">

    <security:debug/>

    <security:global-method-security pre-post-annotations="enabled"/>

    <security:authentication-manager id="authenticationManager">
        <security:authentication-provider user-service-ref="userDao">
            <security:password-encoder ref="passwordEncoder"/>
        </security:authentication-provider>
    </security:authentication-manager>

    <security:http
            realm="Protected API"
            use-expressions="true"
            auto-config="false"
            create-session="stateless"
            entry-point-ref="unauthorizedEntryPoint"
            authentication-manager-ref="authenticationManager">
        <security:access-denied-handler ref="accessDeniedHandler"/>
        <security:custom-filter ref="tokenAuthenticationProcessingFilter" position="FORM_LOGIN_FILTER"/>
        <security:custom-filter ref="tokenFilter" position="REMEMBER_ME_FILTER"/>
        <!--<security:intercept-url method="GET" pattern="/rest/news/**" access="hasRole('user')"/>-->
    </security:http>

</beans>

最佳答案

此问题与 Spring Security 无关。问题出在 Jersey 。

Jersey 正在拦截 AccessDeniedException 并将其作为 ServletException 重新抛出。

我必须做的是编写一个 ExceptionMapper。更多信息 https://jersey.java.net/documentation/latest/representations.html#d0e4866

@Provider
/**
 * AccessDeniedMapper is instantiated by Jersey directly through the "jersey.config.server.provider.packages" setting
 */
public class AccessDeniedMapper implements ExceptionMapper<AccessDeniedException> {
    @Override
    public Response toResponse(AccessDeniedException e) {
        return Response.status(401)
                .build();
    }
}

在启动时,Jersey 使用 jersey.config.server.provider.packages 属性扫描@Provider。来 self 的 web.xml

<!-- Map the REST Servlet to /rest/ -->
<servlet>
    <servlet-name>RestService</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <!--Every class inside of this package (com.unsubcentral.rest) will be available to Jersey-->
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>com.rince.rest</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>RestService</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

关于java - 使用全局方法安全,拒绝访问错误作为 HTTP 500 错误返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21636566/

相关文章:

java - httprequest.getsession 返回 null

security - Fiddler 和安全数据

java - 将数据库值检索到小程序中

java - 更改 EHCache 3 中各个条目的 TTL

java - 使用multipart将图像保存到java项目路径

android - 普通的 native Android 商店应用程序能否执行我自己生成的 JIT 代码,或者安全性是否会阻止这种情况?

java - 是否可以从现有的请求范围激活 session 范围和 session 范围?

java - 如果在 Scala 中 val 比 var 更受欢迎,Java 中的大多数对象引用是否应该标记为 final?

java - JDBC 数据源返回 NULL

java - 在 java.util.Properties$LineReader.readLine(Properties.java :418) for Spring Security) 处获取问题 java.lang.NullPointerException