From 86a28db5cc5cd3076f5feb1f8a0c8ad882c63aff Mon Sep 17 00:00:00 2001 From: Daniel Paniagua Date: Tue, 1 Mar 2016 17:25:59 -0500 Subject: [PATCH] Added support of different servlet root paths for the Authn RequestFilter --- openid-connect-server/pom.xml | 6 + .../filter/AuthorizationRequestFilter.java | 23 ++- .../AuthorizationRequestFilterTest.java | 146 ++++++++++++++++++ pom.xml | 5 + 4 files changed, 177 insertions(+), 3 deletions(-) create mode 100644 openid-connect-server/src/test/java/org/mitre/openid/connect/filter/AuthorizationRequestFilterTest.java diff --git a/openid-connect-server/pom.xml b/openid-connect-server/pom.xml index b50b1a089f..dc9ae4b2af 100644 --- a/openid-connect-server/pom.xml +++ b/openid-connect-server/pom.xml @@ -47,6 +47,12 @@ spring-tx + + javax.servlet + javax.servlet-api + test + + OpenID Connect server libraries for Spring and Spring Security. diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/filter/AuthorizationRequestFilter.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/filter/AuthorizationRequestFilter.java index 230488f372..8f1f88b8cc 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/filter/AuthorizationRequestFilter.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/filter/AuthorizationRequestFilter.java @@ -15,7 +15,7 @@ * limitations under the License. *******************************************************************************/ /** - * + * */ package org.mitre.openid.connect.filter; @@ -71,6 +71,7 @@ public class AuthorizationRequestFilter extends GenericFilterBean { public final static String PROMPTED = "PROMPT_FILTER_PROMPTED"; public final static String PROMPT_REQUESTED = "PROMPT_FILTER_REQUESTED"; + private static final String AUTHORIZE_URL = "/authorize"; @Autowired private OAuth2RequestFactory authRequestFactory; @@ -85,7 +86,7 @@ public class AuthorizationRequestFilter extends GenericFilterBean { private LoginHintExtracter loginHintExtracter = new RemoveLoginHintsWithHTTP(); /** - * + * */ @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { @@ -95,7 +96,7 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) HttpSession session = request.getSession(); // skip everything that's not an authorize URL - if (!request.getServletPath().startsWith("/authorize")) { + if (!isAuthorizeUrl(request)) { chain.doFilter(req, res); return; } @@ -229,6 +230,22 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) } } + /** + * Checks is given request is a authentication request url + * + * @param request + * @return + */ + private boolean isAuthorizeUrl(HttpServletRequest request) { + if (AUTHORIZE_URL.equals(request.getPathInfo())) { + return true; + } + if (request.getServletPath().startsWith(AUTHORIZE_URL)) { + return true; + } + return false; + } + /** * @param parameterMap * @return diff --git a/openid-connect-server/src/test/java/org/mitre/openid/connect/filter/AuthorizationRequestFilterTest.java b/openid-connect-server/src/test/java/org/mitre/openid/connect/filter/AuthorizationRequestFilterTest.java new file mode 100644 index 0000000000..481609dc33 --- /dev/null +++ b/openid-connect-server/src/test/java/org/mitre/openid/connect/filter/AuthorizationRequestFilterTest.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright 2016 The MITRE Corporation + * and the MIT Internet Trust Consortium + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ +/** + * + */ +package org.mitre.openid.connect.filter; + +import org.junit.Before; +import org.junit.Test; +import org.mitre.oauth2.service.ClientDetailsEntityService; +import org.mockito.*; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.security.oauth2.provider.AuthorizationRequest; +import org.springframework.security.oauth2.provider.ClientDetails; +import org.springframework.security.oauth2.provider.OAuth2RequestFactory; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import javax.servlet.FilterChain; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import java.util.Map; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; + +/** + * @author dpaniagua + */ +public class AuthorizationRequestFilterTest { + + @InjectMocks + private AuthorizationRequestFilter authorizationRequestFilter; + + @Mock + private OAuth2RequestFactory oAuth2RequestFactory; + + @Mock + private ClientDetails clientDetails; + + @Mock + private ClientDetailsEntityService clientDetailsService; + + @Mock + private FilterChain springSecurityFilterChain; + + @Mock + AuthorizationRequest authorizationRequest; + + ArgumentCaptor argumentCaptor; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + argumentCaptor = ArgumentCaptor.forClass(Map.class); + Mockito.when(oAuth2RequestFactory.createAuthorizationRequest(argumentCaptor.capture())).thenReturn + (authorizationRequest); + } + + @Test() + public void testDoFilter_outsideRootServletPath() throws Exception { + + // given + String baseUrl = "https://server.example.com/oidc/authorize"; + + MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.get(baseUrl); + requestBuilder.servletPath("/oidc") + .param("response_type", "code") + .param("scope", "openid") + .param("redirect_uri", "https://client.example.org/"); + MockHttpServletRequest request = requestBuilder.buildRequest(null); + + //when + authorizationRequestFilter.doFilter(request, null, springSecurityFilterChain); + //then + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Map.class); + Mockito.verify(oAuth2RequestFactory, times(1)).createAuthorizationRequest(argumentCaptor.capture()); + Mockito.verify(springSecurityFilterChain, times(1)).doFilter(any(ServletRequest.class), any(ServletResponse + .class)); + } + + @Test() + public void testDoFilter_RootServletPath() throws Exception { + + // given + // Values Taken from spec sample: http://openid.net/specs/openid-connect-core-1_0.html + String baseUrl = "https://server.example.com/authorize"; + + MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.get(baseUrl); + + requestBuilder.servletPath("/authorize") + .param("response_type", "code") + .param("scope", "openid") + .param("redirect_uri", "https://client.example.org/"); + MockHttpServletRequest request = requestBuilder.buildRequest(null); + + //when + authorizationRequestFilter.doFilter(request, null, springSecurityFilterChain); + + //then + assertThat(request.getServletPath(), is(equalTo("/authorize"))); + Mockito.verify(oAuth2RequestFactory, times(1)).createAuthorizationRequest(any(Map.class)); + Mockito.verify(springSecurityFilterChain, times(1)).doFilter(any(ServletRequest.class), any(ServletResponse + .class)); + } + + @Test() + public void testDoFilter_withInValidUrl() throws Exception { + + // given + String baseUrl = "https://server.example.com/authorize/something/else"; + + MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.get(baseUrl); + requestBuilder.param("response_type", "code") + .param("scope", "openid") + .servletPath("/authorize") + .param("redirect_uri", "https://client.example.org/"); + MockHttpServletRequest request = requestBuilder.buildRequest(null); + + //when + authorizationRequestFilter.doFilter(request, null, springSecurityFilterChain); + + //then + Mockito.verify(oAuth2RequestFactory, times(1)).createAuthorizationRequest(any(Map.class)); + Mockito.verify(springSecurityFilterChain, times(1)).doFilter(any(ServletRequest.class), any(ServletResponse + .class)); + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 0f00ea1175..3dc53a8736 100644 --- a/pom.xml +++ b/pom.xml @@ -409,6 +409,11 @@ 1.9.5 test + + javax.servlet + javax.servlet-api + 3.0.1 +