Java 如何在auditorAware中更新身份验证
当应用程序启动时,Java 如何在auditorAware中更新身份验证,java,spring,spring-boot,spring-data-jpa,Java,Spring,Spring Boot,Spring Data Jpa,当应用程序启动时,auditorProvider似乎只被调用一次身份验证authentication对象始终为空,并且在以后的doFilter中设置时不会更新。更新数据库中的行时,createdBy和lastModifiedBy始终为空 处理HTTP请求时,似乎会调用MydoFilter 我学习了一个教程来学习spring安全性,但在故障排除了几个小时并学习了许多类似的教程之后,仍然无法理解如何按顺序正确设置身份验证,因此当我更新行时,spring将自动更新lastModifiedBy和crea
auditorProvider
似乎只被调用一次<在doFilter
中设置身份验证之前,会调用代码>身份验证authentication
对象始终为空,并且在以后的doFilter
中设置时不会更新。更新数据库中的行时,createdBy
和lastModifiedBy
始终为空
处理HTTP请求时,似乎会调用MydoFilter
我学习了一个教程来学习spring安全性,但在故障排除了几个小时并学习了许多类似的教程之后,仍然无法理解如何按顺序正确设置身份验证,因此当我更新行时,spring将自动更新lastModifiedBy
和createdBy
。- 您的问题是,您正在创建一个匿名的
AuditorAware
,但您正在对主体外部的SecurityContextHolder.getContext().getAuthentication()
进行评估,因此创建时的任何内容都将保留在主体内部
@Bean
@范围(值=ConfigurableBeanFactory.Scope\u原型)
公共AuditorAware auditorProvider(){
返回()->{
身份验证
=SecurityContextHolder.getContext().getAuthentication();
返回可选的.ofNullable(身份验证)
.map(身份验证::getName);
};
}
- 您可以说,您有
,但如果它是自动连接到框架使用的单例实例中的,那么它是无用的SCOPE\u PROTOTYPE
Optional.ofNullable(authentication).map(authentication::getName)
我在谷歌快速搜索后的解释是,当身份验证
不为null时,它将调用getName方法,但什么时候它将不为null?您是否将return语句转换为数据流?怎样?非常感谢您的帮助假设您的返回是可选的返回(身份验证)这相当于if(authentication==null)返回Optional.empty()否则返回Optional.of(authentication)
但是您可以在它之后链接操作,就像在答案中一样,如果它已经是空的
@Configuration
@EnableJpaAuditing(auditorAwareRef = "auditorProvider")
public class JpaAuditingConfiguration {
@Bean
@Scope(value= ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public AuditorAware<String> auditorProvider() {
Authentication authentication
= SecurityContextHolder.getContext().getAuthentication();
if (authentication == null) {
return () -> Optional.<String>empty();
}
return () -> Optional.of(authentication.getName());
}
public static void main(String[] args) {
SpringApplication.run(JpaAuditingConfiguration.class, args);
}
}
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailServiceImpl userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(new BCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().cors().and()
.logout()
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutSuccessUrl("/logout/success")
.and().authorizeRequests()
.antMatchers(HttpMethod.POST, "/login").permitAll()
.antMatchers(HttpMethod.GET, "/logout/**").permitAll()
.anyRequest().authenticated().and()
// Filter for the api/login requests
.addFilterBefore(new LoginFilter("/login",
authenticationManager()),
UsernamePasswordAuthenticationFilter.class)
// Filter for other requests to check JWT in header
.addFilterBefore(new AuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class);
}
public class AuthenticationFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain filterChain)
throws IOException, ServletException {
Authentication authentication
= AuthenticationService
.getAuthentication((HttpServletRequest)request);
SecurityContext securityContext
= SecurityContextHolder.getContext();
securityContext.setAuthentication(authentication);
filterChain.doFilter(request, response);
}
}
@Bean
@Scope(value= ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public AuditorAware<String> auditorProvider() {
return () -> {
Authentication authentication
= SecurityContextHolder.getContext().getAuthentication();
return Optional.ofNullable(authentication)
.map(Authentication::getName);
};
}