我实现了一个 OncePerRequestFilter
,在哪里 doFilterInternal()
我想使用一个利用率类 JdbcTemplate
以及属性文件中的用户数据。我意识到它无法访问属性文件(数据库连接和变量)中的数据,并且总是空值。我在网上发现,这是因为不同的背景。
我可以在本地成功地设置一个新的jdbc数据源,但是我不想复制代码,所以我只想像在restcontrollers中一样简单地注入源代码( @Value
, @Autowired
).
我怎么能把这些注入到我的利用率类中,这些类将在servlet过滤器中使用,或者直接在我的过滤器中使用?
谢谢您!
更新-代码段:
在 RestController
,注射 JdbcTemplate
正常工作,但在过滤器我不能注入它,总是抛出 nullPointerException
.
@SpringBootApplication
public class AsdApplication {
public static void main(String[] args) {
SpringApplication.run(AsdApplication.class, args);
}
public static class ApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Filter[] getServletFilters() {
DelegatingFilterProxy delegateFilterProxy = new DelegatingFilterProxy();
delegateFilterProxy.setTargetBeanName("MyFilter");
return new Filter[] { delegateFilterProxy };
}
@Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return null;
}
}
}
@RestController
public class RestCtrl {
@Autowired
private JdbcTemplate jdbcTemplate;
@GetMapping("/test")
public ResponseEntity<String> getTest() {
String result = jdbcTemplate.queryForObject("<query>", String.class);
System.out.println("result in ctrl: " + result);
return new ResponseEntity<>("asd ad asd asd asd", HttpStatus.OK);
}
}
@Component(value = "MyFilter")
public class MyFilter extends OncePerRequestFilter {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String result = jdbcTemplate.queryForObject("<query>", String.class);
System.out.println("result in filter: " + result);
User currentUser = new User("username", "password", new ArrayList<>());
UsernamePasswordAuthenticationToken authenticatedUser = new UsernamePasswordAuthenticationToken(
currentUser, null, currentUser.getAuthorities()
);
SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
filterChain.doFilter(request, response);
}
}
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable().authorizeRequests().anyRequest().authenticated();
httpSecurity.addFilterBefore(new MyFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
spring.datasource.url=jdbc:<sqlserver>
spring.datasource.username=<user>
spring.datasource.password=<pass>
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
3条答案
按热度按时间ffx8fchx1#
你应该用这个:
通过这个类,您可以在非bean类中获得不同的springbootbean。
然后在创建它之后,按以下方式获取bean:
eivnm1vs2#
因为您实际使用的是springboot,并且希望将其作为springsecurity过滤器链的一部分(这是另一回事!)你需要做的是
创建
@Bean
方法创建过滤器并使其成为bean创建
@Bean
方法并添加FilterRegistration
防止bean被spring boot注册为过滤器配置Spring Security 。
最后移除
@Component
从你的MyFilter
因为你不需要它,它会创建一个额外的示例。所有先前的更改(如ApplicationInitializer
等等。您可以删除。注意:因为您使用的是Spring Security ,并且以某种方式将其用于身份验证,而不是扩展
OncePerRequestFilter
我建议你延长 Spring 安全期AbstractAuthenticationProcessingFilter
它与Spring Security 集成得更好(比如激发用于身份验证、日志记录等的事件)。klsxnrf13#
我看到你正在创建一个
MyFilter
而不是使用spring管理的@Component(value = "MyFilter")
```httpSecurity.addFilterBefore(new MyFilter(), UsernamePasswordAuthenticationFilter.class);
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
}