Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.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–;自定义批注赢得';不可考虑_Java_Interface_Annotations_Jax Rs - Fatal编程技术网

Java–;自定义批注赢得';不可考虑

Java–;自定义批注赢得';不可考虑,java,interface,annotations,jax-rs,Java,Interface,Annotations,Jax Rs,我构建了一个EmployeeEndpoint,它包含不同的方法,比如创建、更新、删除等等。为了简化这个问题,我只使用了create方法 因为我想要一个可伸缩的应用程序,所以我构建了一个包含基本方法的接口。在接口中,我现在可以使用JAX-RS注释对方法进行注释。因为它们将被继承,所以我只需要重写EmployeeEndpoint中的接口方法 接口 public interface RESTCollection<T> { @POST @Consumes(MediaType.

我构建了一个EmployeeEndpoint,它包含不同的方法,比如创建、更新、删除等等。为了简化这个问题,我只使用了create方法

因为我想要一个可伸缩的应用程序,所以我构建了一个包含基本方法的接口。在接口中,我现在可以使用JAX-RS注释对方法进行注释。因为它们将被继承,所以我只需要重写EmployeeEndpoint中的接口方法

接口

public interface RESTCollection<T> {
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public T create(T entity) throws Exception;
}
注释

@NameBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Permissions {
    Role[] value() default {};
}
枚举

public enum Role {
    Admin,
    User
}
是否有可能以任何方式使用解决方案3或其他我具有相同优势的方法

更新

因为原因似乎不是我发布的代码,我将向您展示我的授权过滤器。所以我用了post

授权过滤器

@Provider
@Priority(Priorities.AUTHORIZATION)
public class AuthorizationFilter implements ContainerRequestFilter {

    @Inject
    @AuthenticatedUser
    private User authenticatedUser;

    @Context
    private ResourceInfo resourceInfo;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {

        Class<?> resourceClass = resourceInfo.getResourceClass();
        List<Role> classRoles = extractRoles(resourceClass);

        Method resourceMethod = resourceInfo.getResourceMethod();
        List<Role> methodRoles = extractRoles(resourceMethod);

        try {

            if (methodRoles.isEmpty()) checkPermissions(classRoles, requestContext.getHeaderString(HttpHeaders.AUTHORIZATION));
            else checkPermissions(methodRoles, requestContext.getHeaderString(HttpHeaders.AUTHORIZATION));

        } catch (NotAuthorizedException e) {
            requestContext.abortWith(
                    Response.status(Response.Status.UNAUTHORIZED).build());
        } catch (Exception e) {
            requestContext.abortWith(
                    Response.status(Response.Status.FORBIDDEN).build());
        }
    }

    private List<Role> extractRoles(AnnotatedElement annotatedElement) {
        if (annotatedElement == null) return new ArrayList<Role>();
        else {
            Permissions perms = annotatedElement.getAnnotation(Permissions.class);
            if (perms == null) return new ArrayList<Role>();
            else {
                Role[] allowedRoles = perms.value();
                return Arrays.asList(allowedRoles);
            }
        }
    }

    private void checkPermissions(List<Role> allowedRoles, String authorizationHeader) throws NotAuthorizedException, Exception {
        if (!allowedRoles.isEmpty()) {
            if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer "))
                throw new NotAuthorizedException("Authorization header must be provided");
            else if (!allowedRoles.contains(this.authenticatedUser.getRole()))
                throw new Exception("User has no permissions");
        }
    }
}
@Provider
@优先级(优先级.授权)
公共类AuthorizationFilter实现ContainerRequestFilter{
@注入
@认证用户
私人用户认证用户;
@上下文
私有资源信息资源信息;
@凌驾
公共无效筛选器(ContainerRequestContext requestContext)引发IOException{
Class resourceClass=resourceInfo.getResourceClass();
List classRoles=extractRoles(resourceClass);
方法resourceMethod=resourceInfo.getResourceMethod();
List methodRoles=extractRoles(resourceMethod);
试一试{
if(methodRoles.isEmpty())检查权限(classRoles,requestContext.getHeaderString(HttpHeaders.AUTHORIZATION));
else检查权限(methodRoles、requestContext.getHeaderString(HttpHeaders.AUTHORIZATION));
}捕获(未经授权){
requestContext.abortWith(
Response.status(Response.status.UNAUTHORIZED.build());
}捕获(例外e){
requestContext.abortWith(
Response.status(Response.status.forbidded.build());
}
}
私有列表提取角色(注释删除注释删除){
if(annotatedElement==null)返回新的ArrayList();
否则{
Permissions perms=annotatedElement.getAnnotation(Permissions.class);
if(perms==null)返回新的ArrayList();
否则{
Role[]allowedRoles=perms.value();
返回array.asList(allowedRoles);
}
}
}
private void checkPermissions(列出allowedRoles、字符串授权标头)引发NotAuthorizedException、Exception{
如果(!allowedRoles.isEmpty()){
if(authorizationHeader==null | |!authorizationHeader.startsWith(“承载人”))
抛出新的NotAuthorizedException(“必须提供授权标头”);
如果(!allowedRoles.contains(this.authenticatedUser.getRole())包含,则为else
抛出新异常(“用户没有权限”);
}
}
}
您的代码看起来不错

我已经运行了一些测试,我能想到的唯一原因是,您在员工资源上使用的2种不同的
权限
类型
。(检查您的导入)

不确定您的
过滤器
代码,但这是我的,正在工作(请参阅导入):

另外,如果您想测试员工资源上注释的实际值:

....
import com.app.services.Permissions; // TODO change this with yours (the one on the filter being the same as this one)
....

@Permissions (Role.Admin)
@Override
public Employee create (Employee employee) throws Exception {
    Class<?> [] cArg    = new Class [1];
    cArg [0]            = Employee.class;

    Method method       = getClass ().getMethod ("create", cArg);
    Permissions perms   = method.getAnnotation (Permissions.class);

    System.out.println (EmployeeService.class.getSimpleName () + " --> Permissions: " + Arrays.toString (perms.value ()));

    return null;
}
。。。。
导入com.app.services.Permissions;//TODO将此更改为您的(过滤器上的与此相同)
....
@权限(Role.Admin)
@凌驾
公共雇员创建(雇员雇员)引发异常{
类别[]cArg=新类别[1];
cArg[0]=Employee.class;
方法Method=getClass().getMethod(“创建”,cArg);
Permissions perms=method.getAnnotation(Permissions.class);
System.out.println(EmployeeService.class.getSimpleName()+“-->权限:“+Arrays.toString(perms.value()));
返回null;
}
您的代码看起来不错

我已经运行了一些测试,我能想到的唯一原因是,您在员工资源上使用的2种不同的
权限
类型
。(检查您的导入)

不确定您的
过滤器
代码,但这是我的,正在工作(请参阅导入):

另外,如果您想测试员工资源上注释的实际值:

....
import com.app.services.Permissions; // TODO change this with yours (the one on the filter being the same as this one)
....

@Permissions (Role.Admin)
@Override
public Employee create (Employee employee) throws Exception {
    Class<?> [] cArg    = new Class [1];
    cArg [0]            = Employee.class;

    Method method       = getClass ().getMethod ("create", cArg);
    Permissions perms   = method.getAnnotation (Permissions.class);

    System.out.println (EmployeeService.class.getSimpleName () + " --> Permissions: " + Arrays.toString (perms.value ()));

    return null;
}
。。。。
导入com.app.services.Permissions;//TODO将此更改为您的(过滤器上的与此相同)
....
@权限(Role.Admin)
@凌驾
公共雇员创建(雇员雇员)引发异常{
类别[]cArg=新类别[1];
cArg[0]=Employee.class;
方法Method=getClass().getMethod(“创建”,cArg);
Permissions perms=method.getAnnotation(Permissions.class);
System.out.println(EmployeeService.class.getSimpleName()+“-->权限:“+Arrays.toString(perms.value()));
返回null;
}

你所说的“根本不考虑权限”是什么意思?当我在JAX-RS的ContainerRequestFilter接口方法filter中捕捉到权限注释时,我得到的值是
null
。刚刚测试过,效果很好。您得到的是NullPointerException还是调用的结果为null?调用的结果为null。您所说的“根本不考虑权限”是什么意思?当我在JAX-RS的ContainerRequestFilter接口方法filter中捕获到Permissions注释时,我得到了
null
。刚刚测试过,它工作正常。您得到的是NullPointerException还是调用的结果为null?调用的结果为null。我也这么认为,但这并不能解释解决方案1和2工作的原因。这是假设OP实际测试了1和2。谢谢你的回答!不是
@NameBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Permissions {
    Role[] value() default {};
}
public enum Role {
    Admin,
    User
}
@Provider
@Priority(Priorities.AUTHORIZATION)
public class AuthorizationFilter implements ContainerRequestFilter {

    @Inject
    @AuthenticatedUser
    private User authenticatedUser;

    @Context
    private ResourceInfo resourceInfo;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {

        Class<?> resourceClass = resourceInfo.getResourceClass();
        List<Role> classRoles = extractRoles(resourceClass);

        Method resourceMethod = resourceInfo.getResourceMethod();
        List<Role> methodRoles = extractRoles(resourceMethod);

        try {

            if (methodRoles.isEmpty()) checkPermissions(classRoles, requestContext.getHeaderString(HttpHeaders.AUTHORIZATION));
            else checkPermissions(methodRoles, requestContext.getHeaderString(HttpHeaders.AUTHORIZATION));

        } catch (NotAuthorizedException e) {
            requestContext.abortWith(
                    Response.status(Response.Status.UNAUTHORIZED).build());
        } catch (Exception e) {
            requestContext.abortWith(
                    Response.status(Response.Status.FORBIDDEN).build());
        }
    }

    private List<Role> extractRoles(AnnotatedElement annotatedElement) {
        if (annotatedElement == null) return new ArrayList<Role>();
        else {
            Permissions perms = annotatedElement.getAnnotation(Permissions.class);
            if (perms == null) return new ArrayList<Role>();
            else {
                Role[] allowedRoles = perms.value();
                return Arrays.asList(allowedRoles);
            }
        }
    }

    private void checkPermissions(List<Role> allowedRoles, String authorizationHeader) throws NotAuthorizedException, Exception {
        if (!allowedRoles.isEmpty()) {
            if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer "))
                throw new NotAuthorizedException("Authorization header must be provided");
            else if (!allowedRoles.contains(this.authenticatedUser.getRole()))
                throw new Exception("User has no permissions");
        }
    }
}
package com.app.filters; // TODO change this with yours

import java.io.IOException;
import java.util.Arrays;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.Context;

import com.app.services.Permissions; // TODO change this with yours

public class AuthorizationFilter implements ContainerRequestFilter {

    @Context
    ResourceInfo resourceInfo;

    @Override
    public void filter (ContainerRequestContext requestContext) throws IOException {
        Permissions perms   = resourceInfo.getResourceMethod ().getAnnotation (Permissions.class);

        System.out.println (getClass ().getSimpleName () + " --> Permissions: " + Arrays.toString (perms.value ())); // prints [Admin]
    }

}
....
import com.app.services.Permissions; // TODO change this with yours (the one on the filter being the same as this one)
....

@Permissions (Role.Admin)
@Override
public Employee create (Employee employee) throws Exception {
    Class<?> [] cArg    = new Class [1];
    cArg [0]            = Employee.class;

    Method method       = getClass ().getMethod ("create", cArg);
    Permissions perms   = method.getAnnotation (Permissions.class);

    System.out.println (EmployeeService.class.getSimpleName () + " --> Permissions: " + Arrays.toString (perms.value ()));

    return null;
}