Loading
I made some api with REST Spring. GET request works fine in Postman but when I try to do POST request I receive this error :
{
"timestamp": "2018-09-25T06:39:27.226+0000",
"status": 403,
"error": "Forbidden",
"message": "Forbidden",
"path": "/cidashboard/projects"
}
This is my controller :
@RestController
@RequestMapping(ProjectController.PROJECT_URL)
public class ProjectController {
public static final String PROJECT_URL = "/cidashboard/projects";
private final ProjectService projectService;
public ProjectController(ProjectService projectService) {
this.projectService = projectService;
}
@GetMapping
List<Project> getAllProjects(){
return projectService.findAllProjects();
}
@GetMapping("/{id}")
Project getProjectById(@PathVariable int id) {
return projectService.findProjectById(id);
}
@PostMapping
void addProject(@RequestBody Project newProject) {
projectService.saveProject(newProject);
}
}
Security configuration
initial I wanted to work with ldap, but in my application properties i left only the conection at database………………………………………………………………………………………………………………………………….
@EnableGlobalMethodSecurity
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/css/**").permitAll();
// .anyRequest().fullyAuthenticated();
// .and()
// .formLogin().loginPage("/login").permitAll()
// .failureUrl("/login-error");
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userDnPatterns("uid={0},ou=people")
.groupSearchBase("ou=groups")
.contextSource(contextSource())
.passwordCompare()
//.passwordEncoder(new LdapShaPasswordEncoder())
.passwordAttribute("userPassword");
}
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/static/**"); // #3
}
@Bean
public DefaultSpringSecurityContextSource contextSource() {
return new DefaultSpringSecurityContextSource(Arrays.asList("ldap://localhost:8389/"), "dc=springframework,dc=org");
}
}
Thanks for building this useful tool.
Found today that Post/Put/Delete doesn’t work — it returns 403 forbidden.
This problem happens in multiple setup — mine, and 3 other coworkers.
- Postman doesn’t send out request at all. I add breakpoint in server side.
I followed http://blog.getpostman.com/2015/06/13/debugging-postman-requests/, it failed at xhr.send.
Please fix this as this will make postman totally not woking.
This is stack trace from postman:
background_page.js:447 POST …… 403 (Forbidden)
sendXhrRequest @ background_page.js:447
addToQueue @ background_page.js:536
onExternalMessage @ background_page.js:554
target.(anonymous function) @ extensions::SafeBuiltins:19
EventImpl.dispatchToListener @ extensions::event_bindings:388
target.(anonymous function) @ extensions::SafeBuiltins:19
publicClassPrototype.(anonymous function) @ extensions::utils:151
EventImpl.dispatch_ @ extensions::event_bindings:372
EventImpl.dispatch @ extensions::event_bindings:394
target.(anonymous function) @ extensions::SafeBuiltins:19
publicClassPrototype.(anonymous function) @ extensions::utils:151
messageListener @ extensions::messaging:207
target.(anonymous function) @ extensions::SafeBuiltins:19
EventImpl.dispatchToListener @ extensions::event_bindings:388
target.(anonymous function) @ extensions::SafeBuiltins:19
publicClassPrototype.(anonymous function) @ extensions::utils:151
EventImpl.dispatch_ @ extensions::event_bindings:372
EventImpl.dispatch @ extensions::event_bindings:394
target.(anonymous function) @ extensions::SafeBuiltins:19
publicClassPrototype.(anonymous function) @ extensions::utils:151
dispatchOnMessage @ extensions::messaging:334
Собственно, проблема следующая:
Postman отрабатывает отлично и возвращает ожидаемый результат
А python на аналогичный запрос выдает 403 код. Хотя вроде как заголовки одинаковые. Что ему, собаке, не хватает?
import requests
from pprint import pprint
url = 'http://ovga.mos.ru:8080/_ajax/pass/list?search={%22grz%22:%22К239ММ159%22}&sort=validitydate&order=desc'
headers = {"X-Requested-With": "XMLHttpRequest",
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/54.0.2840.99 Safari/537.36',
}
response = requests.get(url, headers)
pprint(response)
<Response [403]>
-
Вопрос заданболее двух лет назад
-
2535 просмотров
Ты не все заголовки передал. Postman по-умолчанию генерирует некоторые заголовки самостоятельно, вот так подключается нормально:
headers = {
'Host': 'ovga.mos.ru',
'User-Agent': 'Magic User-Agent v999.26 Windows PRO 11',
'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive',
'X-Requested-With': 'XMLHttpRequest'
}
url = 'http://ovga.mos.ru:8080/_ajax/pass/list?search={"grz":"К239ММ159"}&sort=validitydate&order=desc'
response = requests.get(url, headers=headers)
<Response [200]>
Пригласить эксперта
-
Показать ещё
Загружается…
03 июн. 2023, в 19:30
500 руб./за проект
03 июн. 2023, в 19:30
750 руб./в час
03 июн. 2023, в 19:06
2000 руб./за проект
Минуточку внимания
After implementing a new project with Django that should allow to me to send some long text to the server, then use the KeyBERT library to extract automatically the Keywords from the sent text and finally send me a JSON response with the result. Once I deployed the project to test it using Postman, I found this error when trying to send directly a POST request to my view in Django using Postman.
In this article, I will explain to you 2 possible ways to circumvent this exception when sending requests through Postman to your Django project.
A. Disable CSRF protection for as specific view
Disabling the CSRF protection of a real project or something that really requires it is in no one’s head. You shouldn’t definitively do this unless you know what you’re doing (you understand totally how a CSRF attack and how could it be a problem to your application if you allow form submission without CSRF protection). Some cases where it could be feasible to use this approach:
- A local API that you’re testing locally only.
- A public API that’s designed to be accessible for anyone but somehow you trust all the possible requests (e.g your API is only accessible for specific IPs like the IP of another server that requests information from this endpoint and it has already CSRF protection with another language like PHP).
Otherwise, don’t do it. In my case, I designed a basic API that runs a machine learning library and should return the result of it as response, however the API doesn’t need any user implementation as it’s mean to be used only for me. This approach consists of disabling the CSRF protection of a specific route:
# views.py
from django.http import JsonResponse
# 1. Import the csrf_exempt decorator
from django.views.decorators.csrf import csrf_exempt
# 2. Exempt the view from CSRF checks
@csrf_exempt
def extract_keywords(request):
text = request.POST.get('text')
return JsonResponse(text)
The decorator will disable the CSRF checks for the route, in this case the extract_keywords method of the view. If you send the POST request to the same route again with Postman, it should succeed this time.
B. Auto-set X-CSRFToken header in Postman
The second option will work only if you are facing the following situation. If you have a Django project working properly let’s say in the following URL http://localhost:8080/my-form and it answers to GET
and POST
requests. Your project works properly, when you access the Form address through the browser through a GET request, the form will be rendered so the user can easily submit the data and when it’s submitted through a POST request, the request succeeds in the browser as expected. The problem with Postman appears when it works in the browser, but if you try to simulate the POST request to the same address using Postman, the mentioned exception will appear.
As previously mentioned, Django has inbuilt CSRF protection. The only mechanism that you have to trigger an AJAX request when this protection is enabled is to add the X-CSRFToken header to your request (which should contain a valid CSRF token to validate in the server). You can obtain this token first triggering a GET request to the endpoint to obtain the token and then use a Postman test script to manipulate the subsequent request with JavaScript adding the required header.
To accomplish this, open the Tests tab of your postman request and add the following test code:
var xsrfCookie = postman.getResponseCookie("csrftoken");
postman.setEnvironmentVariable('csrftoken', xsrfCookie.value);
This test JavaScript is executed after the response is received. Once it’s there, run the GET request:
What we did with the previous code is basically extracting the csrftoken of the form obtained with the GET request and it’s now going to be used in the subsequent POST request to validate the form. This token will be stored as an environment variable namely csrftoken
, so we can easily add it to the new POST request as a new header:
After declaring the header, simply run the POST request and it should now succeed:
Happy coding ❤️!