Java 是否向HTTP安全API提供基于注释的配置?
我有一个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
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(路径名);
}
}
}
}
}
}
}
}
}
我的问题是,与上面的插图类似,构建配置的最佳方式是什么。我使用反射来读取传递给注释的参数值。但根据当前的代码,它看起来相当沉重和糟糕,因为在应用配置后,我必须使用与返回对象相同类型的对象对其进行初始化,以便可以应用下一个配置并继续该过程。有没有更好的方法?