KEYCLOAK-5753 fixed NPE thrown when using custom RequestMatcher
This commit is contained in:
parent
e4a6ee19d1
commit
bb900f9db8
2 changed files with 39 additions and 28 deletions
|
@ -17,7 +17,16 @@
|
||||||
|
|
||||||
package org.keycloak.adapters.springsecurity.authentication;
|
package org.keycloak.adapters.springsecurity.authentication;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.apache.http.HttpHeaders;
|
import org.apache.http.HttpHeaders;
|
||||||
|
import org.keycloak.adapters.AdapterDeploymentContext;
|
||||||
|
import org.keycloak.adapters.spi.HttpFacade;
|
||||||
|
import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
@ -26,17 +35,6 @@ import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.IOException;
|
|
||||||
import org.keycloak.adapters.AdapterDeploymentContext;
|
|
||||||
import org.keycloak.adapters.spi.HttpFacade;
|
|
||||||
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
|
|
||||||
import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a Keycloak {@link AuthenticationEntryPoint authentication entry point}. Uses a
|
* Provides a Keycloak {@link AuthenticationEntryPoint authentication entry point}. Uses a
|
||||||
* {@link RequestMatcher} to determine if the request is an interactive login request or a
|
* {@link RequestMatcher} to determine if the request is an interactive login request or a
|
||||||
|
@ -62,15 +60,14 @@ public class KeycloakAuthenticationEntryPoint implements AuthenticationEntryPoin
|
||||||
private final RequestMatcher apiRequestMatcher;
|
private final RequestMatcher apiRequestMatcher;
|
||||||
private String loginUri = DEFAULT_LOGIN_URI;
|
private String loginUri = DEFAULT_LOGIN_URI;
|
||||||
private String realm = DEFAULT_REALM;
|
private String realm = DEFAULT_REALM;
|
||||||
|
|
||||||
private AdapterDeploymentContext adapterDeploymentContext;
|
private AdapterDeploymentContext adapterDeploymentContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Keycloak authentication entry point.
|
* Creates a new Keycloak authentication entry point.
|
||||||
*/
|
*/
|
||||||
public KeycloakAuthenticationEntryPoint(AdapterDeploymentContext adapterDeploymentContext) {
|
public KeycloakAuthenticationEntryPoint(AdapterDeploymentContext adapterDeploymentContext) {
|
||||||
this(DEFAULT_API_REQUEST_MATCHER);
|
this(adapterDeploymentContext, DEFAULT_API_REQUEST_MATCHER);
|
||||||
this.adapterDeploymentContext = adapterDeploymentContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,14 +77,15 @@ public class KeycloakAuthenticationEntryPoint implements AuthenticationEntryPoin
|
||||||
* @param apiRequestMatcher the <code>RequestMatcher</code> to use to determine
|
* @param apiRequestMatcher the <code>RequestMatcher</code> to use to determine
|
||||||
* if the current request is an API request or a browser request (required)
|
* if the current request is an API request or a browser request (required)
|
||||||
*/
|
*/
|
||||||
public KeycloakAuthenticationEntryPoint(RequestMatcher apiRequestMatcher) {
|
public KeycloakAuthenticationEntryPoint(AdapterDeploymentContext adapterDeploymentContext, RequestMatcher apiRequestMatcher) {
|
||||||
Assert.notNull(apiRequestMatcher, "apiRequestMatcher required");
|
Assert.notNull(apiRequestMatcher, "apiRequestMatcher required");
|
||||||
|
Assert.notNull(adapterDeploymentContext, "adapterDeploymentContext required");
|
||||||
|
this.adapterDeploymentContext = adapterDeploymentContext;
|
||||||
this.apiRequestMatcher = apiRequestMatcher;
|
this.apiRequestMatcher = apiRequestMatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException
|
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
|
||||||
{
|
|
||||||
HttpFacade facade = new SimpleHttpFacade(request, response);
|
HttpFacade facade = new SimpleHttpFacade(request, response);
|
||||||
if (apiRequestMatcher.matches(request) || adapterDeploymentContext.resolveDeployment(facade).isBearerOnly()) {
|
if (apiRequestMatcher.matches(request) || adapterDeploymentContext.resolveDeployment(facade).isBearerOnly()) {
|
||||||
commenceUnauthorizedResponse(request, response);
|
commenceUnauthorizedResponse(request, response);
|
||||||
|
|
|
@ -17,25 +17,27 @@
|
||||||
|
|
||||||
package org.keycloak.adapters.springsecurity.authentication;
|
package org.keycloak.adapters.springsecurity.authentication;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import org.apache.http.HttpHeaders;
|
import org.apache.http.HttpHeaders;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
|
||||||
import org.springframework.mock.web.MockHttpServletResponse;
|
|
||||||
|
|
||||||
import static junit.framework.TestCase.assertNull;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import org.keycloak.adapters.AdapterDeploymentContext;
|
import org.keycloak.adapters.AdapterDeploymentContext;
|
||||||
import org.keycloak.adapters.KeycloakDeployment;
|
import org.keycloak.adapters.KeycloakDeployment;
|
||||||
import org.keycloak.adapters.spi.HttpFacade;
|
import org.keycloak.adapters.spi.HttpFacade;
|
||||||
import static org.mockito.Matchers.any;
|
|
||||||
import static org.mockito.Matchers.eq;
|
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
|
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keycloak authentication entry point tests.
|
* Keycloak authentication entry point tests.
|
||||||
|
@ -47,13 +49,16 @@ public class KeycloakAuthenticationEntryPointTest {
|
||||||
private MockHttpServletResponse response;
|
private MockHttpServletResponse response;
|
||||||
@Mock
|
@Mock
|
||||||
private ApplicationContext applicationContext;
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private AdapterDeploymentContext adapterDeploymentContext;
|
private AdapterDeploymentContext adapterDeploymentContext;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private KeycloakDeployment keycloakDeployment;
|
private KeycloakDeployment keycloakDeployment;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private RequestMatcher requestMatcher;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
@ -101,6 +106,14 @@ public class KeycloakAuthenticationEntryPointTest {
|
||||||
assertEquals(logoutUri, response.getHeader("Location"));
|
assertEquals(logoutUri, response.getHeader("Location"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCommenceWithCustomRequestMatcher() throws Exception {
|
||||||
|
new KeycloakAuthenticationEntryPoint(adapterDeploymentContext, requestMatcher)
|
||||||
|
.commence(request, response, null);
|
||||||
|
|
||||||
|
verify(requestMatcher).matches(request);
|
||||||
|
}
|
||||||
|
|
||||||
private void configureBrowserRequest() {
|
private void configureBrowserRequest() {
|
||||||
request.addHeader(HttpHeaders.ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
|
request.addHeader(HttpHeaders.ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue