授权仅适用于get请求

izj3ouym  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(325)

我的rest控制器中有以下方法:
第一个是get请求:

@GetMapping
public ResponseEntity<PagedResponse<Shop>> getAllShops() {
    return ResponseEntity.ok(this.shopService.getAllShopsSortedByDistance());
}

第二个是post请求:

@PostMapping("/like")
public ResponseEntity<RestResponse> addShop(@RequestParam(value = "shop") String shopId,
                                            @CurrentUser UserPrincipal userPrincipal)
{
    RestResponse restResponse = this.shopService.addShopToLikedShops(shopId, userPrincipal.getId());
    UriComponents uriComponents = uriComponentsBuilder.path("/shops").buildAndExpand();
    return ResponseEntity.created().body(restResponse);
}

在angular服务中,我进行以下调用:

getAllShops(): Observable<ShopsPage> {
    const httpOptions = {
        headers: new HttpHeaders({
            'Authorization': this.tokenService.getToken()
        })
    };
    return this.httpClient.get<ShopsPage>(this.apiUrl, httpOptions)
            .pipe(map(response => {
                return response;
            }));
    }

此方法调用控制器中的get方法,工作正常。
第二种服务方式:

addShopToPreferred(shopId: string): Observable<any> {
    const httpOptions = {
        headers: new HttpHeaders({
            'Content-Type': 'application/json',
            'Authorization': this.tokenService.getToken()
        })
    };
    return this.httpClient.post(this.apiUrl + "/like?shop=" + shopId, httpOptions)
        .pipe(map(response => {
            return response;
        }));
}

此服务方法调用post controller方法,它不起作用,错误如下:
错误:{状态:“未授权”,错误:401,消息:“抱歉,您无权访问此资源。”}
我不知道为什么令牌在get上有效,但在post上无效。
编辑
spring安全配置:

@Override
protected void configure(HttpSecurity http) throws Exception {
        http
                .cors()
                .and()
                .csrf()
                .disable()
                .exceptionHandling()
                .authenticationEntryPoint(this.jwtAuthenticationEntryPoint)
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/users/**")
                .permitAll()
                .anyRequest()
                .authenticated();

        // Add our custom JWT security filter
        http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }

编辑2
添加 JwtAuthenticationFilter 班级:

public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private JwtTokenProvider tokenProvider;

    @Autowired
    private CustomUserDetailsService customUserDetailsService;

    private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationFilter.class);

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        try {
            String jwt = getJwtFromRequest(request);

            if (StringUtils.hasText(jwt) && this.tokenProvider.validateToken(jwt)) {
                String userId = this.tokenProvider.getUserIdFromJWT(jwt);

                UserDetails userDetails = this.customUserDetailsService.loadUserById(userId);
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        } catch (Exception ex) {
            logger.error("Could not set user authentication in security context", ex);
        }

        filterChain.doFilter(request, response);
    }

    private String getJwtFromRequest(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }
}
zdwk9cvp

zdwk9cvp1#

这是一个愚蠢的错误,get方法接受两个参数:

getAllShops(url, headers)

但邮局接受三种:

addShop(url, data, headers)

所以我传递的是数据而不是头,post方法应该是这样的:

addShopToPreferred(shopId: string): Observable<any> {
    const httpOptions = {
        headers: new HttpHeaders({
            'Content-Type': 'application/json',
            'Authorization': this.tokenService.getToken()
        })
    };
    return this.httpClient.post(this.apiUrl + "/like?shop=" + shopId, null, httpOptions)
        .pipe(map(response => {
            return response;
        }));
}

相关问题