JBoss AS 5.1.0 GA resteasy 应用程序 - 在每个请求上强制登录

Posted

技术标签:

【中文标题】JBoss AS 5.1.0 GA resteasy 应用程序 - 在每个请求上强制登录【英文标题】:JBoss AS 5.1.0 GA resteasy application - force login on every request 【发布时间】:2016-11-25 06:17:06 【问题描述】:

我正在使用带有 JBoss AS 5.1.0 GA 的 Resteasy 3.0.11.Final。我有一个已定义的 REST Web 服务。整个服务通过 BASIC 身份验证和自定义安全域进行保护。当我使用 Postman 为用户 A 发送带有 BASIC 身份验证的请求(#1)时,JBoss AS 为用户调用登录模块,然后调用本地 ejb(使用初始上下文查找)方法与调用者主体 A。在我为用户 B 发送另一个带有 BASIC 身份验证的请求(#2)之后,在这种情况下,JBoss AS 不会调用登录模块并使用调用者主体 A 调用本地 ejb 方法再次强>。一段时间后,向用户 B 发送请求会产生所需的结果(使用调用方主体 B 的本地 ejb 方法调用)。我不确定是什么导致了问题,Resteasy 服务配置/会话处理或负责登录模块的 JBoss AS 安全域配置(主题超时?调用方法后缺少注销?)?基本上我想配置 Resteasy 来强制一个新的会话与一个新的登录模块调用为每个休息请求的本地 ejb 方法调用。

web.xml:

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>my-app</display-name>
  <context-param>
    <param-name>resteasy.providers</param-name>
    <param-value>org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider,com.mycompany.infrastructure.ExceptionMapper</param-value>
  </context-param>
  <context-param>
    <param-name>resteasy.resources</param-name>
    <param-value>com.mycompany.resource.Resource</param-value>
  </context-param>
  <listener>
    <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
  </listener>
  <servlet>
    <servlet-name>my-app-resteasy-servlet</servlet-name>
    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
    <init-param>
      <param-name>javax.ws.rs.core.Application</param-name>
      <param-value>com.mycompany.application.Application</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>my-app-resteasy-servlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>my-app-resteasy-servlet</web-resource-name>
      <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>User</role-name>
    </auth-constraint>
  </security-constraint>
  <login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>MyRealm</realm-name>
  </login-config>
  <security-role>
    <role-name>User</role-name>
  </security-role>
</web-app>

jboss-web.xml

<jboss-web>
    <context-root>/path</context-root>
    <security-domain>java:/jaas/MyRealm</security-domain>
</jboss-web>

beans.xml

<beans
       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/beans_1_1.xsd"
       bean-discovery-mode="all">
</beans>

MyRealm 的登录配置.xml

<application-policy name="MyRealm">
     <authentication>
      <login-module code="com.mycompany.security.UsernamePasswordLoginModuleImpl"
        flag="required">
        <module-option name="password-stacking">useFirstPass</module-option>
      </login-module>
   </authentication>
</application-policy>

资源.java

@Path("/resource")
@Stateless
public class Resource 

    @POST
    @Path("/execute")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public ResponseDTO execute(RequestDTO dto) 
        try 
            // code
         catch (Exception exception) 
            // handle
        
    

【问题讨论】:

【参考方案1】:

我找到了一个非常粗略的解决方案:

资源.java:

@Path("/resource")
@Stateless
public class Resource 

    @POST
    @Path("/execute")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public ResponseDTO execute(RequestDTO dto, @Context HttpServletRequest request) 
        try 
            // code
         catch (Exception exception) 
            // handle
         finally 
            if (request != null) 
                request.getSession().invalidate();
            
        
    

或者相同的结果,不同的实现(显然没有在资源中的每个方法中重复相同的代码):

SessionInvalidatorFilter.java

public class SessionInvalidatorFilter implements ContainerResponseFilter 
    @Context
    private HttpServletRequest request;

    public void filter(ContainerRequestContext requestCtx, ContainerResponseContext responseCtx) throws IOException 
        if ((request != null) && (request.getSession() != null)) 
            request.getSession().invalidate();
        
    

web.xml

<context-param>
    <param-name>resteasy.providers</param-name>
    <param-value>com.mycompany.infrastructure.filter.SessionInvalidatorFilter</param-value>
</context-param>

【讨论】:

以上是关于JBoss AS 5.1.0 GA resteasy 应用程序 - 在每个请求上强制登录的主要内容,如果未能解决你的问题,请参考以下文章

jboss-5.1.0.GA启动返回java.lang.IllegalArgumentException

如何使用 Cargo maven 插件远程部署 EAR 到 JBoss 5.1.0.GA?

运行JBoss 5.1.0 GA时出现Error installing to Instantiated:name=AttachmentStore state=Described错误的解决办法

Jboss AS 7 与 JDK8 一起使用

如何检查和设置 JBoss 5 的 URL 和端口号?

修改Jboss服务端口及国际化资源文件设置