私は、作成、更新、削除などのさまざまなメソッドを保持するEmployeeEndpointを構築しました。この質問を簡略化するために、私はcreateメソッドを使用しました。Javaカスタムアノテーションは考慮されません
スケーラブルなアプリケーションが必要なので、基本メソッドを保持するインタフェースを構築しました。インターフェース内で、メソッドをJAX-RS-Annotationsで注釈を付けることができます。それらは継承されるので、私はEmployeeEndpoint内のインターフェースメソッドをオーバーライドするだけです。
インタフェース
public interface RESTCollection<T> {
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public T create(T entity) throws Exception;
}
エンドポイント
@Stateless
@Path(“employee“)
public class EmployeeEndpoint implements RESTCollection<Employee> {
@Override
public Employee create(Employee employee) throws Exception {
return this.createEmployee(employee);
}
}
は、上記の例では、正常に動作します。私はカスタムアノテーションを追加したい場合は私が行うことができます。
ソリューション1
public interface RESTCollection<T> {
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Permissions(Role.Admin)
public T create(T entity) throws Exception;
}
または
ソリューション2
@Stateless
@Path(“employee“)
public class EmployeeEndpoint implements RESTCollection<Employee> {
@Override
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Permissions(Role.Admin)
public Employee create(Employee employee) throws Exception {
return this.createEmployee(employee);
}
}
しかしソリューション ISN」すべてのエンティティを作成できるわけではないので、良いアイデアです管理者が管理します。そしてソリューションでは私はスケーラビリティの利点を失うし、注釈のコードは少なくなっています。だから、最良の方法は次のようになります。
ソリューション3
@Stateless
@Path(“employee“)
public class EmployeeEndpoint implements RESTCollection<Employee> {
@Override
@Permissions(Role.Admin)
public Employee create(Employee employee) throws Exception {
return this.createEmployee(employee);
}
}
しかし、私はフィルタと呼ばれるJAX-RS」ContainerRequestFilterインターフェイスメソッド内で権限アノテーションをキャッチしたときに、今、私は私null
の値を取得します理解していない。注釈
@NameBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Permissions {
Role[] value() default {};
}
列挙
public enum Role {
Admin,
User
}
@Context
private ResourceInfo resourceInfo;
resourceInfo.getResourceMethod().getAnnotation(Permissions.class) // is null
は、どのような方法で解決して行くことも可能です私は同じ利点を持っているまたは異なるアプローチ?
UPDATE
理由は、私はあなたに私のAuthorizationFilterが表示されます掲載のコードではないようですので。したがって、私はthisの投稿を使用しました。
AuthorizationFilter
@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");
}
}
}
「権限はまったく考慮されていません」とはどういう意味ですか? –
JAX-RSのContainerRequestFilterインターフェイスメソッドのPermissions-Annotationをfilterという名前で捕捉すると、 'null'という値が得られます。 – Nadine
ちょうどテストされ、それは正常に動作します。あなたはNullPointerExceptionを取得していますか、またはnullの呼び出しの結果ですか? –