Bad Request Error (400) after $.ajax POST on OAuth module

We are working with @jose007 on the CDAGenerator module, since we will include it in an FHIR resource later on. We are need to work with OAuth.

We are trying to send a JSON object to a Controller by using a $.ajax POST call, but we find an Bad Request Error 400.

Note that without the Oauth module the call works correctly.

JQuery :

$('#botonBuscarDocument').on( 'click', function(e) {
	if (validate()) {
		var encounter = {
			typeEncounter: document.getElementById("cda_type").value,
			patientId: document.getElementById("patientId").value,
			encounterId: '',
			patientUuid: -1
		};
		var jqxhr = $.ajax({
			url: '${pageContext.request.contextPath}/module/CDAGenerator/exportcda.form',
			type: "POST",
			dataType: "text",
			contentType: "application/json",
			data: JSON.stringify( encounter ),
			success: function(  listEncounter) {
				console.log('todo ok en document all');
				mostrarTablaEncounter(listEncounter);
			},
			error: function( jqXHR, textStatus, errorThrown ) {
				console.log(textStatus+ "\nError Tirado: \n"+ errorThrown);
			}
		});
	}
});

Controller:

@RequestMapping(value = { "/module/CDAGenerator/exportcda.form" }, method = RequestMethod.POST )
@ResponseBody
public String manage( @RequestBody final String typeEncounter, HttpServletResponse response ) throws JSONException{
	System.out.println("----------------------------"+typeEncounter);

	JSONObject bcth =  new JSONObject( typeEncounter );

	Integer patientId = new Integer( bcth.getString( "patientId" ) );
	String patientUuid = bcth.getString( "patientUuid" );

	System.out.println("--typeEncounter--"+bcth.getString("typeEncounter"));
	System.out.println("--patientId--"+patientId);
	System.out.println("--encounterId--"+bcth.getString("encounterId"));
	
	System.out.println("--patientUuid--"+bcth.getString("patientUuid"));


	PatientService patientService = Context.getPatientService();
	org.openmrs.Patient patient;
	if ( patientId.compareTo( new Integer( -1 ) ) == 1 )
		patient = patientService.getPatient( patientId );
	else
		patient = patientService.getPatientByUuid( patientUuid );


	if ( bcth.getString("encounterId").equals("") ) {
		return this.getListEncounterJSON( patient, bcth.getString("typeEncounter") );
	}
	else {
		ClinicalDocument cda = null;
		FhirCdaServerService cdaservice = Context.getService(FhirCdaServerService.class);

		Integer encotunterId = new Integer( bcth.getString( "encounterId" ) );

		cda = cdaservice.produceCDA( Context.getEncounterService().getEncounter( encotunterId ) );

		CDAPackage.eINSTANCE.eClass();

		response.setHeader("Content-Disposition","attachment;filename=" + patient.getGivenName() +
			bcth.getString("typeEncounter") + ".xml");
		try {
			StringWriter r = new StringWriter();
			CDAUtil.save(cda, r);
			String cdaDoc = r.toString();
			cdaDoc = cdaDoc.replaceAll("
", "\n");
			cdaDoc = cdaDoc.replaceAll("&lt;", "<");
			cdaDoc = cdaDoc.replaceAll("&quot;", "\"");
			byte[] res = cdaDoc.getBytes(Charset.forName("UTF-8"));
			response.setContentType("text/xml");
			response.setCharacterEncoding("UTF-8");
			response.getOutputStream().write(res);
			response.flushBuffer();
		}
		catch (IOException e) {
			e.printStackTrace();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}

We attach the captures:

Can someone help us? @mavrk @pkatopenmrs

Are you able to reach the controller? Do you get any logs on the server side? And what’s your module’s id?

It does not reach the controller. Do not print System.out of the beginning.

There is no server side log.

We do not have module ID, we are OpenMRS beginners.

Which oauth module version are you using? May I get to know from where did you downloaded the the .omod file?

We are using branch master. With branch “gsoc-18” the result is the same.

Oauth module

Only with this change in “webModuleApplicationContext.xml” (login):

<!--User Login Page used prior to Authorization Code Grant Type-->
<!--TODO Currently using form-login, replace with custom login form-->
<http disable-url-rewriting="false"
      xmlns="http://www.springframework.org/schema/security"
      use-expressions="false">
    <access-denied-handler error-page="/login.htm?authorization_error=true"/>
    <intercept-url pattern="/ws/oauth/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/ws/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/ms/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <http-basic entry-point-ref="UserAuthenticationEntryPoint"/>
    <headers disabled="true"/>
		<form-login login-page="/login.htm" default-target-url="/" login-processing-url="/login.htm" authentication-failure-url="/login.htm" />
    <csrf disabled="true"/>
</http>

Here is a copy of our omod. The problematic option is export CDA and then CDA search button.

Sorry @dmgogorza but I could not generate the same error as the the export CDA option is not accepting any patient name :confused: ?

did you tried to run OAuth2 module (gsoc-18 branch) .omod file with following change to WebModuleApplicationContext.xml :

<http disable-url-rewriting="false"
      xmlns="http://www.springframework.org/schema/security"
      use-expressions="false">
    <access-denied-handler error-page="/login.htm?authorization_error=true"/>
    <intercept-url pattern="/ws/oauth/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/ws/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/ms/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <http-basic/>
    <headers disabled="false"/>
    <form-login login-page="/login.htm" default-target-url="/"
                login-processing-url="/login.htm" authentication-failure-url="/login.htm"/>
    <csrf disabled="true"/>
</http>

If you still couldn’t get the cause of issue, then tell me the exact way by which i could generate the same error.

When I modify:

<headers disabled="true"/> by <headers disabled="false"/>

this error happens again: Problem using JQuery with OAuth2 module

For that reason you are not able to select a patient, and it is not possible to arrive at the error.

Using:

<http-basic/>
<headers disabled="true"/>

The problem keeps happening.

Maybe this related to the problem of jquery. :thinking:

Every module has to be assigned a unique identifier what we call the moduleId, this is typically the maven artifact Id of your module in the pom file, what is it?

Also note that OpenMRS isn’t configured out of the box to use spring security.

We take this module as a base: CDAGenerator

I guess we’ll have your same identification.

Hi @wyclif and @pkatopenmrs, thank you very much for replying, what we need is to be able to configure the webModuleApplicationContext.xml file so that it allows ajax to call with the following URL: “/module/CDAGenerator/exportcda.form”, method ‘POST’.

You can do it via xml but annotations are way simpler, the snippet below should be able to get your controller called,

@Controller
public class MyController {
    @RequestMapping(value = "/module/CDAGenerator/exportcda.form", method = RequestMethod.POST)
	public void post() {
       //...your code	
    }
}

Of course you can add a parameter to the method annotated with @RequestBody to read in the posted data, you can use the @ResponseBody annotation on the method and change the return type to send back data.

1 Like

Hello @wyclif, thank you for respondent, we have been able to solve the problem by changing the control as you recommended. Thank you

We only have to solve this problem of changing “true” to “false”. Is it okay that we leave it like this? or if it’s wrong in what way we can do it so that we do not make those mistakes

I mentioned earlier that OpenMRS doesn’t and isn’t configured to use spring security therefore, I’d not expect such features to magically work.