gpt4 book ai didi

java - 将自定义 UserDetailsS​​ervice Autowiring 到 AbstractAuthenticationProcessingFilter

转载 作者:行者123 更新时间:2023-12-01 06:06:16 24 4
gpt4 key购买 nike

我有一个自定义的 UserDetailsS​​ervice:

public class CustomUserDetailsService implements UserDetailsService {

@Autowired
private AccountRepository accountRepository;
@Autowired
private PasswordEncoder passwordEncoder;
private static Logger logger = LoggerFactory.getLogger(JWTLoginFilter.class);

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
CustomUserDetails account = accountRepository.findByUsername(username);
if (account != null) {
return account;
} else {
throw new UsernameNotFoundException("could not find the user '" + username + "'");
}
}

public void saveUser(String userName, String password) {
CustomUserDetails userDetails = new CustomUserDetails(userName, passwordEncoder.encode(password), true, true, true,true, AuthorityUtils.commaSeparatedStringToAuthorityList("USER_ROLE"));
accountRepository.save(userDetails);
logger.debug("New user with username " + userName + " was created");
}

}

我有一个注册过滤器(处理创建新用户)并扩展AbstractAuthenticationProcessingFilter:

public class JWTSignupFilter extends AbstractAuthenticationProcessingFilter {

@Autowired
private CustomUserDetailsService userDetailService;
private static Logger logger = LoggerFactory.getLogger(JWTLoginFilter.class);

public JWTSignupFilter(String url, AuthenticationManager authManager) {
super(new AntPathRequestMatcher(url, HttpMethod.POST.toString()));
setAuthenticationManager(authManager);
}

@Override
public Authentication attemptAuthentication(HttpServletRequest request,HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
CustomUserDetails creds = new ObjectMapper().readValue(request.getInputStream(), CustomUserDetails.class);
if (userDetailService.loadUserByUsername(creds.getUsername()) != null) {
logger.debug("Duplicate username " + creds.getUsername());
throw new AuthenticationException("Duplicate username") {
private static final long serialVersionUID = 1L;
};
}
userDetailService.saveUser(creds.getUsername(), creds.getPassword());
return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(creds.getUsername(),creds.getPassword()));
}

@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication auth) throws IOException, ServletException {
TokenAuthenticationService.addAuthentication(response, auth.getName());
chain.doFilter(request, response);
}
}

当执行到达userDetailService.loadUserByUsername时,我得到空指针异常,这意味着 Autowiring 不起作用。

我尝试像下面这样实现ApplicationContextAware,但它仍然是Null。我还用 @Service 注释了 JWTSignupFilter 但它也不起作用。知道如何解决这个问题吗?

public class JWTSignupFilter extends AbstractAuthenticationProcessingFilter implements ApplicationContextAware {

private CustomUserDetailsService userDetailService;

.....

@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
userDetailService = applicationContext.getBean(CustomUserDetailsService.class);
}
}

这是WebSecurityConfigurerAdapter中重写的configure方法,其中登录过滤器发挥作用:

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/login").permitAll()
.and()
.authorizeRequests()
.antMatchers("/signup").permitAll()
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.logout().logoutUrl("/logout").logoutSuccessHandler(logoutHandler).logoutSuccessUrl("/login").invalidateHttpSession(true)
.and()
// We filter the api/signup requests
.addFilterBefore(
new JWTSignupFilter("/signup", authenticationManager()),
UsernamePasswordAuthenticationFilter.class)
// We filter the api/login requests
.addFilterBefore(
new JWTLoginFilter("/login", authenticationManager()),
UsernamePasswordAuthenticationFilter.class)
// And filter other requests to check the presence of JWT in
// header
.addFilterBefore(
new JWTAuthenticationFilter(userDetailsServiceBean()),
UsernamePasswordAuthenticationFilter.class);
}

最佳答案

试试这个:

将以下代码添加到您的配置文件中:

    @Bean
public JWTSignupFilter jWTSignupFilter() throws Exception {
return new JWTSignupFilter("/login", authenticationManager());
}

将以下行添加到您的 WebSecurityConfigurerAdapter 扩展类

@Autowired 
JWTLoginFilter jWTSignupFilter

并替换

.addFilterBefore(
new JWTLoginFilter("/login", authenticationManager()),
UsernamePasswordAuthenticationFilter.class)

.addFilterBefore(
jWTSignupFilter,
UsernamePasswordAuthenticationFilter.class)

已更新

您的 WebSecurityConfigurerAdapter 扩展类应如下所示:

public Class CustomConfigurationClass extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/login").permitAll()
.and()
.authorizeRequests()
.antMatchers("/signup").permitAll()
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.logout().logoutUrl("/logout").logoutSuccessHandler(logoutHandler).logoutSuccessUrl("/login").invalidateHttpSession(true)
.and()
// We filter the api/signup requests
.addFilterBefore(
jWTSignupFilter(),
UsernamePasswordAuthenticationFilter.class)
// We filter the api/login requests
.addFilterBefore(
new JWTLoginFilter("/login", authenticationManager()),
UsernamePasswordAuthenticationFilter.class)
// And filter other requests to check the presence of JWT in
// header
.addFilterBefore(
new JWTAuthenticationFilter(userDetailsServiceBean()),
UsernamePasswordAuthenticationFilter.class);
}

@Bean
public JWTSignupFilter jWTSignupFilter() throws Exception {
return new JWTSignupFilter("/signup", authenticationManager());
}
}

关于java - 将自定义 UserDetailsS​​ervice Autowiring 到 AbstractAuthenticationProcessingFilter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43882662/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com