Permalink
Browse files

SECOAUTH-212: fix exception rendering

  • Loading branch information...
1 parent 702bcf0 commit 33acf01dccc563c184f897448d7d61ed4aa847ff @dsyer dsyer committed Apr 5, 2012
View
3 .../java/org/springframework/security/oauth2/provider/TestResourceOwnerPasswordProvider.java
@@ -104,6 +104,9 @@ public void testTokenNotGrantedIfSecretNotProvided() throws Exception {
}
catch (HttpClientErrorException e) {
assertEquals(HttpStatus.UNAUTHORIZED, e.getStatusCode());
+ List<String> values = tokenEndpointResponse.getHeaders().get("WWW-Authenticate");
+ assertEquals(1, values.size());
+ assertEquals("Bearer realm=\"sparklr2\", error=\"invalid_token\", error_description=\"Bad Credentials\"", values.get(0));
}
}
View
17 ...pringframework/security/oauth2/provider/error/AbstractOAuth2SecurityExceptionHandler.java
@@ -44,7 +44,7 @@
// This is from Spring MVC.
private HandlerExceptionResolver handlerExceptionResolver = new DefaultHandlerExceptionResolver();
-
+
public void setExceptionTranslator(WebResponseExceptionTranslator exceptionTranslator) {
this.exceptionTranslator = exceptionTranslator;
}
@@ -53,10 +53,11 @@ public void setExceptionRenderer(OAuth2ExceptionRenderer exceptionRenderer) {
this.exceptionRenderer = exceptionRenderer;
}
- protected void doHandle(HttpServletRequest request, HttpServletResponse response, Exception authException)
+ protected final void doHandle(HttpServletRequest request, HttpServletResponse response, Exception authException)
throws IOException, ServletException {
try {
ResponseEntity<OAuth2Exception> result = exceptionTranslator.translate(authException);
+ result = enhanceResponse(result, authException);
exceptionRenderer.handleHttpEntityResponse(result, new ServletWebRequest(request, response));
response.flushBuffer();
}
@@ -79,4 +80,16 @@ protected void doHandle(HttpServletRequest request, HttpServletResponse response
}
}
+ /**
+ * Allow subclasses to manipulate the response before it is rendered.
+ *
+ * @param result the response that was generated by the
+ * {@link #setExceptionTranslator(WebResponseExceptionTranslator) exception translator}.
+ * @param authException the authentication exception that is being handled
+ */
+ protected ResponseEntity<OAuth2Exception> enhanceResponse(ResponseEntity<OAuth2Exception> result,
+ Exception authException) {
+ return result;
+ }
+
}
View
2 ...springframework/security/oauth2/provider/error/DefaultWebResponseExceptionTranslator.java
@@ -78,7 +78,7 @@
HttpHeaders headers = new HttpHeaders();
headers.set("Cache-Control", "no-store");
if (status==HttpStatus.UNAUTHORIZED.value()) {
- headers.set("WWW-Authenticate", String.format("%s, %s", OAuth2AccessToken.BEARER_TYPE, e.getSummary()));
+ headers.set("WWW-Authenticate", String.format("%s %s", OAuth2AccessToken.BEARER_TYPE, e.getSummary()));
}
ResponseEntity<OAuth2Exception> response = new ResponseEntity<OAuth2Exception>(e, headers,
View
42 ...va/org/springframework/security/oauth2/provider/error/OAuth2AuthenticationEntryPoint.java
@@ -18,10 +18,13 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.ResponseEntity;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.security.web.AuthenticationEntryPoint;
+import org.springframework.util.StringUtils;
/**
* If authentication fails and the caller has asked for a specific content type response, this entry point can send one,
@@ -31,7 +34,8 @@
* @author Dave Syer
*
*/
-public class OAuth2AuthenticationEntryPoint extends AbstractOAuth2SecurityExceptionHandler implements AuthenticationEntryPoint {
+public class OAuth2AuthenticationEntryPoint extends AbstractOAuth2SecurityExceptionHandler implements
+ AuthenticationEntryPoint {
private String typeName = OAuth2AccessToken.BEARER_TYPE;
@@ -47,25 +51,35 @@ public void setTypeName(String typeName) {
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
throws IOException, ServletException {
- addAuthenticateHeader(response, authException);
doHandle(request, response, authException);
}
- private void addAuthenticateHeader(HttpServletResponse response, AuthenticationException authException) {
-
- if (response.containsHeader("WWW-Authenticate")) {
- return;
+ @Override
+ protected ResponseEntity<OAuth2Exception> enhanceResponse(ResponseEntity<OAuth2Exception> response, Exception exception) {
+ HttpHeaders headers = response.getHeaders();
+ String existing = null;
+ if (headers.containsKey("WWW-Authenticate")) {
+ existing = extractTypePrefix(headers.getFirst("WWW-Authenticate"));
}
-
- StringBuilder builder = new StringBuilder(String.format("%s realm=\"%s\"", typeName, realmName));
-
- if (authException instanceof OAuth2Exception) {
- OAuth2Exception oauth2Exception = (OAuth2Exception) authException;
- builder.append(", " + oauth2Exception.getSummary());
+ StringBuilder builder = new StringBuilder();
+ builder.append(typeName+" ");
+ builder.append("realm=\"" + realmName + "\"");
+ if (existing!=null) {
+ builder.append(", "+existing);
}
+ HttpHeaders update = new HttpHeaders();
+ update.putAll(response.getHeaders());
+ update.set("WWW-Authenticate", builder.toString());
+ return new ResponseEntity<OAuth2Exception>(response.getBody(), update, response.getStatusCode());
+ }
- response.addHeader("WWW-Authenticate", builder.toString());
-
+ private String extractTypePrefix(String header) {
+ String existing = header;
+ String[] tokens = existing.split(" +");
+ if (tokens.length > 1 && !tokens[0].endsWith(",")) {
+ existing = StringUtils.arrayToDelimitedString(tokens, " ").substring(existing.indexOf(" ") + 1);
+ }
+ return existing;
}
}
View
2 ...rg/springframework/security/oauth2/provider/error/TestOAuth2AuthenticationEntryPoint.java
@@ -63,7 +63,7 @@ public void testCommenceWithXml() throws Exception {
public void testTypeName() throws Exception {
entryPoint.setTypeName("Foo");
entryPoint.commence(request, response, new BadCredentialsException("Bad"));
- assertEquals("Foo realm=\"foo\"", response.getHeader("WWW-Authenticate"));
+ assertEquals("Foo realm=\"foo\", error=\"invalid_token\", error_description=\"Bad\"", response.getHeader("WWW-Authenticate"));
}
@Test

0 comments on commit 33acf01

Please sign in to comment.