// Store it in the session for later validation.
String state = new BigInteger(130, new SecureRandom()).toString(32);
Cookie cookie = new Cookie(CSRF_STATE_COOKIE, sha256Hex(state));
- cookie.setPath("/");
+ cookie.setPath(server.getContextPath() + "/");
cookie.setHttpOnly(true);
cookie.setMaxAge(-1);
cookie.setSecure(server.isSecured());
// remove cookie
stateCookie.setValue(null);
stateCookie.setMaxAge(0);
- stateCookie.setPath("/");
+ stateCookie.setPath(server.getContextPath() + "/");
response.addCookie(stateCookie);
String stateInRequest = request.getParameter("state");
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.sonar.api.platform.Server;
import org.sonar.api.server.authentication.BaseIdentityProvider;
import org.sonar.api.server.authentication.IdentityProvider;
import org.sonar.api.server.authentication.OAuth2IdentityProvider;
private final IdentityProviderRepository identityProviderRepository;
private final BaseContextFactory baseContextFactory;
private final OAuth2ContextFactory oAuth2ContextFactory;
+ private final Server server;
- public InitFilter(IdentityProviderRepository identityProviderRepository, BaseContextFactory baseContextFactory, OAuth2ContextFactory oAuth2ContextFactory) {
+ public InitFilter(IdentityProviderRepository identityProviderRepository, BaseContextFactory baseContextFactory, OAuth2ContextFactory oAuth2ContextFactory, Server server) {
this.identityProviderRepository = identityProviderRepository;
this.baseContextFactory = baseContextFactory;
this.oAuth2ContextFactory = oAuth2ContextFactory;
+ this.server = server;
}
@Override
String requestURI = httpRequest.getRequestURI();
String keyProvider = "";
try {
- keyProvider = extractKeyProvider(requestURI, INIT_CONTEXT);
+ keyProvider = extractKeyProvider(requestURI, server.getContextPath() + INIT_CONTEXT);
IdentityProvider provider = identityProviderRepository.getEnabledByKey(keyProvider);
if (provider instanceof BaseIdentityProvider) {
BaseIdentityProvider baseIdentityProvider = (BaseIdentityProvider) provider;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.sonar.api.CoreProperties;
+import org.sonar.api.platform.Server;
import org.sonar.api.server.authentication.IdentityProvider;
import org.sonar.api.server.authentication.OAuth2IdentityProvider;
import org.sonar.api.server.authentication.UnauthorizedException;
private final IdentityProviderRepository identityProviderRepository;
private final OAuth2ContextFactory oAuth2ContextFactory;
+ private final Server server;
- public OAuth2CallbackFilter(IdentityProviderRepository identityProviderRepository, OAuth2ContextFactory oAuth2ContextFactory) {
+ public OAuth2CallbackFilter(IdentityProviderRepository identityProviderRepository, OAuth2ContextFactory oAuth2ContextFactory, Server server) {
this.identityProviderRepository = identityProviderRepository;
this.oAuth2ContextFactory = oAuth2ContextFactory;
+ this.server = server;
}
@Override
String requestUri = httpRequest.getRequestURI();
String keyProvider = "";
try {
- keyProvider = extractKeyProvider(requestUri, CALLBACK_PATH);
+ keyProvider = extractKeyProvider(requestUri, server.getContextPath() + CALLBACK_PATH);
IdentityProvider provider = identityProviderRepository.getEnabledByKey(keyProvider);
if (provider instanceof OAuth2IdentityProvider) {
OAuth2IdentityProvider oauthProvider = (OAuth2IdentityProvider) provider;
@Override
public void redirectToRequestedPage() {
try {
- getResponse().sendRedirect("/");
+ getResponse().sendRedirect(server.getContextPath() + "/");
} catch (IOException e) {
throw new IllegalStateException("Fail to redirect to home", e);
}
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
CsrfVerifier underTest = new CsrfVerifier(server);
+ @Before
+ public void setUp() throws Exception {
+ when(server.getContextPath()).thenReturn("");
+ }
+
@Test
public void generate_state_on_secured_server() throws Exception {
when(server.isSecured()).thenReturn(true);
assertThat(updatedCookie.getMaxAge()).isEqualTo(0);
}
+ @Test
+ public void verify_state_when_context() throws Exception {
+ String state = "state";
+ when(request.getCookies()).thenReturn(new Cookie[] {new Cookie("OAUTHSTATE", sha256Hex(state))});
+ when(request.getParameter("state")).thenReturn(state);
+ when(server.getContextPath()).thenReturn("/sonarqube");
+
+ underTest.verifyState(request, response);
+
+ verify(response).addCookie(cookieArgumentCaptor.capture());
+ Cookie updatedCookie = cookieArgumentCaptor.getValue();
+ assertThat(updatedCookie.getPath()).isEqualTo("/sonarqube/");
+ }
+
@Test
public void fail_with_unauthorized_when_state_cookie_is_not_the_same_as_state_parameter() throws Exception {
when(request.getCookies()).thenReturn(new Cookie[] {new Cookie("OAUTHSTATE", sha1Hex("state"))});
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import org.sonar.api.platform.Server;
import org.sonar.api.server.authentication.BaseIdentityProvider;
import org.sonar.api.server.authentication.Display;
import org.sonar.api.server.authentication.IdentityProvider;
BaseContextFactory baseContextFactory = mock(BaseContextFactory.class);
OAuth2ContextFactory oAuth2ContextFactory = mock(OAuth2ContextFactory.class);
+ Server server = mock(Server.class);
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
FakeBasicIdentityProvider baseIdentityProvider = new FakeBasicIdentityProvider(BASIC_PROVIDER_KEY, true);
BaseIdentityProvider.Context baseContext = mock(BaseIdentityProvider.Context.class);
- InitFilter underTest = new InitFilter(identityProviderRepository, baseContextFactory, oAuth2ContextFactory);
+ InitFilter underTest = new InitFilter(identityProviderRepository, baseContextFactory, oAuth2ContextFactory, server);
@Before
public void setUp() throws Exception {
when(oAuth2ContextFactory.newContext(request, response, oAuth2IdentityProvider)).thenReturn(oauth2Context);
when(baseContextFactory.newContext(request, response, baseIdentityProvider)).thenReturn(baseContext);
+ when(server.getContextPath()).thenReturn("");
}
@Test
assertThat(underTest.doGetPattern()).isNotNull();
}
+ @Test
+ public void do_filter_with_context() throws Exception {
+ when(server.getContextPath()).thenReturn("/sonarqube");
+ when(request.getRequestURI()).thenReturn("/sonarqube/sessions/init/" + OAUTH2_PROVIDER_KEY);
+ identityProviderRepository.addIdentityProvider(oAuth2IdentityProvider);
+
+ underTest.doFilter(request, response, chain);
+
+ assertOAuth2InitCalled();
+ }
+
@Test
public void do_filter_on_auth2_identity_provider() throws Exception {
when(request.getRequestURI()).thenReturn("/sessions/init/" + OAUTH2_PROVIDER_KEY);
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import org.sonar.api.platform.Server;
import org.sonar.api.server.authentication.OAuth2IdentityProvider;
import org.sonar.api.server.authentication.UnauthorizedException;
import org.sonar.api.utils.log.LogTester;
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
+ Server server = mock(Server.class);
FilterChain chain = mock(FilterChain.class);
FakeOAuth2IdentityProvider oAuth2IdentityProvider = new FakeOAuth2IdentityProvider(OAUTH2_PROVIDER_KEY, true);
OAuth2IdentityProvider.InitContext oauth2Context = mock(OAuth2IdentityProvider.InitContext.class);
- OAuth2CallbackFilter underTest = new OAuth2CallbackFilter(identityProviderRepository, oAuth2ContextFactory);
+ OAuth2CallbackFilter underTest = new OAuth2CallbackFilter(identityProviderRepository, oAuth2ContextFactory, server);
@Before
public void setUp() throws Exception {
when(oAuth2ContextFactory.newContext(request, response, oAuth2IdentityProvider)).thenReturn(oauth2Context);
+ when(server.getContextPath()).thenReturn("");
}
@Test
assertThat(underTest.doGetPattern()).isNotNull();
}
+ @Test
+ public void do_filter_with_context() throws Exception {
+ when(server.getContextPath()).thenReturn("/sonarqube");
+ when(request.getRequestURI()).thenReturn("/sonarqube/oauth2/callback/" + OAUTH2_PROVIDER_KEY);
+ identityProviderRepository.addIdentityProvider(oAuth2IdentityProvider);
+
+ underTest.doFilter(request, response, chain);
+
+ assertCallbackCalled();
+ }
+
@Test
public void do_filter_on_auth2_identity_provider() throws Exception {
when(request.getRequestURI()).thenReturn("/oauth2/callback/" + OAUTH2_PROVIDER_KEY);
@Test
public void redirect_to_requested_page() throws Exception {
+ when(server.getContextPath()).thenReturn("");
OAuth2IdentityProvider.CallbackContext callback = underTest.newCallback(request, response, identityProvider);
callback.redirectToRequestedPage();
verify(response).sendRedirect("/");
}
+ @Test
+ public void redirect_to_requested_page_with_context() throws Exception {
+ when(server.getContextPath()).thenReturn("/sonarqube");
+ OAuth2IdentityProvider.CallbackContext callback = underTest.newCallback(request, response, identityProvider);
+
+ callback.redirectToRequestedPage();
+
+ verify(response).sendRedirect("/sonarqube/");
+ }
+
@Test
public void verify_csrf_state() throws Exception {
OAuth2IdentityProvider.CallbackContext callback = underTest.newCallback(request, response, identityProvider);
style="background-color: <%= provider.getDisplay().getBackgroundColor().to_s %>"
title="Log in with <%= provider.getName().to_s -%>">
<img alt="<%= provider.getName().to_s -%>" width="20" height="20"
- src="<%= provider.getDisplay().getIconPath().to_s -%>">
+ src="<%= ApplicationController.root_context + provider.getDisplay().getIconPath().to_s -%>">
<span>Log in with <%= provider.getName().to_s -%></span>
</a>
</li>