3939import org .springframework .boot .actuate .endpoint .mvc .MvcEndpoints ;
4040import org .springframework .boot .autoconfigure .condition .ConditionalOnBean ;
4141import org .springframework .boot .autoconfigure .condition .ConditionalOnClass ;
42+ import org .springframework .boot .autoconfigure .condition .ConditionalOnMissingClass ;
4243import org .springframework .boot .autoconfigure .condition .SearchStrategy ;
4344import org .springframework .boot .autoconfigure .web .ErrorAttributes ;
4445import org .springframework .boot .autoconfigure .web .HttpMessageConverters ;
5051import org .springframework .context .annotation .Bean ;
5152import org .springframework .context .annotation .Configuration ;
5253import org .springframework .security .config .annotation .web .configuration .EnableWebSecurity ;
54+ import org .springframework .security .config .annotation .web .configuration .WebSecurityConfigurerAdapter ;
5355import org .springframework .web .servlet .DispatcherServlet ;
5456import org .springframework .web .servlet .HandlerAdapter ;
5557import org .springframework .web .servlet .HandlerMapping ;
@@ -133,40 +135,6 @@ public HandlerAdapter handlerAdapter(HttpMessageConverters converters) {
133135 return adapter ;
134136 }
135137
136- @ Bean
137- public HandlerMapping handlerMapping (MvcEndpoints endpoints ,
138- ListableBeanFactory beanFactory ) {
139- Set <MvcEndpoint > set = new HashSet <MvcEndpoint >(endpoints .getEndpoints ());
140- set .addAll (beanFactory .getBeansOfType (MvcEndpoint .class ).values ());
141- EndpointHandlerMapping mapping = new EndpointHandlerMapping (set );
142- // In a child context we definitely want to see the parent endpoints
143- mapping .setDetectHandlerMethodsInAncestorContexts (true );
144- injectIntoSecurityFilter (beanFactory , mapping );
145- if (this .mappingCustomizers != null ) {
146- for (EndpointHandlerMappingCustomizer customizer : this .mappingCustomizers ) {
147- customizer .customize (mapping );
148- }
149- }
150- return mapping ;
151- }
152-
153- private void injectIntoSecurityFilter (ListableBeanFactory beanFactory ,
154- EndpointHandlerMapping mapping ) {
155- // The parent context has the security filter, so we need to get it injected with
156- // our EndpointHandlerMapping if we can.
157- if (BeanFactoryUtils .beanNamesForTypeIncludingAncestors (beanFactory ,
158- ManagementWebSecurityConfigurerAdapter .class ).length == 1 ) {
159- ManagementWebSecurityConfigurerAdapter bean = beanFactory
160- .getBean (ManagementWebSecurityConfigurerAdapter .class );
161- bean .setEndpointHandlerMapping (mapping );
162- }
163- else {
164- logger .warn ("No single bean of type "
165- + ManagementWebSecurityConfigurerAdapter .class .getSimpleName ()
166- + " found (this might make some endpoints inaccessible without authentication)" );
167- }
168- }
169-
170138 /*
171139 * The error controller is present but not mapped as an endpoint in this context
172140 * because of the DispatcherServlet having had it's HandlerMapping explicitly
@@ -177,6 +145,71 @@ public ManagementErrorEndpoint errorEndpoint(final ErrorAttributes errorAttribut
177145 return new ManagementErrorEndpoint (this .errorPath , errorAttributes );
178146 }
179147
148+ @ Configuration
149+ @ ConditionalOnMissingClass (WebSecurityConfigurerAdapter .class )
150+ static class EndpointHandlerMappingSimpleConfiguration {
151+
152+ @ Autowired (required = false )
153+ private List <EndpointHandlerMappingCustomizer > mappingCustomizers ;
154+
155+ @ Bean
156+ public HandlerMapping handlerMapping (MvcEndpoints endpoints ,
157+ ListableBeanFactory beanFactory ) {
158+
159+ EndpointHandlerMapping mapping = doCreateEndpointHandlerMapping (endpoints , beanFactory );
160+ if (this .mappingCustomizers != null ) {
161+ for (EndpointHandlerMappingCustomizer customizer : this .mappingCustomizers ) {
162+ customizer .customize (mapping );
163+ }
164+ }
165+ return mapping ;
166+ }
167+
168+ protected EndpointHandlerMapping doCreateEndpointHandlerMapping (MvcEndpoints endpoints ,
169+ ListableBeanFactory beanFactory ) {
170+ Set <MvcEndpoint > set = new HashSet <MvcEndpoint >(endpoints .getEndpoints ());
171+ set .addAll (beanFactory .getBeansOfType (MvcEndpoint .class ).values ());
172+ EndpointHandlerMapping mapping = new EndpointHandlerMapping (set );
173+ // In a child context we definitely want to see the parent endpoints
174+ mapping .setDetectHandlerMethodsInAncestorContexts (true );
175+ return mapping ;
176+ }
177+
178+ }
179+
180+ @ Configuration
181+ @ ConditionalOnClass (WebSecurityConfigurerAdapter .class )
182+ static class EndpointHandlerMappingSecurityConfiguration
183+ extends EndpointHandlerMappingSimpleConfiguration {
184+
185+ @ Override
186+ protected EndpointHandlerMapping doCreateEndpointHandlerMapping (MvcEndpoints endpoints ,
187+ ListableBeanFactory beanFactory ) {
188+
189+ EndpointHandlerMapping mapping = super .doCreateEndpointHandlerMapping (endpoints , beanFactory );
190+ injectIntoSecurityFilter (beanFactory , mapping );
191+ return mapping ;
192+ }
193+
194+ private void injectIntoSecurityFilter (ListableBeanFactory beanFactory ,
195+ EndpointHandlerMapping mapping ) {
196+ // The parent context has the security filter, so we need to get it injected with
197+ // our EndpointHandlerMapping if we can.
198+ if (BeanFactoryUtils .beanNamesForTypeIncludingAncestors (beanFactory ,
199+ ManagementWebSecurityConfigurerAdapter .class ).length == 1 ) {
200+ ManagementWebSecurityConfigurerAdapter bean = beanFactory
201+ .getBean (ManagementWebSecurityConfigurerAdapter .class );
202+ bean .setEndpointHandlerMapping (mapping );
203+ }
204+ else {
205+ logger .warn ("No single bean of type "
206+ + ManagementWebSecurityConfigurerAdapter .class .getSimpleName ()
207+ + " found (this might make some endpoints inaccessible without authentication)" );
208+ }
209+ }
210+
211+ }
212+
180213 @ Configuration
181214 @ ConditionalOnClass ({ EnableWebSecurity .class , Filter .class })
182215 @ ConditionalOnBean (name = "springSecurityFilterChain" , search = SearchStrategy .PARENTS )
0 commit comments