授权仅适用于GET请求



我的rest控制器中有以下方法:

第一个是获取请求:

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

第二个是张贴请求::

@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);
}

在角服务中,我打以下电话:

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;
}));
}

这个服务方法调用后控制器方法,它不起作用,错误如下:

错误:{状态:"未授权",错误:401,消息:"对不起,您无权访问此资源。"}

我不知道为什么令牌在GET上有效,但在POST上无效。

编辑
春季安全配置:

@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;
}
}

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

getAllShops(url, headers)

但是POST接受三个:

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;
}));
}

最新更新