1
1
/*
2
- * Copyright 2002-2013 the original author or authors.
2
+ * Copyright 2002-2018 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
23
23
import org .springframework .security .web .access .AccessDeniedHandler ;
24
24
import org .springframework .security .web .access .AccessDeniedHandlerImpl ;
25
25
import org .springframework .security .web .access .ExceptionTranslationFilter ;
26
+ import org .springframework .security .web .access .RequestMatcherDelegatingAccessDeniedHandler ;
26
27
import org .springframework .security .web .authentication .DelegatingAuthenticationEntryPoint ;
27
28
import org .springframework .security .web .authentication .Http403ForbiddenEntryPoint ;
28
29
import org .springframework .security .web .savedrequest .HttpSessionRequestCache ;
@@ -70,6 +71,8 @@ public final class ExceptionHandlingConfigurer<H extends HttpSecurityBuilder<H>>
70
71
71
72
private LinkedHashMap <RequestMatcher , AuthenticationEntryPoint > defaultEntryPointMappings = new LinkedHashMap <>();
72
73
74
+ private LinkedHashMap <RequestMatcher , AccessDeniedHandler > defaultDeniedHandlerMappings = new LinkedHashMap <>();
75
+
73
76
/**
74
77
* Creates a new instance
75
78
* @see HttpSecurity#exceptionHandling()
@@ -104,6 +107,26 @@ public ExceptionHandlingConfigurer<H> accessDeniedHandler(
104
107
return this ;
105
108
}
106
109
110
+ /**
111
+ * Sets a default {@link AccessDeniedHandler} to be used which prefers being
112
+ * invoked for the provided {@link RequestMatcher}. If only a single default
113
+ * {@link AccessDeniedHandler} is specified, it will be what is used for the
114
+ * default {@link AccessDeniedHandler}. If multiple default
115
+ * {@link AccessDeniedHandler} instances are configured, then a
116
+ * {@link RequestMatcherDelegatingAccessDeniedHandler} will be used.
117
+ *
118
+ * @param deniedHandler the {@link AccessDeniedHandler} to use
119
+ * @param preferredMatcher the {@link RequestMatcher} for this default
120
+ * {@link AccessDeniedHandler}
121
+ * @return the {@link ExceptionHandlingConfigurer} for further customizations
122
+ * @since 5.1
123
+ */
124
+ public ExceptionHandlingConfigurer <H > defaultAccessDeniedHandlerFor (
125
+ AccessDeniedHandler deniedHandler , RequestMatcher preferredMatcher ) {
126
+ this .defaultDeniedHandlerMappings .put (preferredMatcher , deniedHandler );
127
+ return this ;
128
+ }
129
+
107
130
/**
108
131
* Sets the {@link AuthenticationEntryPoint} to be used.
109
132
*
@@ -169,13 +192,27 @@ public void configure(H http) throws Exception {
169
192
AuthenticationEntryPoint entryPoint = getAuthenticationEntryPoint (http );
170
193
ExceptionTranslationFilter exceptionTranslationFilter = new ExceptionTranslationFilter (
171
194
entryPoint , getRequestCache (http ));
172
- if (accessDeniedHandler != null ) {
173
- exceptionTranslationFilter .setAccessDeniedHandler (accessDeniedHandler );
174
- }
195
+ AccessDeniedHandler deniedHandler = getAccessDeniedHandler (http );
196
+ exceptionTranslationFilter .setAccessDeniedHandler (deniedHandler );
175
197
exceptionTranslationFilter = postProcess (exceptionTranslationFilter );
176
198
http .addFilter (exceptionTranslationFilter );
177
199
}
178
200
201
+ /**
202
+ * Gets the {@link AccessDeniedHandler} according to the rules specified by
203
+ * {@link #accessDeniedHandler(AccessDeniedHandler)}
204
+ * @param http the {@link HttpSecurity} used to look up shared
205
+ * {@link AccessDeniedHandler}
206
+ * @return the {@link AccessDeniedHandler} to use
207
+ */
208
+ AccessDeniedHandler getAccessDeniedHandler (H http ) {
209
+ AccessDeniedHandler deniedHandler = this .accessDeniedHandler ;
210
+ if (deniedHandler == null ) {
211
+ deniedHandler = createDefaultDeniedHandler (http );
212
+ }
213
+ return deniedHandler ;
214
+ }
215
+
179
216
/**
180
217
* Gets the {@link AuthenticationEntryPoint} according to the rules specified by
181
218
* {@link #authenticationEntryPoint(AuthenticationEntryPoint)}
@@ -191,16 +228,28 @@ AuthenticationEntryPoint getAuthenticationEntryPoint(H http) {
191
228
return entryPoint ;
192
229
}
193
230
231
+ private AccessDeniedHandler createDefaultDeniedHandler (H http ) {
232
+ if (this .defaultDeniedHandlerMappings .isEmpty ()) {
233
+ return new AccessDeniedHandlerImpl ();
234
+ }
235
+ if (this .defaultDeniedHandlerMappings .size () == 1 ) {
236
+ return this .defaultDeniedHandlerMappings .values ().iterator ().next ();
237
+ }
238
+ return new RequestMatcherDelegatingAccessDeniedHandler (
239
+ this .defaultDeniedHandlerMappings ,
240
+ new AccessDeniedHandlerImpl ());
241
+ }
242
+
194
243
private AuthenticationEntryPoint createDefaultEntryPoint (H http ) {
195
- if (defaultEntryPointMappings .isEmpty ()) {
244
+ if (this . defaultEntryPointMappings .isEmpty ()) {
196
245
return new Http403ForbiddenEntryPoint ();
197
246
}
198
- if (defaultEntryPointMappings .size () == 1 ) {
199
- return defaultEntryPointMappings .values ().iterator ().next ();
247
+ if (this . defaultEntryPointMappings .size () == 1 ) {
248
+ return this . defaultEntryPointMappings .values ().iterator ().next ();
200
249
}
201
250
DelegatingAuthenticationEntryPoint entryPoint = new DelegatingAuthenticationEntryPoint (
202
- defaultEntryPointMappings );
203
- entryPoint .setDefaultEntryPoint (defaultEntryPointMappings .values ().iterator ()
251
+ this . defaultEntryPointMappings );
252
+ entryPoint .setDefaultEntryPoint (this . defaultEntryPointMappings .values ().iterator ()
204
253
.next ());
205
254
return entryPoint ;
206
255
}
0 commit comments