简体   繁体   中英

Custom UserDetailsService is not called by spring-boot

I'm trying to use UserDetailsService in spring-security to implement my authentication logic. However, UserDetailsService is not called during an HTTP request. Here is the code:

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserService userService;

    @Override
    public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException {
        Optional<User> user = userService.getById(Long.parseLong(userId));
        if (user.isEmpty()) {
            throw new UsernameNotFoundException("User " + userId + " not found");
        }
        return new org.springframework.security.core.userdetails.User(
                user.get().getName(),
                user.get().getHashedPassword(),
                List.of());
    }
}
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomUserDetailsService customUserDetailsService;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    protected void configure(HttpSecurity http) throws Exception {  // (2)
        http.authorizeRequests()
            .antMatchers("/user/add", "/user/loginByEmail").permitAll() // (3)
            .anyRequest().authenticated()
            .and()
            .logout()
            .permitAll()
            .and()
            .httpBasic();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserDetailsService)
            .passwordEncoder(passwordEncoder);
    }
}

I use a test to test the authentication logic, here is the core of the test code:

MvcResult addMvcResult = mockMvc.perform(post("/habit/friend/addById")
                .with(SecurityMockMvcRequestPostProcessors.httpBasic("Joey", "password"))
                .contentType("application/json")
                .content(StringUtils.toJSONString(addFriendRequestByIdDTO)))
        .andExpect(status().isOk())
        .andReturn();

The log shows that the authentication header is inserted by spring-test:

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /habit/friend/addById
       Parameters = {}
          Headers = [Content-Type:"application/json;charset=UTF-8", Content-Length:"47", Authorization:"Basic Sm9leTpwYXNzd29yZA=="]
             Body = {
  "currentUserId" : 1,
  "friendUserId" : 2
}
    Session Attrs = {org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository.CSRF_TOKEN=org.springframework.security.web.csrf.DefaultCsrfToken@3a48c398}

However, the authentication failed, I got a 403, and CustomUserDetailsService is never called. Why?

Your problem seems to be with CSRF rather than with UserDetailsService's implementation not being registered, Starting from Spring 4.x, CSRF protection is enabled by default and unless you turn it off like

http
    .csrf()
    .disable()

you are going to get 403 errors.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM