Ognjen Mišić
Ognjen Mišić

Reputation: 1416

Spring Security X509 - 403 Forbidden

I'm attempting to implement authentication of one single client to my spring boot rest API through X509 - client certification. I've created a private key:

openssl genrsa -des3 -out client.key 1024

To create this key I've set some generic password like changeit, and this password was used in all subsequent file creations and requests.

Next, I've created a certificate signing request:

openssl req -new -key client.key -out client.csr

and set the common name localhost (other fields are irrelevant as far as I understand?)

Next, created the certificate using the csr:

openssl x509 -req -days 3650 -in client.csr -signkey client.key -out client.crt

Next, created the Java Truststore:

keytool -import -file client.crt -alias clientCA -keystore truststore.jks

And finally, created the keystore as a .p12 file:

openssl pkcs12 -export -in client.crt -inkey client.key -certfile client.crt -name "clientcert" -out keystore.p12

On the Spring boot(2.0.2 version) side I've got the security configuration class:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.x509();
}

/*
 * localhost is the CN of the client certificate
 */
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
            .withUser("localhost")
            .password("none")
            .roles("USER");
  }
}

and the application.properties file:

server.port=8443
logging.level.root=info

server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=changeit
server.ssl.trust-store=classpath:truststore.jks
server.ssl.trust-store-password=changeit
server.ssl.client-auth=need
security.headers.hsts=NONE

Submitting a get request like

curl -vkE ./keystore.p12:changeit --cert-type P12  "https://localhost:8443/customers/test"

gives me a valid response (purposely changing or omitting the proper cert throw an SSL error), which is good.

NOW: If I try to submit a POST the same way with a request body, like

curl -kiE ./keystore.p12:changeit --cert-type P12 -X POST -H "Content-Type: application/json" --data @req-body.json  "https://localhost:8443/customers"

I get the following response:

HTTP/1.1 403
Set-Cookie: JSESSIONID=106214250C497F20C5F1AA02E554B316; Path=/; Secure; HttpOnly
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Mon, 16 Jul 2018 13:49:43 GMT

{"timestamp":"2018-07-16T13:49:43.335+0000","status":403,"error":"Forbidden","message":"Forbidden","path":"/customers"}%

I have no clue why this is happening (the 403) and am kindly asking for help.

P.S. Submitting any http method other than GET (even the ones the controller does not support): throws the same 403 - Forbidden.

P.P.S. Calling a non-existent resource with a GET returns a nice proper 404 response. So it has something to do with the HTTP method settings somewhere?

Upvotes: 1

Views: 1805

Answers (1)

Ognjen Mišić
Ognjen Mišić

Reputation: 1416

Found out the cause: I disabled the csrf and now it works.

Upvotes: 2

Related Questions