diff --git a/config/src/main/java/org/springframework/security/config/http/OAuth2LoginBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/http/OAuth2LoginBeanDefinitionParser.java index 48a6151346..176cdcad0d 100644 --- a/config/src/main/java/org/springframework/security/config/http/OAuth2LoginBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/http/OAuth2LoginBeanDefinitionParser.java @@ -19,7 +19,6 @@ package org.springframework.security.config.http; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -27,11 +26,13 @@ import org.w3c.dom.Element; import org.springframework.beans.BeanMetadataElement; import org.springframework.beans.BeansException; +import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanReference; import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.parsing.BeanComponentDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.ManagedMap; import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.context.ApplicationContext; @@ -57,7 +58,6 @@ import org.springframework.security.web.authentication.DelegatingAuthenticationE import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter; import org.springframework.security.web.util.matcher.AndRequestMatcher; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher; import org.springframework.security.web.util.matcher.NegatedRequestMatcher; import org.springframework.security.web.util.matcher.OrRequestMatcher; @@ -235,7 +235,7 @@ final class OAuth2LoginBeanDefinitionParser implements BeanDefinitionParser { .getBeanDefinition(); } else { - Map entryPoint = getLoginEntryPoint(element); + Map entryPoint = getLoginEntryPoint(element); if (entryPoint != null) { this.oauth2LoginAuthenticationEntryPoint = BeanDefinitionBuilder .rootBeanDefinition(DelegatingAuthenticationEntryPoint.class) @@ -364,42 +364,35 @@ final class OAuth2LoginBeanDefinitionParser implements BeanDefinitionParser { return this.oauth2LoginLinks; } - private Map getLoginEntryPoint(Element element) { - Map entryPoints = null; + private Map getLoginEntryPoint(Element element) { + Map entryPoints = null; Element clientRegsElt = DomUtils.getChildElementByTagName(element.getOwnerDocument().getDocumentElement(), Elements.CLIENT_REGISTRATIONS); if (clientRegsElt != null) { List clientRegList = DomUtils.getChildElementsByTagName(clientRegsElt, ELT_CLIENT_REGISTRATION); if (clientRegList.size() == 1) { - RequestMatcher loginPageMatcher = new AntPathRequestMatcher(DEFAULT_LOGIN_URI); - RequestMatcher faviconMatcher = new AntPathRequestMatcher("/favicon.ico"); - RequestMatcher defaultEntryPointMatcher = this.getAuthenticationEntryPointMatcher(); - RequestMatcher defaultLoginPageMatcher = new AndRequestMatcher( - new OrRequestMatcher(loginPageMatcher, faviconMatcher), defaultEntryPointMatcher); - RequestMatcher notXRequestedWith = new NegatedRequestMatcher( - new RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest")); + BeanDefinition loginPageMatcher = BeanDefinitionBuilder + .rootBeanDefinition(RequestMatcherFactoryBean.class) + .addConstructorArgValue(DEFAULT_LOGIN_URI) + .getBeanDefinition(); + BeanDefinition faviconMatcher = BeanDefinitionBuilder + .rootBeanDefinition(RequestMatcherFactoryBean.class) + .addConstructorArgValue("/favicon.ico") + .getBeanDefinition(); + BeanDefinition entryPointMatcher = BeanDefinitionBuilder + .rootBeanDefinition(EntryPointMatcherFactoryBean.class) + .addConstructorArgValue(loginPageMatcher) + .addConstructorArgValue(faviconMatcher) + .getBeanDefinition(); Element clientRegElt = clientRegList.get(0); - entryPoints = new LinkedHashMap<>(); - entryPoints.put( - new AndRequestMatcher(notXRequestedWith, new NegatedRequestMatcher(defaultLoginPageMatcher)), - new LoginUrlAuthenticationEntryPoint(DEFAULT_AUTHORIZATION_REQUEST_BASE_URI + "/" - + clientRegElt.getAttribute(ATT_REGISTRATION_ID))); + entryPoints = new ManagedMap<>(); + entryPoints.put(entryPointMatcher, new LoginUrlAuthenticationEntryPoint( + DEFAULT_AUTHORIZATION_REQUEST_BASE_URI + "/" + clientRegElt.getAttribute(ATT_REGISTRATION_ID))); } } return entryPoints; } - private RequestMatcher getAuthenticationEntryPointMatcher() { - ContentNegotiationStrategy contentNegotiationStrategy = new HeaderContentNegotiationStrategy(); - MediaTypeRequestMatcher mediaMatcher = new MediaTypeRequestMatcher(contentNegotiationStrategy, - MediaType.APPLICATION_XHTML_XML, new MediaType("image", "*"), MediaType.TEXT_HTML, - MediaType.TEXT_PLAIN); - mediaMatcher.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL)); - RequestMatcher notXRequestedWith = new NegatedRequestMatcher( - new RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest")); - return new AndRequestMatcher(Arrays.asList(notXRequestedWith, mediaMatcher)); - } - private static class OidcAuthenticationRequestChecker implements AuthenticationProvider { @Override @@ -463,4 +456,42 @@ final class OAuth2LoginBeanDefinitionParser implements BeanDefinitionParser { } + @Deprecated + static class EntryPointMatcherFactoryBean implements FactoryBean { + + private final RequestMatcher entryPointMatcher; + + EntryPointMatcherFactoryBean(RequestMatcher loginPageMatcher, RequestMatcher faviconMatcher) { + RequestMatcher defaultEntryPointMatcher = getAuthenticationEntryPointMatcher(); + RequestMatcher defaultLoginPageMatcher = new AndRequestMatcher( + new OrRequestMatcher(loginPageMatcher, faviconMatcher), defaultEntryPointMatcher); + RequestMatcher notXRequestedWith = new NegatedRequestMatcher( + new RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest")); + this.entryPointMatcher = new AndRequestMatcher(notXRequestedWith, + new NegatedRequestMatcher(defaultLoginPageMatcher)); + } + + private RequestMatcher getAuthenticationEntryPointMatcher() { + ContentNegotiationStrategy contentNegotiationStrategy = new HeaderContentNegotiationStrategy(); + MediaTypeRequestMatcher mediaMatcher = new MediaTypeRequestMatcher(contentNegotiationStrategy, + MediaType.APPLICATION_XHTML_XML, new MediaType("image", "*"), MediaType.TEXT_HTML, + MediaType.TEXT_PLAIN); + mediaMatcher.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL)); + RequestMatcher notXRequestedWith = new NegatedRequestMatcher( + new RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest")); + return new AndRequestMatcher(Arrays.asList(notXRequestedWith, mediaMatcher)); + } + + @Override + public RequestMatcher getObject() { + return this.entryPointMatcher; + } + + @Override + public Class getObjectType() { + return RequestMatcher.class; + } + + } + }