Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 自定义JAX-RS授权-在每个请求中使用JWT_Java_Security_Rest_Glassfish_Jax Rs - Fatal编程技术网

Java 自定义JAX-RS授权-在每个请求中使用JWT

Java 自定义JAX-RS授权-在每个请求中使用JWT,java,security,rest,glassfish,jax-rs,Java,Security,Rest,Glassfish,Jax Rs,我有一个JAX-RS服务,我希望我的所有用户都能访问我的服务,但只有那些有权查看结果的用户。基于角色的安全性、现有领域和atuhentication方法不符合我的要求 例如: 用户根据一个REST服务进行身份验证,我向他发送带有其ID的JWT令牌 用户请求其他资源,并在每个请求中发送带有其ID的JWT 我检查他的用户id(来自JWT),如果业务逻辑返回结果,我将返回结果,否则我将发送空的结果集或特定的HTTP状态 问题是:在某个单独的过滤器、安全上下文或每个REST方法实现中,我应该在哪里检查用

我有一个JAX-RS服务,我希望我的所有用户都能访问我的服务,但只有那些有权查看结果的用户。基于角色的安全性、现有领域和atuhentication方法不符合我的要求

例如:

  • 用户根据一个REST服务进行身份验证,我向他发送带有其ID的JWT令牌
  • 用户请求其他资源,并在每个请求中发送带有其ID的JWT
  • 我检查他的用户id(来自JWT),如果业务逻辑返回结果,我将返回结果,否则我将发送空的结果集或特定的HTTP状态
  • 问题是:在某个单独的过滤器、安全上下文或每个REST方法实现中,我应该在哪里检查用户ID?如何提供具有此ID的REST方法,在按ID过滤请求后,是否可以在每个方法中注入securityContext


    我使用的是GlassFish 4.1和Jersey JAX-RS实现。

    您可以在。在这里处理自定义安全特性是很常见的

    一些需要考虑的事情

  • 该类应使用注释,以便在其他过滤器(如果有)之前执行

  • 您应该使用过滤器内部的。我要做的是实现一个
    SecurityContext
    。你可以随心所欲地实现它

  • 下面是一个没有任何安全逻辑的简单示例

    @Provider
    @Priority(Priorities.AUTHENTICATION)
    public class SecurityFilter implements ContainerRequestFilter {
    
        @Override
        public void filter(ContainerRequestContext requestContext) throws IOException {
            SecurityContext originalContext = requestContext.getSecurityContext();
            Set<String> roles = new HashSet<>();
            roles.add("ADMIN");
            Authorizer authorizer = new Authorizer(roles, "admin", 
                                                   originalContext.isSecure());
            requestContext.setSecurityContext(authorizer);
        }
    
        public static class Authorizer implements SecurityContext {
    
            Set<String> roles;
            String username;
            boolean isSecure;
            public Authorizer(Set<String> roles, final String username, 
                                                 boolean isSecure) {
                this.roles = roles;
                this.username = username;
                this.isSecure = isSecure;
            }
    
            @Override
            public Principal getUserPrincipal() {
                return new User(username);
            }
    
            @Override
            public boolean isUserInRole(String role) {
                return roles.contains(role);
            }
    
            @Override
            public boolean isSecure() {
                return isSecure;
            }
    
            @Override
            public String getAuthenticationScheme() {
                return "Your Scheme";
            } 
        } 
    
        public static class User implements Principal {
            String name;
    
            public User(String name) {
                this.name = name;
            }
    
            @Override
            public String getName() { return name; }   
        }
    }
    
    需要注意的几件事:

    • SecurityContext
      被注入到方法中
    • 我们获取
      主体
      并将其转换为
      用户
      。因此,实际上您可以创建实现
      主体的任何类,并根据需要使用此对象
    • 允许使用
      @roles
      注释。对于Jersey,有一个过滤器通过在
      @RolesAllowed
      注释中传递每个值来检查
      SecurityContext.isUserInRole
      ,以查看是否允许用户访问资源

      要在Jersey中启用此功能,我们需要注册
      RolesAllowedDynamicFeature

      @ApplicationPath("/api")
      public class AppConfig extends ResourceConfig {
      
          public AppConfig() {
              packages("packages.to.scan");
              register(RolesAllowedDynamicFeature.class);
          }
      }
      

    我正在搜索一个独立于Jersey且适用于Wildfly的解决方案->找到了这个github示例实现:

    它应该给你一个提示,如何解决它干净

    实现一个JWTRequestFilter,它实现ContainerRequestFilter

    如上所述,在web.xml中将过滤器注册为resteasy提供者:

    
    自定义JAX-RS提供程序
    resteasy.providers
    com.sixturtle.jwt.JWTRequestFilter
    resteasy.role.based.security
    真的
    
    谢谢您的回复。我想我可以使用ContainerRequestFilter,但我不需要角色和SecurityContext来满足我的需求。仅仅使用servlet过滤器是否太简单了,对于对REST资源的每个请求,我都会对之前发送的JWT头进行解组,从中提取用户信息并将其传递给服务方法,以确定每个方法中用户的授权级别?这似乎是一个简单实用的解决方案,应该可以工作。在servlet过滤器中可以做的事情,在ContainerRequestFilter中也可以做。但对于后者,您可以访问Jersey应用程序库,我通过将JWT数据注入用户主体,然后在我拥有的每个REST方法中从注入的SecurityContext获取数据,实现了您的解决方案。请允许我投票并接受您的帮助,好的,先生。在Wildfly 10中如何做?您如何创建“我的方案”,这是一组角色名称吗?
    @ApplicationPath("/api")
    public class AppConfig extends ResourceConfig {
    
        public AppConfig() {
            packages("packages.to.scan");
            register(RolesAllowedDynamicFeature.class);
        }
    }