我有一个spring boot应用程序,在应用程序启动期间,我尝试使用Javaassist注入Spring-Security Java配置。我从DB的值动态生成java配置。这是代码,
public class WarLock implements SpringApplicationRunListener {
private final SpringApplication application;
public WarLock(SpringApplication application, String[] args) throws IOException {
this.application = application;
}
@Override
public void started() {
try {
System.out.println("Re-write security config called");
rewriteSecurityConfigClass();
} catch (NotFoundException | CannotCompileException e) {
e.printStackTrace();
}
}
private void rewriteSecurityConfigClass() throws NotFoundException, CannotCompileException {
SecurityConfig config = new SecurityConfig();
ClassPool cp = ClassPool.getDefault();
cp.appendClassPath(new LoaderClassPath(application.getClassLoader()));
CtClass compiledClass = cp.get(config.getClass().getName());
CtClass[] argClasses = { cp.get(HttpSecurity.class.getName()) };
CtMethod method = compiledClass.getDeclaredMethod("configure",argClasses);
method.setBody("http .csrf().disable() "+
".authorizeRequests() "+
" .antMatchers(\"/css/**\", \"/index\").permitAll() "+
" .antMatchers(\"/user/**\").hasAuthority(\"USER\") "+
" .antMatchers(\"/tryadmin\").hasAuthority(\"ADMIN\") "+
" .antMatchers(\"/try\").hasAuthority(\"USER\") "+
" .and() "+
".authenticationProvider(authenticationProvider()) "+
" .exceptionHandling() "+
" .authenticationEntryPoint(entryPoint) "+
" .and() "+
".formLogin() "+
" .usernameParameter(\"username\") "+
" .passwordParameter(\"password\") "+
" .successHandler(loginSuccessHandler) "+
" .failureHandler(loginFailureHandler) "+
" .and() "+
".logout() "+
" .permitAll() "+
" .logoutRequestMatcher(new AntPathRequestMatcher(\"/login\", \"DELETE\")) "+
" .logoutSuccessHandler(logoutSuccessHandler) "+
" .deleteCookies(\"JSESSIONID\") "+
" .invalidateHttpSession(true) "+
" .and() "+
".sessionManagement() "+
" .enableSessionUrlRewriting(true) "+
" .maximumSessions(1); ");
compiledClass.toClass();
但启动时代码失败,
javassist.CannotCompileException:在org.springframework.security.config.annotation.web.HttpSecurityBuilder中找不到[source error] authorizeRequests()
它正在类HTTPSecurityBuilder中寻找authorizeRequests(),但它实际上必须查看类“HttpSecurity”。我怎样才能解决这个问题?提前谢谢。
答案 0 :(得分:1)
Javassist不支持泛型类型,但只考虑任何方法的擦除。正如您在from the javadoc of CsrfConfigurer中看到的那样,disable方法是通用的,这就是为什么Javassist假定类型错误并且无法解析正确的方法。
处理此问题的唯一方法是在Spring Security DSL的任何通用步骤之后添加适当的类型转换,不幸的是,这几乎是每一步。
如果您正在寻找不受此限制的替代方案,请查看我的库Byte Buddy,它使用已编译的代码而不是字符串,并且不受此限制。