如何在tomee中检查url是否受保护?

wljmcqd8  于 2021-06-30  发布在  Java
关注(0)|答案(0)|浏览(183)

我试图在tomee8中实现基于jwt的身份验证(基于tomcat9)。我用org.glassfish。soteria:jakarta.security.enterprise:1.0.1作为雅加达安全的一个实现。遵循本教程https://github.com/payara/payara-examples/blob/master/javaee/security-jwt-example/src/main/java/fish/payara/examples/security/jwtauthenticationmechanism.java java类如下所示:

@RequestScoped 
public class JWTAuthenticationMechanism implements HttpAuthenticationMechanism 

private static final Logger LOGGER = Logger.getLogger(JWTAuthenticationMechanism.class.getName());

/**
 * Access to the
 * IdentityStore(AuthenticationIdentityStore,AuthorizationIdentityStore) is
 * abstracted by the IdentityStoreHandler to allow for multiple identity
 * stores to logically act as a single IdentityStore
 */
@Inject
private IdentityStoreHandler identityStoreHandler;

@Inject
private TokenProvider tokenProvider;

@Override
public AuthenticationStatus validateRequest(HttpServletRequest request, HttpServletResponse response, HttpMessageContext context) {

    LOGGER.log(Level.INFO, "validateRequest: {0}", request.getRequestURI());
    // Get the (caller) name and password from the request
    // NOTE: This is for the smallest possible example only. In practice
    // putting the password in a request query parameter is highly insecure
    String name = request.getParameter("name");
    String password = request.getParameter("password");
    String token = extractToken(context);

    if (name != null && password != null) {
        LOGGER.log(Level.INFO, "credentials : {0}, {1}", new String[]{name, password});
        // validation of the credential using the identity store
        CredentialValidationResult result = identityStoreHandler.validate(new UsernamePasswordCredential(name, password));
        if (result.getStatus() == CredentialValidationResult.Status.VALID) {
            // Communicate the details of the authenticated user to the container and return SUCCESS.
            return createToken(result, context);
        }
        // if the authentication failed, we return the unauthorized status in the http response
        return context.responseUnauthorized();
    } else if (token != null) {
        // validation of the jwt credential
        return validateToken(token, context);
    } else if (context.isProtected()) {
        // A protected resource is a resource for which a constraint has been defined.
        // if there are no credentials and the resource is protected, we response with unauthorized status
        return context.responseUnauthorized();
    }
    // there are no credentials AND the resource is not protected, 
    // SO Instructs the container to "do nothing"
    return context.doNothing();
}
...

用户发送带有用户名和密码的登录请求,identitystorehandler验证它。然后我们生成jwt令牌并将其发送回去。前端将它附加到下一个请求。
这很管用。
validaterequest()为每个请求触发,无论是受保护的还是未受保护的。据我所知,它来自规范,是一个理想的行为。
现在,如果令牌过期,并且用户将请求发送到不受保护的url,它将被拒绝,因为令牌存在并且无效。
我想首先检查url是否受保护,并且仅当它受保护时才检查令牌的存在性和有效性。但是((httpmessagecontext)context.isprotected())总是返回false。在控制器中,受保护的方法使用@rolesallowed和@permitall注解进行注解。我也尝试了基于web.xml的约束,但是isprotected()仍然是错误的。
为什么总是假的?
更新
我错误地认为基于注解的安全性和via描述符(web.xml)是可以互换的。如果web.xml不包含任何安全约束-未经身份验证的用户对@rolesallowed资源的请求将被拒绝,并出现403错误,则对@permitall资源的请求将得到满足。这是一种奇怪的行为,既需要经过身份验证的用户,也应该被拒绝。
如果web.xml有auth constraint标记,那么context.isprotected()为该url模式返回true。
但对于带有@rolesallowed和@permitall注解的方法,如果这些方法中的路径与web.xml中的url模式不匹配,它仍然返回false。
根据这个https://www.ibm.com/support/knowledgecenter/sseqtp_8.5.5/com.ibm.websphere.base.doc/ae/twbs_jaxrs_impl_securejaxrs_annotations.html
带注解的约束是任何配置的安全约束之外的附加约束。在web容器运行时环境检查web.xml文件中配置的安全约束之后,jax-rs运行时环境检查带注解的约束。
这是否意味着基于容器的安全性(soteria)不会将带注解的方法视为受保护的方法?

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题