我的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;
}));
}
此服务方法调用了post controller方法,但没有用,这是错误信息:
错误:{状态:“未经授权”,错误: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;
}
}
答案 0 :(得分:0)
这是一个愚蠢的错误,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;
}));
}