java - WebSphere Liberty JSR-250 实现(RolesAllowed)

标签 java jax-rs websphere-liberty

为了使用 JSR-250 的安全注释(RolesAllowed、PermitAll、DenyAll):

  • 在 Jersey 中,您需要注册 RolesAllowedDynamicFeature 类。
  • 在 RESTeasy 中,您将使用 web.xml 配置:

    <context-param>
       <param-name>resteasy.role.based.security</param-name>
       <param-value>true</param-value>
    </context-param>
    

这两者都依赖于 SecurityContext.isUserInRole() 的实现,但 WebSphere Liberty Profile 似乎并不依赖。

我们如何让它在 WebSphere Liberty Profile (WLP) 中工作?

我使用了一个最小的例子:

  1. 使用@RolesAllowed创建资源类/方法:

    @Path("/rest")
    public class HelloWorld {
        @GET
        @RolesAllowed("ANYTHING")
        public Response hello() {
            return Response.ok("Hello World").build();
        }
    }
    
  2. 在过滤器中设置您的 SecurityContextImpl,重写 isUserInRole() 以始终返回 true;
  3. 为 JAX-RS 实现启用“基于角色的安全性”。 (Jersey 或 RESTeasy 等,如上所述。对于 WLP,我必须添加 appSecurity-2.0 功能)
  4. 您应该有一个可行的示例。

但是,即使 isUserInRole 返回 true,WebSphere Liberty Profile 也会返回 403 Forbidden。

有谁知道如何在 Liberty 中正确使用 @RolesAllowed 注释以及我可能会缺少什么?

代码

@ApplicationPath("/")
public class MyApplication extends Application {
    public MyApplication() {}
}

@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthFilter implements ContainerRequestFilter {
    @Override
    public void filter(ContainerRequestContext ctx) throws IOException {
        System.out.println("Setting SecurityContext..");
        ctx.setSecurityContext(new MySecurityContext("someuser", "anyrole"));
    }
}

public class MySecurityContext implements SecurityContext {

    private String user;
    private String role;

    public static class MyPrincipal implements Principal {
        private String name;

        public MyPrincipal(String name) { this.name = name; }
        @Override public String getName() { return name; }
    }

    public MySecurityContext(String user, String role) {
        this.user = user;
        this.role = role;
    }

    @Override public String getAuthenticationScheme() { return "BASIC"; }
    @Override public Principal getUserPrincipal() { return new MyPrincipal(user); }
    @Override public boolean isSecure() { return true; }

    @Override
    public boolean isUserInRole(String role) {
        return true;
    }
}

@Path("/test")
public class HelloWorld {
    @GET
    @RolesAllowed("doesntmatter")
    public Response hello() {
        return Response.ok("Hello World").build();
    }
}

pom.xml(仅依赖项)

<dependencies>
    <dependency>
        <groupId>javax.ws.rs</groupId>
        <artifactId>javax.ws.rs-api</artifactId>
        <version>2.0.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.annotation</groupId>
        <artifactId>javax.annotation-api</artifactId>
        <version>1.2</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

服务器.xml

代码在禁用 appSecurity 功能的情况下工作。启用后不起作用。

<server description="test">
    <featureManager>
        <feature>jaxrs-2.0</feature>
        <feature>localConnector-1.0</feature>
        <!--  <feature>appSecurity-2.0</feature> -->
    </featureManager>

    <webApplication id="RoleTest" location="RoleTest.war" name="RoleTest"/>
    <httpEndpoint httpPort="9081" httpsPort="9444" id="defaultHttpEndpoint"/>

    <!-- below lines are required when appSecurity feature is loaded -->
    <!--  
    <keyStore id="defaultKeyStore" password="{xor}Lz4sLCgwLTtu"/>
    <basicRegistry id="basic" realm="BasicRegistry"> 
        <user name="username" password="password" />
    </basicRegistry>
    -->
</server>

最佳答案

也许你可以尝试这个:

1个服务器.xml

<server description="test">
    <featureManager>
        <feature>jaxrs-2.0</feature>
        <feature>appSecurity-2.0</feature>
    </featureManager>

    <webApplication id="RoleTest" location="RoleTest.war" name="RoleTest">
        <application-bnd>
            <security-role name="ANYTHING">
                <user name="username" />
            </security-role>
            <security-role name="AuthenticationRole">
                <user name="username" />
            </security-role>
            <security-role name="AllAuthenticated">
                <special-subject type="ALL_AUTHENTICATED_USERS" />
            </security-role>
        </application-bnd>
    </webApplication>

    <httpEndpoint httpPort="9081" httpsPort="9444" id="defaultHttpEndpoint" />

    <basicRegistry id="basic" realm="BasicRegistry">
        <user name="username" password="password" />
    </basicRegistry>
</server>

2 Java 代码 使用 @RolesAllowed 创建 MyApplication 类和资源类/方法:

@ApplicationPath("/")
public class MyApplication extends Application {
    public MyApplication() {}
    public Set<Class<?>> getClasses(){
      Set<Class<?>> classes = new HashSet();
      classes.add(HelloWorld.class);

      return classes;
   }
}


@Path("/rest")
public class HelloWorld {
    @GET
    @RolesAllowed("ANYTHING")
    public Response hello() {
        return Response.ok("Hello World").build();
    }
}

3 web.xml

<web-app xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee web-app_3_0.xsd"
    version="3.0">

  <display-name>Test Application</display-name>
  <description>blablabla</description>

    <servlet>
        <servlet-name>MyApplication</servlet-name>
        <servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
        <init-param>
            <param-name>requestProcessorAttribute</param-name>
            <param-value>requestProcessorAttribute_webcontainer</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>com.xxx.MyApplication</servlet-name>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>SecurityContextApp</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>com.xxx.MyApplication</servlet-name>
        <url-pattern>/xxx/*</url-pattern>
    </servlet-mapping>


    <security-constraint id="SecurityConstraint_2">
        <web-resource-collection id="WebResourceCollection_2">
            <web-resource-name>com.xxx.MyApplication
            </web-resource-name>
            <description>Protection area for Rest Servlet</description>
            <url-pattern>/xxx/rest</url-pattern>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
        </web-resource-collection>
        <user-data-constraint id="UserDataConstraint_2">
            <transport-guarantee>NONE</transport-guarantee>
        </user-data-constraint>
        <auth-constraint id="AuthConstraint_2">
            <role-name>AuthenticationRole</role-name>
        </auth-constraint>
    </security-constraint>    


    <login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>test</realm-name>
    </login-config>
    <security-role id="SecurityRole_1">
        <description>blabla</description>
        <role-name>ANYTHING</role-name>
    </security-role>

    <security-role id="SecurityRole_2">
        <role-name>AuthenticationRole</role-name>
    </security-role>

</web-app>

还有什么问题可以给我留言。

关于java - WebSphere Liberty JSR-250 实现(RolesAllowed),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34686009/

相关文章:

java - 回文程序-字符串索引超出范围异常

java - 如何在关系数据库中保留大字符串字段的编辑历史

java - 我可以在 JAX-RS 中用一个实现来实现两个资源接口(interface)吗?

java - 在 Android 上使用 REST 服务,最简单的方法?

jakarta-ee - Resteasy @FormParam 总是返回 null

java - 使用 Liberty 配置文件配置 log4jdbc-log4j2

java - 数组索引越界

java - 在 selenium 中输入 iframe

java - 从 server.xml 按名称读取变量

ssl - 如何在 Open Liberty 上启用 TLSv1.2 目前它说已为 TLSV1 启用