首页 > 解决方案 > Spring Boot授权返回401错误?

问题描述

我有一个问题,当我成功登录时,我想请求获取用户详细信息。我发送的请求是一个安全的 GET 请求,https://localhost:8080/users/userOne这个请求是由我的 Angular 前端发送的。

但我现在的问题是,Spring Boot 告诉我用户未获得授权并发送 401 错误。当我从前端向后端发出请求时,我正在发送一个授权令牌。在下面的代码中,您可以看到我在做什么。

角服务

  getUserDetails(username) {
    const headers = new HttpHeaders().append('Authorization', this.cookieService.get('token')).append('Content-Type', 'application/json');
    return this.http.get(`http://localhost:8080/users/` + username, { headers }).pipe(
      map(
        userData => {
          console.log(userData);
          return userData;
        }
      ));
  }

我的用户控制器:

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @CrossOrigin(origins = "http://localhost:4200/", maxAge = 3600)
    @RequestMapping(value = "/users", method = RequestMethod.GET)
    public ResponseEntity<User> getUserByUsername (@RequestBody String username){
        final User user = userService.getUserByUsername(username);
        return ResponseEntity.ok(user);
    }
}

我的网络安全配置

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().authorizeRequests()
                .antMatchers(HttpMethod.POST,"/authenticate").permitAll()
                .anyRequest().authenticated().and()
                .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and().sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().formLogin().disable();
        http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }

我的过滤器

@Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws ServletException, IOException {
        res.setHeader("Access-Control-Allow-Origin", "*");
        res.setHeader("Access-Control-Allow-Credentials", "true");
        res.setHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,PATCH,OPTIONS");
        res.setHeader("Access-Control-Allow-Headers", "Authorization, Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");

        if ("OPTIONS".equalsIgnoreCase(req.getMethod())) {
            res.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, res);
        }
    }

Angular 中的身份验证请求:

authenticate(username, password) {
      const headers = new HttpHeaders({
        'Content-Type': 'application/json',
        Authorization: sessionStorage.getItem('token'),
      });
      return this.httpClient.post<any>('http://localhost:8080/authenticate', {username, password}).pipe(
       map(
         userData => {
          sessionStorage.setItem('username', username);
          sessionStorage.setItem('token', userData.token);
          this.isLoggedIn = true;
          return userData;
         }
       )
      );
    }

我得到的错误:

GET http://localhost:8080/users/userOne 401
ERROR HttpErrorResponse {headers: HttpHeaders, status: 401, statusText: "OK", url: "http://localhost:8080/users/Bogatom", ok: false, …}

我不知道我做错了什么......

标签: angularspringsecurityrequesthttp-status-code-401

解决方案


首先,您需要http://localhost:8080/login使用以下作为此请求的标头进行 POST 调用

headers = { "Content-Type": "application/x-www-form-urlencoded", "X-XSRF-TOKEN": csrf_token }

以及在请求正文中使用 urlencode 编码的凭据

credentials = { 'username': username, 'password': password }

此请求的响应将包含诸如“X-XSRF-TOKEN”和/或 JSESSIONID 之类的元素,您在向所有后续请求http://localhost:8080/users或任何其他授权的 URL 发出请求时需要传递这些元素。希望这可以帮助。


推荐阅读