У меня есть следующие методы в моем контроллере отдыха:
Первый - это запрос на получение:
@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;
}));
}
Этот сервисный метод вызывает метод пост-контроллера, он не работает, вот ошибка:
ошибка: {status: "Unauthorized", ошибка: 401, сообщение: "Извините, выВы не авторизованы для доступа к этому ресурсу. "}
Я не знаю, почему токен работает на GET, но не на POST.
EDIT
конфигурация безопасности пружины:
@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;
}
}