Spring-security: Getting "HTTP 400 Bad Request" instead of "HTTP 401 Unauthorized" for incorrect user credentials

Created on 19 Aug 2018  路  3Comments  路  Source: spring-projects/spring-security

I noticed that Spring security returns HTTP 400 instead of HTTP 401 for a user who gives a wrong password. From what I was reading online it would seem that HTTP 401 is more appropriate than just HTTP 400.

waiting-for-feedback

Most helpful comment

I observed the same issue with spring-security-oauth2-2.3.4.RELEASE.

In the
org.springframework.security.oauth2.provider.password.ResourceOwnerPasswordTokenGranter#getOAuth2Authentication there is even a comment that refers to some spec:

try {
    userAuth = authenticationManager.authenticate(userAuth);
}
catch (AccountStatusException ase) {
    //covers expired, locked, disabled cases (mentioned in section 5.2, draft 31)
    throw new InvalidGrantException(ase.getMessage());
}
catch (BadCredentialsException e) {
    // If the username/password are wrong the spec says we should send 400/invalid grant
    throw new InvalidGrantException(e.getMessage());
}

However, the rfc2616 says

10.4.2 401 Unauthorized

The request requires user authentication. The response MUST include a
WWW-Authenticate header field (section 14.47) containing a challenge
applicable to the requested resource. The client MAY repeat the
request with a suitable Authorization header field (section 14.8). If
the request already included Authorization credentials, then the 401
response indicates that authorization has been refused for those
credentials.

Also, according to rfc2617

If the origin server does not wish to accept the credentials sent
with a request, it SHOULD return a 401 (Unauthorized) response.

All 3 comments

I am unable to produce this with a servlet environment or a WebFlux environment. Can you provide more details on how to reproduce?

I observed the same issue with spring-security-oauth2-2.3.4.RELEASE.

In the
org.springframework.security.oauth2.provider.password.ResourceOwnerPasswordTokenGranter#getOAuth2Authentication there is even a comment that refers to some spec:

try {
    userAuth = authenticationManager.authenticate(userAuth);
}
catch (AccountStatusException ase) {
    //covers expired, locked, disabled cases (mentioned in section 5.2, draft 31)
    throw new InvalidGrantException(ase.getMessage());
}
catch (BadCredentialsException e) {
    // If the username/password are wrong the spec says we should send 400/invalid grant
    throw new InvalidGrantException(e.getMessage());
}

However, the rfc2616 says

10.4.2 401 Unauthorized

The request requires user authentication. The response MUST include a
WWW-Authenticate header field (section 14.47) containing a challenge
applicable to the requested resource. The client MAY repeat the
request with a suitable Authorization header field (section 14.8). If
the request already included Authorization credentials, then the 401
response indicates that authorization has been refused for those
credentials.

Also, according to rfc2617

If the origin server does not wish to accept the credentials sent
with a request, it SHOULD return a 401 (Unauthorized) response.

I got the same issue. Debugged for a while till I found out it's caused by Spring. Don't get it why they put 400 here.

@rwinch please remove the waiting-for-feedback tag as @kmatusiewicz already responses to you.
The question remains: Why does the class ResourceOwnerPasswordTokenGranter treat it as 400 ?

Was this page helpful?
0 / 5 - 0 ratings