Весенняя охрана вернула 401, даже allowAll () - PullRequest
0 голосов
/ 11 апреля 2020

Я делаю весенний загрузочный веб-сервер, который имеет Spring Security и JWT для аутентификации / авторизации пользователя через имя пользователя и пароль. Но кажется, что Spring распознает /api/users/signup и /api/users/signin как URL, который должен быть аутентифицирован.

UserController.java:

    @PostMapping("/signin")
    public ResponseEntity<String> login(@ApiParam("Username") @RequestParam String username, //
                                        @ApiParam("Password") @RequestParam String password) {
        return ResponseEntity.ok(userService.signin(username, password));
    }

    @PostMapping("/signup")
    public void signUp(@ApiParam("SignUp User") @RequestBody SignUpRequest request) {
        User user = User.of(request.getUsername(), bCryptPasswordEncoder.encode(request.getPassword()), request.getEmail());
        Role userRole = roleRepository.findByName(RoleName.ROLE_MEMBER).orElse(null);
        user.setRoles(Collections.singleton(userRole));

        userRepository.save(user);
    }

WebSecurityConfig.java

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
        prePostEnabled = true
)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private final JwtTokenProvider jwtTokenProvider;


    public WebSecurityConfig(JwtTokenProvider jwtTokenProvider) {
        this.jwtTokenProvider = jwtTokenProvider;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // Disable CSRF (cross site request forgery)
        http.csrf().disable();

        // No session will be created or used by spring security
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        // Entry points
        http.authorizeRequests()//
                .antMatchers("/api/users/signin").permitAll()//
                .antMatchers("/api/users/signup").permitAll()//
                .antMatchers("/api/test/**").permitAll()
                .antMatchers("/h2-console/**/**").permitAll()
                // Disallow everything else..
                .anyRequest().authenticated();

        // If a user try to access a resource without having enough permissions
        http.exceptionHandling().accessDeniedPage("/login");

        // Apply JWT
        http.apply(new JwtTokenFilterConfigurer(jwtTokenProvider));

        http.cors().disable();

        // Optional, if you want to test the API from a browser
        // http.httpBasic();

        super.configure(http);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(10);
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

JwtTokenFilter.java:

public class JwtTokenFilter extends OncePerRequestFilter {

    private JwtTokenProvider jwtTokenProvider;

    public JwtTokenFilter(JwtTokenProvider jwtTokenProvider) {
        this.jwtTokenProvider = jwtTokenProvider;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        String token = jwtTokenProvider.resolveToken(httpServletRequest);
        try {
            if (token != null && jwtTokenProvider.validateToken(token)) {
                Authentication auth = jwtTokenProvider.getAuthentication(token);
                SecurityContextHolder.getContext().setAuthentication(auth);
            }
        } catch (CustomException ex) {
            //this is very important, since it guarantees the user is not authenticated at all
            SecurityContextHolder.clearContext();
            httpServletResponse.sendError(ex.getHttpStatus().value(), ex.getMessage());
            return;
        }

        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }
}

MyUserDetailsService.java:

@Service
public class MyUserDetailsService implements UserDetailsService {
    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        final User user = userRepository.findByUsername(username).orElseThrow(() -> new CustomException("User doesn't exist", HttpStatus.NOT_FOUND));

        List<GrantedAuthority> authorities = user.getRoles().stream().map(role ->
            new SimpleGrantedAuthority(role.getName().getAuthority())
        ).collect(Collectors.toList());

        if (user == null) {
            throw new UsernameNotFoundException("User '" + username + "' not found");
        }

        return org.springframework.security.core.userdetails.User//
                .withUsername(username)
                .password(user.getPassword())
                .authorities(authorities)
                .accountExpired(false)
                .accountLocked(false)
                .credentialsExpired(false)
                .disabled(false)
                .build();
    }
}

Когда я запрашиваю обе эти ссылки, как я сказал выше. Это делается быстро, давая мне 401 код ошибки HTTP во время тестирования на почтальоне .

Обе эта ссылка и эта ссылка вообще не помогают .

1 Ответ

0 голосов
/ 11 апреля 2020

Вместо этого вы можете попробовать исключить эти URL-адреса из WebSecurity section, чтобы они вообще не обрабатывались Spring Security и вашим JwtTokenFilter.

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  public void configure(final WebSecurity web) throws Exception {
      web.ignoring()
       .antMatchers("/api/users/signin").antMatchers("/api/users/signup");
  }
}
...