Java 是否向HTTP安全API提供基于注释的配置?

Java 是否向HTTP安全API提供基于注释的配置?,java,reflection,configuration,enums,annotations,Java,Reflection,Configuration,Enums,Annotations,我有一个HTTP安全API,可以像这样配置安全性、身份验证和授权 SecurityConfigurationBuilder configurationBuilder = new SecurityConfigurationBuilder(); HttpSecurityBuilder builder = configurationBuilder.http(); builder .pathGroup("REST Service Group A") //returns

我有一个HTTP安全API,可以像这样配置安全性、身份验证和授权

SecurityConfigurationBuilder configurationBuilder = new SecurityConfigurationBuilder();
    HttpSecurityBuilder builder = configurationBuilder.http();

    builder
        .pathGroup("REST Service Group A")  //returns PathConfigurationBuilder
            .inbound() //returns InboundConfigurationBuilder
            .authc() //returns AuthenticationConfigurationBuilder
                .form() //returns FormAuthenticationConfigurationBuilder
                    .loginPage("/loginA.html")
                    .errorPage("/errorA.html")
            .authz()
                .allowedRoles("Role A")
        .pathGroup("REST Service Group B")
            .inbound()
            .authc()
                .form()
                    .loginPage("/loginB.html")
                    .errorPage("/errorB.html")
            .authz() //returns AuthorizationConfigurationBuilder
                .allowedRoles("Role B")
        .path("/rest/a/*", "REST Service Group A")  //returns PathConfigurationBuilder
        .path("/rest/b/*", "REST Service Group B");

HttpSecurityConfiguration configuration = builder.build().getHttpSecurityConfiguration();
注意:每个config方法返回一个类的对象。我只提到其中的几个

同样,我们也可以这样配置

SecurityConfigurationBuilder configurationBuilder = new SecurityConfigurationBuilder();
    HttpSecurityBuilder builder = configurationBuilder.http();

    builder
        .allPaths()
        .inbound()
        .authc()
        .form()
        .loginPage("/login.html")
        .errorPage("/error.html")
        .authz()
        .allowedRoles("Role A", "Role B")
        .allowedGroups("Group A", "Group B")
        .allowedRealms("Realm A", "Realm B")
        .expression("#{identity.isLoggedIn()}");

HttpSecurityConfiguration configuration = builder.build().getHttpSecurityConfiguration();
我现在需要使用枚举字段上的注释提供类似的配置。例如

//Declaration of @annotation_A depends on @annotation_B means that annotation_B can only    be declared if annotation_A is declared.
//Also, declaration of annotation_A must precede annotation_B

@PicketlinkHttpSecurity
public interface Security {

static enum Secure {

    //optional
    @Http

    //Any one of these,optional
    @Permissive
    @Restrictive

    //Any one of these, optional
    @AllPaths
    @Path(pathName = "Path URL Pattern")
    @Path(pathName = "Path URL Pattern", pathGroup = "Path Group")
    @PathGroup(pathGroup = "Path Group")

    //optional, declaration depends on (@allPaths, @path, @pathGroup) whichever is declared
    @Logout

    //optional, declaration depends on (@allPaths, @path, @pathGroup) whichever is declared
    @Inbound

    //optional, declarion depends on @inbound
    @Methods(methods = {"method_one", "method_two"}, ...)

    //optional, declaration depends on @inbound
    @Headers(headerName = "name", headerValues={"value1", "value2", ...}, requestedWith = "request_header")

    //optional, declaration depends on (@allPaths, @path, @pathGroup) whichever is delclared
    @Outbound

    //optional, declaration depends on @outbound
    @RedirectTo(redirect = "redirectPath")

    //optional, declaration depends on @inbound/@outbound
    @Authc

    //Any one of form,basic,digest,x509,token(//optional and declaration depends on @authc)
    @Form(restoreOriginalRequest = "yes_OR_no", loginPage="loginPage", errorPage="errorPage")
    @Basic(realmName="realmName")
    @Digest(realmName="realmName")
    @X509(subjectRegex="")
    @Token

    //optional, declaration depends on @inbound/@outbound
    @Authz
    //optional, any one or many of these, declaration depends on @authz
    @AllowedRoles(Roles={"Role_A", "Role_B", ...})
    @AllowedGroups(Goups={"Goup_A", "Goup_B", ...})
    @AllowedRealms(Realms={"Realm_A", "Realm_B", ...})
    @Expressions(expressions= {"expression1", "expression2", ...})

    SecurityConfigiration_One,

    //Other Security Configuration Annotations Decorated Enum Fields
  }

}
现在,我有一个类SecurityConfigExtension,它尝试读取这个枚举类并构建SecurityConfigurationBuilder此类中的一段不完整代码

public class SecurityConfigExtension implements Extension {

private transient final Logger log = Logger.getLogger(SecurityConfigExtension.class);

SecurityConfigurationBuilder builder = new SecurityConfigurationBuilder();
HttpSecurityBuilder httpSecurityBuilder = new HttpSecurityBuilder(builder);
PathConfigurationBuilder pathConfigurationBuilder;

public <T> void processAnnotatedType(@Observes ProcessAnnotatedType<T> event) {

    AnnotatedType<T> tp = event.getAnnotatedType();

    if (tp.isAnnotationPresent(PicketlinkHttpSecurity.class)) {

        if (!tp.getJavaClass().isInterface()) {
            log.warn("ViewConfig annotation should only be applied to interfaces, and [" + tp.getJavaClass()
                + "] is not an interface.");
        } else {
            for (Class<?> clazz : tp.getJavaClass().getClasses()) {
                for (Field enumm : clazz.getFields()) {
                    for (Annotation a : enumm.getAnnotations()) {
                        if (a.annotationType() == Http.class) {
                            this.httpSecurityBuilder = this.builder.http();
                        } else if (a.annotationType() == Permissive.class) {
                            this.httpSecurityBuilder = this.httpSecurityBuilder.permissive();
                        } else if (a.annotationType() == Restrictive.class) {
                            this.httpSecurityBuilder = this.httpSecurityBuilder.restrictive();
                        } else if (a.annotationType() == AllPaths.class) {
                            this.pathConfigurationBuilder = this.httpSecurityBuilder.allPaths();
                        } else if (a.annotationType() == Path.class) {
                            Path path = (Path) a;
                            String pathName = path.pathName();
                            String pathGroup = path.pathGroup();
                            if (pathName != null && !pathName.isEmpty() && pathGroup != null && !pathGroup.isEmpty()) {
                                this.pathConfigurationBuilder = this.httpSecurityBuilder.path(pathName, pathGroup);
                            } else {
                                this.pathConfigurationBuilder = this.httpSecurityBuilder.path(pathName);
                            }
                        }
                    }
                }
            }
        }
     }
  }
}
公共类SecurityConfigExtension实现扩展{
私有瞬态最终记录器日志=Logger.getLogger(SecurityConfigExtension.class);
SecurityConfiguration builder=新的SecurityConfiguration builder();
HttpSecurityBuilder HttpSecurityBuilder=新的HttpSecurityBuilder(生成器);
PathConfigurationBuilder PathConfigurationBuilder;
public void processAnnotatedType(@processAnnotatedType事件){
AnnotatedType tp=event.getAnnotatedType();
if(tp.isAnnotationPresent(PicketlinkHttpSecurity.class)){
如果(!tp.getJavaClass().isInterface()){
log.warn(“ViewConfig注释应该只应用于接口,[”+tp.getJavaClass()
+“]不是一个接口。”);
}否则{
对于(类clazz:tp.getJavaClass().getClasses()){
对于(字段enumm:clazz.getFields()){
对于(注释a:enumm.getAnnotations()){
if(a.annotationType()==Http.class){
this.httpSecurityBuilder=this.builder.http();
}else if(a.annotationType()==Permissive.class){
this.httpSecurityBuilder=this.httpSecurityBuilder.permissive();
}else if(a.annotationType()=限制性.class){
this.httpSecurityBuilder=this.httpSecurityBuilder.restrictive();
}else if(a.annotationType()==allpath.class){
this.pathConfigurationBuilder=this.httpSecurityBuilder.allpath();
}else if(a.annotationType()==Path.class){
路径路径=(路径)a;
字符串pathName=path.pathName();
字符串pathGroup=path.pathGroup();
if(pathName!=null&&!pathName.isEmpty()&&pathGroup!=null&&!pathGroup.isEmpty()){
this.pathConfigurationBuilder=this.httpSecurityBuilder.path(路径名,路径组);
}否则{
this.pathConfigurationBuilder=this.httpSecurityBuilder.path(路径名);
}
}
}
}
}
}
}
}
}
我的问题是,与上面的插图类似,构建配置的最佳方式是什么。我使用反射来读取传递给注释的参数值。但根据当前的代码,它看起来相当沉重和糟糕,因为在应用配置后,我必须使用与返回对象相同类型的对象对其进行初始化,以便可以应用下一个配置并继续该过程。有没有更好的方法?