Skip to content
This repository has been archived by the owner on Apr 5, 2022. It is now read-only.

Send HTTP status code 401 to the response when token can not be acquired #145

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package org.springframework.cloud.security.oauth2.proxy;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.springframework.cloud.security.oauth2.proxy.ProxyAuthenticationProperties.Route;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.client.OAuth2RestOperations;
import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;

Expand All @@ -21,6 +22,7 @@
* can detect the token as part of the currently authenticated principal.
*
* @author Dave Syer
* @author Davy Steegen
*
*/
public class OAuth2TokenRelayFilter extends ZuulFilter {
Expand Down Expand Up @@ -91,12 +93,12 @@ private String getAccessToken(RequestContext ctx) {
try {
value = restTemplate.getAccessToken().getValue();
}
catch (Exception e) {
// Quite possibly a UserRedirectRequiredException, but the caller
// probably doesn't know how to handle it, otherwise they wouldn't be
// using this filter, so we rethrow as an authentication exception
ctx.set("error.status_code", HttpServletResponse.SC_UNAUTHORIZED);
throw new BadCredentialsException("Cannot obtain valid access token");
catch (UserRedirectRequiredException urre) {
try {
ctx.getResponse().sendError(HttpServletResponse.SC_UNAUTHORIZED);
} catch (IOException e) {
throw new RuntimeException("Unable to send error to the response", e);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,22 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.HashMap;

import javax.servlet.http.HttpServletResponse;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.client.OAuth2RestOperations;
import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException;
import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.provider.AuthorizationRequest;
Expand Down Expand Up @@ -62,6 +66,9 @@ public void init() {
httpRequest.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_TYPE, "bearer");
httpRequest.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_VALUE, "FOO");
auth.setDetails(new OAuth2AuthenticationDetails(httpRequest));

RequestContext.testSetCurrentContext(new RequestContext());
RequestContext.getCurrentContext().setResponse(new MockHttpServletResponse());
}

@After
Expand Down Expand Up @@ -117,20 +124,13 @@ public void unauthorizedWithRestTemplate() {
AuthorizationCodeResourceDetails resource = new AuthorizationCodeResourceDetails();
resource.setClientId("client");
Mockito.when(restTemplate.getResource()).thenReturn(resource);
Mockito.when(restTemplate.getAccessToken()).thenThrow(new RuntimeException());
Mockito.when(restTemplate.getAccessToken()).thenThrow(new UserRedirectRequiredException("http://login", new HashMap<String, String>()));
filter.setRestTemplate(restTemplate);
assertNotNull(RequestContext.getCurrentContext());
SecurityContextHolder.getContext().setAuthentication(auth);
assertTrue(filter.shouldFilter());
try {
filter.run();
fail("Expected BadCredentialsException");
}
catch (BadCredentialsException e) {
assertEquals(401,
RequestContext.getCurrentContext().get("error.status_code"));

}
filter.run();
assertEquals(RequestContext.getCurrentContext().getResponse().getStatus(), HttpServletResponse.SC_UNAUTHORIZED);
}

}