【问题标题】:spring security session throws an error when instantiatedspring security session 实例化时抛出错误
【发布时间】:2014-04-12 14:17:22
【问题描述】:

我正在创建的 Web 应用程序中使用 Spring 安全性,但在使用会话时遇到问题。

我登录后一切正常,但当我尝试使用会话时,它总是抛出错误。

当此代码中的第六行被调用时:

@POST
@Path("PostUserData/{userId}")
@Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8")
public final Response postUserData(@PathParam("userId") String userId, String input){
    Response response;
    ServletRequestAttributes attr = (ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
    HttpSession session= attr.getRequest().getSession(true); // true == allow create

    response = Response.created(null).build();
    return response;
}

这个错误来了:

java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
    at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)

我正在遵循http://www.baeldung.com/spring-security-session 的指示。

在我的安全应用程序上下文 xml 文件中重要的是:

<http pattern="/**" use-expressions="true" create-session="always">
    <intercept-url pattern="/**" access="permitAll" />
    <form-login
            username-parameter="username"
            password-parameter="password" login-processing-url="/login"
            login-page='/login.jsp'
            default-target-url='/View/Login/SelectUser.html'
            always-use-default-target='true'
            authentication-failure-url="/login.jsp"/>
    <logout logout-url="/logout/" logout-success-url="/" />
    <session-management invalid-session-url="/">
        <concurrency-control expired-url="/" max-sessions="2" />
    </session-management>
</http>

我已经在我的 web.xml 中添加了

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <welcome-file-list>
        <welcome-file>/</welcome-file>
    </welcome-file-list>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/security-app-context.xml
        </param-value>
    </context-param>

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
        <welcome-file>login.html</welcome-file>
        <welcome-file>login.htm</welcome-file>
    </welcome-file-list>

    <listener>
        <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
    </listener>

</web-app>

有人知道可能出了什么问题吗?我可能需要实例化会话或其他东西吗?

【问题讨论】:

  • web.xml中有更多的Spring配置吗?此外,您在所有 URL:s 上使用 permitAll 的事实似乎是错误的。
  • 我在问题中添加了我的整个 web.xml,我只是将它作为 permitAll,而我正在让它全部工作,将来不会像那样:)
  • 错误信息暗示你不能在没有DispatcherServlet的情况下使用ServletRequestAttributes,但是你的web.xml中没有DispatcherServlet。您在什么情况下尝试访问会话?
  • 在我登录之后,用户被重定向到一个页面,在该页面上,他单击了一个将 http POST 发布到 Web API 的表单。假设该 API 将一些参数放入会话。我更新了问题中的代码,显示了我是如何做到的。奇怪的是这曾经可以工作,所以我不认为这是我从未使用过的 DispatcherServlet。
  • 我正在使用 Jersey 创建 Web API,并且仅使用 Spring 安全性进行身份验证和授权。

标签: java spring session spring-security


【解决方案1】:

为什么不简单地将 HttpSession 添加为方法的参数?

像这样:

@POST
@Path("PostUserData/{userId}")
@Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8")
public final Response postUserData(@PathParam("userId") String userId, 
        String input, HttpSession session){

    // Your method here
    return Response.created(null).build();
}

【讨论】:

  • 是的,这就是我所做的,我只是不知道您可以这样做并获得会话。如果你问我,那是一种魔法。但我所做的是将:“@Context HttpServletRequest request”作为参数和方法“HttpSession session = request.getSession();”
  • 这一点都不神奇,事实上,定义自己的自定义控制器参数非常容易。见docs.spring.io/spring/docs/4.0.2.RELEASE/…
猜你喜欢
  • 2019-10-13
  • 1970-01-01
  • 1970-01-01
  • 2018-10-04
  • 1970-01-01
  • 2015-06-11
  • 2019-10-15
  • 2021-03-14
  • 2014-03-22
相关资源
最近更新 更多