Steps to reproduce:
1. Get this sample application: https://github.com/spring-guides/gs-convert-jar-to-war-maven/tree/master/complete .
2. Add spring-boot-starter-security
to pom.xml .
3. mvn package
to get the WAR file.
4. Deploy the WAR file to a servlet container (I tried Tomcat and Websphere).
5. curl --user invalid:credentials http://localhost:10080/gs-convert-jar-to-war-maven/
(I have tomcat running on port 10080)
The output is:
<html><head><title>Apache Tomcat/7.0.54 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 401 - Bad credentials</h1><HR size="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u>Bad credentials</u></p><p><b>description</b> <u>This request requires HTTP authentication.</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/7.0.54</h3></body></html>
Notes:
- The bug only happens with "Bad Credentials". Other errors are handled correctly, for example:curl http://localhost:10080/gs-convert-jar-to-war-maven/
(no user credentials supplied)
{"timestamp":1410409793317,"status":401,"error":"Unauthorized","message":"Full authentication is required to access this resource"}
- The bug only happens when deployed as a WAR file, running the application directly using java -jar
does not trigger the bug. For example: curl --user invalid:credentials http://localhost:8080/
{"timestamp":1410410056046,"status":401,"error":"Unauthorized","message":"Bad credentials","path":"/"}
Comment From: dsyer
Would you mind trying that with Spring Boot 1.1.6.RELEASE, please?
Comment From: imgx64
Same result with 1.1.6.RELEASE and 1.2.0.BUILD-SNAPSHOT .
Comment From: dsyer
Works for me (I get JSON) with 1.1.6.RELEASE (and 1.1.7.BUILD-SNAPSHOT) and Tomcat 7.0.47 (but there's no reason to suspect the server version would affect anything). Can you post your war file somewhere?
Comment From: imgx64
Here: https://docs.google.com/uc?id=0B4x4sp-4PxtDNWlLZnlQVld0Yms&export=download
Comment From: dsyer
Still works for me. What server versions are you using?
Comment From: imgx64
Tomcat 7.0.54 and Websphere 8.0.0.9.
Can you post the exact curl command that you used? As I mentioned above, it only happens for one error and not the others (when the user credentials are wrong, not missing)
Comment From: dsyer
Ah. I missed that. Odd, but at least I can reproduce it now.
Comment From: imgx64
This bug still happens if you have a "@EnableWebSecurity" configuration.
I also think that hardcoding "/error" is wrong. Shouldn't the path be taken from ErrorController.getErrorPath()
? Its documentation clearly states:
Primarily used to know the error paths that will not need to be secured.
BasicErrorController.getErrorPath()
(the ErrorController registered by default) already returns "/error".
Comment From: dsyer
Good catch on the error controller (fixed that). What did you mean about @EnableWebSecurity
? Since that switches off Spring Boot autoconfig for security, I might believe that would behave differently, but please elucidate (preferably with a sample project).
Comment From: imgx64
Adding the following class to the gs-convert-jar-to-war-maven project re-reproduces the bug:
package hello;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated();
http.httpBasic();
}
}
Comment From: dsyer
Yeah, but that switches off the Boot security config, and then you don't explicitly ignore /error, so there is no option for Tomcat but to render its own error page. There's nothing we can do about that, as far as I understand it, but you can fix it easily, either by not using @EnableWebSecurity
or by adding /error to your ignored paths.
Comment From: imgx64
But it works correctly when Tomcat is embedded (java -jar ...). What's the difference between the two?
Comment From: dsyer
The difference is that the ErrorPageFilter
is not needed in an embedded server, so there's no need to try and forward to the error page. I doubt if there is a way round that, but suggestions are more than welcome.
Comment From: imgx64
I see, thanks for the help. I guess I'll add /error to my ignored paths in my application.
Comment From: mikymigs
I see, thanks for the help. I guess I'll add /error to my ignored paths in my application.
I know this is old, but how do you do that? (ignore /error)