首页 > 解决方案 > 现有端点的未经授权的错误 401,服务器日志中未引发错误

问题描述

我将用户名和密码字段添加到现有客户实体。我添加了一个自定义 JWT 过滤器和身份验证提供程序,其中 WebSecurityConfig 注释为 @Order(2)。但是当我发送带有用户名和密码有效负载的发布请求时,我收到未经授权的错误 401 响应但服务器日志中没有错误消息我已经适当地检查了 WebConfig 文件。我做错了什么?我整天都在做这件事,我似乎已经很沮丧了。

这是UserDetails

public class MyCustomerDetails implements UserDetails{

    /**
     * 
     */
    private static final long serialVersionUID = -5087929420394311276L;

    private Long id;
    private String username;
    private String password;
    
    public MyCustomerDetails() {
        
    }
    
    public MyCustomerDetails(Long id, String username, String password) {
        super();
        this.id = id;
        this.username = username;
        this.password = password;
    }

   public static MyCustomerDetails build(Customer customer) {
        return new MyCustomerDetails(customer.getId(), 
                customer.getUserName(), customer.getPassword());
    }


   @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public String getPassword() {
        // TODO Auto-generated method stub
        return password;
    }

    @Override
    public String getUsername() {
        // TODO Auto-generated method stub
        return username;
    }

    ............

这是控制器

@CrossOrigin(origins = {"http://localhost:3000"})
@RestController
public class CustomerController {
    
        @Autowired
        CustomerAccountService customerRepo;
        
         @Autowired
         private CustomerJwtTokenUtil customerJwtTokenUtil;
        
         @Autowired
         private AuthenticationManager authenticationManager;
         
    
         @PostMapping(value="/validateCustomer")
          public ResponseEntity <?> createAuthenticationToken( @RequestBody MyCustomerDetails
          authenticationRequest) throws Exception 
             {  
             authenticate(authenticationRequest.getUsername(),  
                authenticationRequest.getPassword()); 
        // Long userId = authenticationRequest.getId();
             final MyCustomerDetails userDetails =  
                 (MyCustomerDetails)   customerRepo.loadUserByUsername(authenticationRequest.getUsername());
           
           final String token = 
                   customerJwtTokenUtil.generateToken(userDetails);
          
          return new ResponseEntity<>(new JwtResponse(token), HttpStatus.OK) ;
                    
         
               }
         private void authenticate(String username, String password) throws Exception {
                    try {
                        authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
                    } catch (DisabledException e) {
                        throw new Exception("USER_DISABLED", e);
                    } catch (BadCredentialsException e) {
                        throw new Exception("INVALID_CREDENTIALS", e);
                    }
                }
             

这是WebSecurityconfig


@Configuration
@Order(2)
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class CustomerSecurityConfiguration extends WebSecurityConfigurerAdapter {

    
    @Autowired
    private CustomerJwtAuthenticationEntryPoint customerJwtAuthenticationEntryPoint;
    
    @Autowired
    private UserDetailsService myCustomerDetailsService;
    
    @Autowired 
    private CustomerJwtRequestFilter customerJwtRequestFilter;
     
    
    @Bean
    public CustomerAccountService myCustomerAccountService() {
        return new CustomerAccountService();
    }
    
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    /*
     * @Bean public UserDetailsService myCustomerDetailsService() { return
     * myCustomerDetailsService(); }
     */
    
    
     @Bean
        public DaoAuthenticationProvider daoAuthenticationProvider(PasswordEncoder passwordEncoder,
                                                                   UserDetailsService userDetailsService){ 
            DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
            daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
            daoAuthenticationProvider.setUserDetailsService(userDetailsService);
            return daoAuthenticationProvider;
      }
     
     
     @Override
     @Bean
     public AuthenticationManager authenticationManagerBean() throws Exception {
         return super.authenticationManagerBean();
     }

     
     protected void configure(AuthenticationManagerBuilder auth ) throws Exception {
         auth.userDetailsService(myCustomerDetailsService).passwordEncoder(passwordEncoder());
         }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
      http.cors().and().csrf().disable()
      .authorizeRequests()
      .antMatchers("/***").permitAll()
    
     // .antMatchers("/customer/**").hasAuthority("CUSTOMER")
      .anyRequest().authenticated()
      .and()
      .exceptionHandling()
      .authenticationEntryPoint(customerJwtAuthenticationEntryPoint)
      
      .and()
      .formLogin().permitAll()
    //  .loginPage("/login")
     
      .and()
      .logout().logoutUrl("/logout").logoutSuccessUrl("/login")
     
      .and()
      .sessionManagement()
      .maximumSessions(1)
      .and()
      .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
      http.addFilterBefore(customerJwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }
          
    
}

服务

@Primary
public class CustomerAccountService implements UserDetailsService {
    
    
    @Autowired  
    private CustomerAccountRepo custRepo;
    
    @Qualifier("passwordEncoder")
    @Autowired
    private PasswordEncoder bCryptPasswordEncoder;
    
    
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Customer customer = custRepo.findByUserName(username);
        if(customer == null) {
            throw new UsernameNotFoundException("Customer not found");
        }
        
      return MyCustomerDetails.build(customer);
        
      }
    

这是基类


@Configuration
@EnableWebMvc
//@ComponentScan(basePackages = "com.bethsaida.org.security")
@EnableJpaRepositories
@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
public class BethsaidaApplication  {
    
     public static void main(String[] args) 
      {SpringApplication.run(BethsaidaApplication.class, args);}
 
     public class WebConfig implements WebMvcConfigurer 
        { 
         private static final long MAX_AGE_SECS = 3600;

        @Override
        public void addCorsMappings(CorsRegistry registry) 
         { registry.addMapping("/**")
             .allowedOrigins("*")
             .allowedMethods("HEAD", "OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE")
             .maxAge(MAX_AGE_SECS);}
        }
     
    }



标签: javaspringspring-bootspring-securityjwt

解决方案


你可以用这个

   @Override
   public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
        .allowedOrigins("*")
        .allowedMethods("POST", "PUT", "DELETE")
        .allowedHeaders("header1", "header2")
        .exposedHeaders("header1", "header2")
        .allowCredentials(false).maxAge(3600);
   }

直接在你的CustomerSecurityConfiguration班级里面。因为WebMvcConfigurer是由实现的,WebMvcConfigurerAdapter所以你可以在你的CustomerSecurityConfiguration类中定义这个方法。

有关更多信息,您可以在此处查看


推荐阅读