16
16
17
17
package org .springframework .security .config .method ;
18
18
19
- import java .lang .reflect .Method ;
20
19
import java .util .List ;
21
20
import java .util .Map ;
22
- import java .util .function .Supplier ;
23
21
24
- import org .aopalliance .intercept .MethodInvocation ;
25
22
import org .w3c .dom .Element ;
26
23
import org .w3c .dom .Node ;
27
24
28
- import org .springframework .aop .ClassFilter ;
29
- import org .springframework .aop .MethodMatcher ;
30
25
import org .springframework .aop .Pointcut ;
31
26
import org .springframework .aop .config .AbstractInterceptorDrivenBeanDefinitionDecorator ;
32
- import org .springframework .aop .support .AopUtils ;
33
- import org .springframework .aop .support .RootClassFilter ;
34
27
import org .springframework .beans .BeanMetadataElement ;
35
28
import org .springframework .beans .factory .config .BeanDefinition ;
36
29
import org .springframework .beans .factory .config .BeanDefinitionHolder ;
41
34
import org .springframework .beans .factory .support .RootBeanDefinition ;
42
35
import org .springframework .beans .factory .xml .BeanDefinitionDecorator ;
43
36
import org .springframework .beans .factory .xml .ParserContext ;
44
- import org .springframework .expression .EvaluationContext ;
45
- import org .springframework .expression .Expression ;
46
- import org .springframework .expression .spel .standard .SpelExpressionParser ;
47
37
import org .springframework .security .access .SecurityConfig ;
48
- import org .springframework .security .access .expression .ExpressionUtils ;
49
- import org .springframework .security .access .expression .SecurityExpressionHandler ;
50
- import org .springframework .security .access .expression .method .DefaultMethodSecurityExpressionHandler ;
51
38
import org .springframework .security .access .intercept .aopalliance .MethodSecurityInterceptor ;
52
39
import org .springframework .security .access .method .MapBasedMethodSecurityMetadataSource ;
53
- import org .springframework .security .authorization .AuthorizationDecision ;
54
- import org .springframework .security .authorization .AuthorizationManager ;
55
40
import org .springframework .security .authorization .method .AuthorizationManagerBeforeMethodInterceptor ;
41
+ import org .springframework .security .authorization .method .MethodExpressionAuthorizationManager ;
56
42
import org .springframework .security .config .BeanIds ;
57
43
import org .springframework .security .config .Elements ;
58
- import org .springframework .security .core .Authentication ;
59
- import org .springframework .security .web .access .expression .ExpressionAuthorizationDecision ;
60
- import org .springframework .util .Assert ;
61
- import org .springframework .util .ClassUtils ;
62
44
import org .springframework .util .StringUtils ;
63
45
import org .springframework .util .xml .DomUtils ;
64
46
@@ -93,8 +75,6 @@ static class InternalAuthorizationManagerInterceptMethodsBeanDefinitionDecorator
93
75
94
76
private static final String ATT_AUTHORIZATION_MGR = "authorization-manager-ref" ;
95
77
96
- private final ClassLoader beanClassLoader = ClassUtils .getDefaultClassLoader ();
97
-
98
78
@ Override
99
79
protected BeanDefinition createInterceptorDefinition (Node node ) {
100
80
Element interceptMethodsElt = (Element ) node ;
@@ -121,8 +101,8 @@ boolean supports(Node node) {
121
101
122
102
private Pointcut pointcut (Element interceptorElt , Element protectElt ) {
123
103
String method = protectElt .getAttribute (ATT_METHOD );
124
- Class <?> javaType = javaType ( interceptorElt , method );
125
- return new PrefixBasedMethodMatcher ( javaType , method );
104
+ String parentBeanClass = (( Element ) interceptorElt . getParentNode ()). getAttribute ( "class" );
105
+ return PrefixBasedMethodMatcher . fromClass ( parentBeanClass , method );
126
106
}
127
107
128
108
private BeanMetadataElement authorizationManager (Element interceptMethodsElt , Element protectElt ) {
@@ -131,129 +111,15 @@ private BeanMetadataElement authorizationManager(Element interceptMethodsElt, El
131
111
return new RuntimeBeanReference (authorizationManager );
132
112
}
133
113
String access = protectElt .getAttribute (ATT_ACCESS );
134
- SpelExpressionParser parser = new SpelExpressionParser ();
135
- Expression expression = parser .parseExpression (access );
136
114
return BeanDefinitionBuilder .rootBeanDefinition (MethodExpressionAuthorizationManager .class )
137
- .addConstructorArgValue (expression ).getBeanDefinition ();
115
+ .addConstructorArgValue (access ).getBeanDefinition ();
138
116
}
139
117
140
118
private BeanMetadataElement authorizationManager (Map <Pointcut , BeanMetadataElement > managers ) {
141
- return BeanDefinitionBuilder .rootBeanDefinition (PointcutMatchingAuthorizationManager .class )
119
+ return BeanDefinitionBuilder .rootBeanDefinition (PointcutDelegatingAuthorizationManager .class )
142
120
.addConstructorArgValue (managers ).getBeanDefinition ();
143
121
}
144
122
145
- private Class <?> javaType (Element interceptMethodsElt , String method ) {
146
- int lastDotIndex = method .lastIndexOf ("." );
147
- String parentBeanClass = ((Element ) interceptMethodsElt .getParentNode ()).getAttribute ("class" );
148
- Assert .isTrue (lastDotIndex != -1 || StringUtils .hasText (parentBeanClass ),
149
- () -> "'" + method + "' is not a valid method name: format is FQN.methodName" );
150
- if (lastDotIndex == -1 ) {
151
- return ClassUtils .resolveClassName (parentBeanClass , this .beanClassLoader );
152
- }
153
- String methodName = method .substring (lastDotIndex + 1 );
154
- Assert .hasText (methodName , () -> "Method not found for '" + method + "'" );
155
- String typeName = method .substring (0 , lastDotIndex );
156
- return ClassUtils .resolveClassName (typeName , this .beanClassLoader );
157
- }
158
-
159
- private static class PrefixBasedMethodMatcher implements MethodMatcher , Pointcut {
160
-
161
- private final ClassFilter classFilter ;
162
-
163
- private final String methodPrefix ;
164
-
165
- PrefixBasedMethodMatcher (Class <?> javaType , String methodPrefix ) {
166
- this .classFilter = new RootClassFilter (javaType );
167
- this .methodPrefix = methodPrefix ;
168
- }
169
-
170
- @ Override
171
- public ClassFilter getClassFilter () {
172
- return this .classFilter ;
173
- }
174
-
175
- @ Override
176
- public MethodMatcher getMethodMatcher () {
177
- return this ;
178
- }
179
-
180
- @ Override
181
- public boolean matches (Method method , Class <?> targetClass ) {
182
- return matches (this .methodPrefix , method .getName ());
183
- }
184
-
185
- @ Override
186
- public boolean isRuntime () {
187
- return false ;
188
- }
189
-
190
- @ Override
191
- public boolean matches (Method method , Class <?> targetClass , Object ... args ) {
192
- return matches (this .methodPrefix , method .getName ());
193
- }
194
-
195
- private boolean matches (String mappedName , String methodName ) {
196
- boolean equals = methodName .equals (mappedName );
197
- return equals || prefixMatches (mappedName , methodName ) || suffixMatches (mappedName , methodName );
198
- }
199
-
200
- private boolean prefixMatches (String mappedName , String methodName ) {
201
- return mappedName .endsWith ("*" )
202
- && methodName .startsWith (mappedName .substring (0 , mappedName .length () - 1 ));
203
- }
204
-
205
- private boolean suffixMatches (String mappedName , String methodName ) {
206
- return mappedName .startsWith ("*" ) && methodName .endsWith (mappedName .substring (1 ));
207
- }
208
-
209
- }
210
-
211
- private static class PointcutMatchingAuthorizationManager implements AuthorizationManager <MethodInvocation > {
212
-
213
- private final Map <Pointcut , AuthorizationManager <MethodInvocation >> managers ;
214
-
215
- PointcutMatchingAuthorizationManager (Map <Pointcut , AuthorizationManager <MethodInvocation >> managers ) {
216
- this .managers = managers ;
217
- }
218
-
219
- @ Override
220
- public AuthorizationDecision check (Supplier <Authentication > authentication , MethodInvocation object ) {
221
- for (Map .Entry <Pointcut , AuthorizationManager <MethodInvocation >> entry : this .managers .entrySet ()) {
222
- Class <?> targetClass = (object .getThis () != null ) ? AopUtils .getTargetClass (object .getThis ())
223
- : null ;
224
- if (entry .getKey ().getClassFilter ().matches (targetClass )
225
- && entry .getKey ().getMethodMatcher ().matches (object .getMethod (), targetClass )) {
226
- return entry .getValue ().check (authentication , object );
227
- }
228
- }
229
- return new AuthorizationDecision (false );
230
- }
231
-
232
- }
233
-
234
- private static class MethodExpressionAuthorizationManager implements AuthorizationManager <MethodInvocation > {
235
-
236
- private final Expression expression ;
237
-
238
- private SecurityExpressionHandler <MethodInvocation > expressionHandler = new DefaultMethodSecurityExpressionHandler ();
239
-
240
- MethodExpressionAuthorizationManager (Expression expression ) {
241
- this .expression = expression ;
242
- }
243
-
244
- @ Override
245
- public AuthorizationDecision check (Supplier <Authentication > authentication , MethodInvocation invocation ) {
246
- EvaluationContext ctx = this .expressionHandler .createEvaluationContext (authentication , invocation );
247
- boolean granted = ExpressionUtils .evaluateAsBoolean (this .expression , ctx );
248
- return new ExpressionAuthorizationDecision (granted , this .expression );
249
- }
250
-
251
- void setExpressionHandler (SecurityExpressionHandler <MethodInvocation > expressionHandler ) {
252
- this .expressionHandler = expressionHandler ;
253
- }
254
-
255
- }
256
-
257
123
}
258
124
259
125
/**
0 commit comments