通过JWT验证所有OpenLiberty端点



我有一个设置,这样用@RolesAllowed注释的端点既需要身份验证又需要授权。但是,那些没有任何特定注释的端点甚至不需要身份验证。如何配置服务器,使所有url在默认情况下都受到保护,至少需要一个登录用户?

UPDATE到目前为止还没有简单的解决方案。仍在寻找更简单的方法。

你可以这样做,但它需要修改server.xml和所有jax-rs资源类:

server.xml中提供角色绑定(类似可以通过ibm-web-bnd.xml文件完成):

<application-bnd>
<!-- role from JWT claim. The access-id must have your claim issuer. In my case it was mp.jwt.verify.issuer=http://openliberty.io   --> 
<security-role name="admin">
<group access-id="group:http://openliberty.io/admin" id="group1" name="admin" />
</security-role>
<!-- role for authenticated users -->
<security-role name="auth-user">
<special-subject type="ALL_AUTHENTICATED_USERS" />
</security-role>
</application-bnd>

在资源类中,您需要为所有经过身份验证的人定义角色。我像这样在类的顶部定义它,因为这样可以保护所有没有显式定义@RolesAllowed的方法:

@RolesAllowed({ "auth-user" })
public class SystemResource {

注意:以下内容适用于使用Liberty的专有openIdConnectClient特性,但不适用于mpJWT。对于mpJWT,安全约束与mpJWT冲突。有针对OpenLiberty的问题,但在mpJWT进入雅加达安全之前,它不太可能得到解决。

要求对所有端点进行身份验证的最简单(但仍然不容易)的方法是在web.xml文件中设置安全约束:

<security-constraint>
<web-resource-collection>
<web-resource-name>ProtectAll</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<!-- repeat for PUT, POST, PATCH, etc -->
</web-resource-collection>
<auth-constraint>
<role-name>all-authenticated</role-name>
</auth-constraint>
</security-constraint>

然后正如@Gas提到的,您需要创建一个从Liberty的ALL_AUTHENTICATED_USERS特殊主题到all-authenticated角色名称的映射:

<application ..[snip]..>
<application-bnd>
<security-role name="all-authenticated">
<special-subject type="ALL_AUTHENTICATED_USERS" />
</security-role>
</application-bnd>
</application>

这两个配置的组合将告诉Liberty保护这个web模块中托管的所有url。

需要注意的一点是,这将保护/health,/metrics等可观察性端点。如果您的监视系统需要未经身份验证的访问,您可能希望添加一个额外的安全约束,将这些资源分配给映射到Liberty的EVERYONE特殊主题的角色。

最后,我选择了以下过滤器,我认为它比目前提出的其他选择更简单、更明确:

import jakarta.inject.Inject;
import jakarta.ws.rs.NotAuthorizedException;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerRequestFilter;
import jakarta.ws.rs.ext.Provider;
import org.eclipse.microprofile.jwt.JsonWebToken;
@Provider
public class AuthFilter implements ContainerRequestFilter {
@Inject
private JsonWebToken jwt;
@Override
public void filter(ContainerRequestContext req) {
var isAuthenticated = jwt != null && jwt.getName() != null && jwt.getGroups() != null;
if (!isAuthenticated) {
throw new NotAuthorizedException("Authentication required.");
}
}
}

最新更新