繁体   English   中英

401 在 authenticationManager.authenticate() 上未经授权(Spring Security)

[英]401 Unauthorized on authenticationManager.authenticate() (Spring Security)

401 Unauthorized尝试登录时产生,而注册工作正常。

在调试期间,我发现响应是在调用UserController方法authenticationManager.authenticate()的行上给出的。 我注意到的另一件事是,由于某种原因,我在使用JPA Repositories 而不是DAO时没有遇到这个问题。 我正在使用 PostgreSQL

在此处输入图片说明

下面是UserController对应方法的代码:

    @RequestMapping(path = "/auth", method = RequestMethod.POST)
    @ResponseStatus(value = HttpStatus.OK)
    public AuthResponse authenticate(@RequestBody AuthRequest req){
        authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(req.getUsername(), req.getPassword()));
        String token = jwtService.generateToken(req.getUsername());
        return new AuthResponse(token);
    }

JwtFilter.doFilterInternal():

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        String authorizationHeader = httpServletRequest.getHeader("Authorization");
        String jwtToken = null;
        String username = null;
        if (authorizationHeader != null && authorizationHeader.startsWith("Bearer")) {
            jwtToken = authorizationHeader.substring(7);
            username = jwtService.extractUsername(jwtToken);
        }
        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            if (jwtService.validateToken(jwtToken, userDetails.getUsername())) {
                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities()
                );
                usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            }
        }
        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }

SecurityConfig.configure():

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().cors().disable()
                .authorizeRequests()
                .anyRequest().permitAll()
                .and().addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().httpBasic();
    }

UserService.loadUserByUsername():

@Service
public class UserService implements IUserService, UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        User userByName = userDao.getUserByUsername(s);
        return new org.springframework.security.core.userdetails.User(userByName.getUsername(), userByName.getPassword(), userByName.getAuthorities());
    }
}

DAO 查询:

@Override
public User getUserByUsername(String username) {
    return jdbcTemplate.queryForObject("SELECT * FROM user_table WHERE username = ?", new Object[]{username}, User.class);
}

这可能是 JWT 问题。 在行中: .and().addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)使用 Debug 来查看,你有什么作为参数。

如果您查看文档

An AuthenticationManager must honour the following contract concerning exceptions:

A DisabledException must be thrown if an account is disabled and the AuthenticationManager can test for this state.
A LockedException must be thrown if an account is locked and the AuthenticationManager can test for account locking.
A BadCredentialsException must be thrown if incorrect credentials are presented. Whilst the above exceptions are optional, an AuthenticationManager must always test credentials.
Exceptions should be tested for and if applicable thrown in the order expressed above (i.e. if an account is disabled or locked, the authentication request is immediately rejected and the credentials testing process is not performed). This prevents credentials being tested against disabled or locked accounts.

我猜你的身份验证正在抛出这三个异常之一(或者可能是其他一些异常)。 您需要查看日志以确定是哪一个,或者捕获异常并对其进行调试。

问题是查询没有返回预期值。 我变了:

 @Override
public User getUserByUsername(String username) {
    List<User> userList = jdbcTemplate.query("SELECT * FROM user_table WHERE username = ?", new Object[]{username}, (resultSet,i) -> {
        System.out.println(1);
        return new User(resultSet.getInt("id"),
                resultSet.getString("username"),
                resultSet.getString("password"),
                resultSet.getString("role"));
    });
    return userList.get(0);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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