1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.springframework.security.oauth2.config.annotation.web.configurers;
17
18 import java.util.Collections;
19
20 import org.springframework.http.MediaType;
21 import org.springframework.security.access.expression.SecurityExpressionHandler;
22 import org.springframework.security.authentication.AuthenticationDetailsSource;
23 import org.springframework.security.authentication.AuthenticationEventPublisher;
24 import org.springframework.security.authentication.AuthenticationManager;
25 import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
26 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
27 import org.springframework.security.config.annotation.web.configurers.ExceptionHandlingConfigurer;
28 import org.springframework.security.oauth2.provider.ClientDetailsService;
29 import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetailsSource;
30 import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager;
31 import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter;
32 import org.springframework.security.oauth2.provider.authentication.TokenExtractor;
33 import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;
34 import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint;
35 import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler;
36 import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
37 import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
38 import org.springframework.security.oauth2.provider.token.TokenStore;
39 import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
40 import org.springframework.security.web.AuthenticationEntryPoint;
41 import org.springframework.security.web.DefaultSecurityFilterChain;
42 import org.springframework.security.web.FilterInvocation;
43 import org.springframework.security.web.access.AccessDeniedHandler;
44 import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
45 import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;
46 import org.springframework.util.Assert;
47 import org.springframework.web.accept.ContentNegotiationStrategy;
48 import org.springframework.web.accept.HeaderContentNegotiationStrategy;
49
50 import javax.servlet.http.HttpServletRequest;
51
52
53
54
55
56
57
58
59 public final class ResourceServerSecurityConfigurer extends
60 SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
61
62 private AuthenticationEntryPoint authenticationEntryPoint = new OAuth2AuthenticationEntryPoint();
63
64 private AccessDeniedHandler accessDeniedHandler = new OAuth2AccessDeniedHandler();
65
66 private OAuth2AuthenticationProcessingFilter resourcesServerFilter;
67
68 private AuthenticationManager authenticationManager;
69
70 private AuthenticationEventPublisher eventPublisher = null;
71
72 private ResourceServerTokenServices resourceTokenServices;
73
74 private TokenStore tokenStore = new InMemoryTokenStore();
75
76 private String resourceId = "oauth2-resource";
77
78 private SecurityExpressionHandler<FilterInvocation> expressionHandler = new OAuth2WebSecurityExpressionHandler();
79
80 private TokenExtractor tokenExtractor;
81
82 private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource;
83
84 private boolean stateless = true;
85
86 public ResourceServerSecurityConfigurer() {
87 resourceId(resourceId);
88 }
89
90 private ClientDetailsService clientDetails() {
91 return getBuilder().getSharedObject(ClientDetailsService.class);
92 }
93
94 public TokenStore getTokenStore() {
95 return tokenStore;
96 }
97
98
99
100
101
102
103 public ResourceServerSecurityConfigurer stateless(boolean stateless) {
104 this.stateless = stateless;
105 return this;
106 }
107
108 public ResourceServerSecurityConfigurer authenticationEntryPoint(AuthenticationEntryPoint authenticationEntryPoint) {
109 this.authenticationEntryPoint = authenticationEntryPoint;
110 return this;
111 }
112
113 public ResourceServerSecurityConfigurer accessDeniedHandler(AccessDeniedHandler accessDeniedHandler) {
114 this.accessDeniedHandler = accessDeniedHandler;
115 return this;
116 }
117
118 public ResourceServerSecurityConfigurer tokenStore(TokenStore tokenStore) {
119 Assert.state(tokenStore != null, "TokenStore cannot be null");
120 this.tokenStore = tokenStore;
121 return this;
122 }
123
124 public ResourceServerSecurityConfigurer eventPublisher(AuthenticationEventPublisher eventPublisher) {
125 Assert.state(eventPublisher != null, "AuthenticationEventPublisher cannot be null");
126 this.eventPublisher = eventPublisher;
127 return this;
128 }
129
130 public ResourceServerSecurityConfigurer expressionHandler(
131 SecurityExpressionHandler<FilterInvocation> expressionHandler) {
132 Assert.state(expressionHandler != null, "SecurityExpressionHandler cannot be null");
133 this.expressionHandler = expressionHandler;
134 return this;
135 }
136
137 public ResourceServerSecurityConfigurer tokenExtractor(TokenExtractor tokenExtractor) {
138 Assert.state(tokenExtractor != null, "TokenExtractor cannot be null");
139 this.tokenExtractor = tokenExtractor;
140 return this;
141 }
142
143
144
145
146
147
148
149
150 public ResourceServerSecurityConfigurer authenticationDetailsSource(
151 AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource) {
152 Assert.state(authenticationDetailsSource != null, "AuthenticationDetailsSource cannot be null");
153 this.authenticationDetailsSource = authenticationDetailsSource;
154 return this;
155 }
156
157 public ResourceServerSecurityConfigurer authenticationManager(AuthenticationManager authenticationManager) {
158 Assert.state(authenticationManager != null, "AuthenticationManager cannot be null");
159 this.authenticationManager = authenticationManager;
160 return this;
161 }
162
163 public ResourceServerSecurityConfigurer tokenServices(ResourceServerTokenServices tokenServices) {
164 Assert.state(tokenServices != null, "ResourceServerTokenServices cannot be null");
165 this.resourceTokenServices = tokenServices;
166 return this;
167 }
168
169 @Override
170 public void init(HttpSecurity http) throws Exception {
171 registerDefaultAuthenticationEntryPoint(http);
172 }
173
174 @SuppressWarnings("unchecked")
175 private void registerDefaultAuthenticationEntryPoint(HttpSecurity http) {
176 ExceptionHandlingConfigurer<HttpSecurity> exceptionHandling = http
177 .getConfigurer(ExceptionHandlingConfigurer.class);
178 if (exceptionHandling == null) {
179 return;
180 }
181 ContentNegotiationStrategy contentNegotiationStrategy = http.getSharedObject(ContentNegotiationStrategy.class);
182 if (contentNegotiationStrategy == null) {
183 contentNegotiationStrategy = new HeaderContentNegotiationStrategy();
184 }
185 MediaTypeRequestMatcher preferredMatcher = new MediaTypeRequestMatcher(contentNegotiationStrategy,
186 MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_JSON,
187 MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_XML, MediaType.MULTIPART_FORM_DATA,
188 MediaType.TEXT_XML);
189 preferredMatcher.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL));
190 exceptionHandling.defaultAuthenticationEntryPointFor(postProcess(authenticationEntryPoint), preferredMatcher);
191 }
192
193 public ResourceServerSecurityConfigurer resourceId(String resourceId) {
194 this.resourceId = resourceId;
195 if (authenticationEntryPoint instanceof OAuth2AuthenticationEntryPoint) {
196 ((OAuth2AuthenticationEntryPoint) authenticationEntryPoint).setRealmName(resourceId);
197 }
198 return this;
199 }
200
201 @Override
202 public void configure(HttpSecurity http) throws Exception {
203
204 AuthenticationManager oauthAuthenticationManager = oauthAuthenticationManager(http);
205 resourcesServerFilter = new OAuth2AuthenticationProcessingFilter();
206 resourcesServerFilter.setAuthenticationEntryPoint(authenticationEntryPoint);
207 resourcesServerFilter.setAuthenticationManager(oauthAuthenticationManager);
208 if (eventPublisher != null) {
209 resourcesServerFilter.setAuthenticationEventPublisher(eventPublisher);
210 }
211 if (tokenExtractor != null) {
212 resourcesServerFilter.setTokenExtractor(tokenExtractor);
213 }
214 if (authenticationDetailsSource != null) {
215 resourcesServerFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
216 }
217 resourcesServerFilter = postProcess(resourcesServerFilter);
218 resourcesServerFilter.setStateless(stateless);
219
220
221 http
222 .authorizeRequests().expressionHandler(expressionHandler)
223 .and()
224 .addFilterBefore(resourcesServerFilter, AbstractPreAuthenticatedProcessingFilter.class)
225 .exceptionHandling()
226 .accessDeniedHandler(accessDeniedHandler)
227 .authenticationEntryPoint(authenticationEntryPoint);
228
229 }
230
231 private AuthenticationManager oauthAuthenticationManager(HttpSecurity http) {
232 OAuth2AuthenticationManager oauthAuthenticationManager = new OAuth2AuthenticationManager();
233 if (authenticationManager != null) {
234 if (authenticationManager instanceof OAuth2AuthenticationManager) {
235 oauthAuthenticationManager = (OAuth2AuthenticationManager) authenticationManager;
236 }
237 else {
238 return authenticationManager;
239 }
240 }
241 oauthAuthenticationManager.setResourceId(resourceId);
242 oauthAuthenticationManager.setTokenServices(resourceTokenServices(http));
243 oauthAuthenticationManager.setClientDetailsService(clientDetails());
244 return oauthAuthenticationManager;
245 }
246
247 private ResourceServerTokenServices resourceTokenServices(HttpSecurity http) {
248 tokenServices(http);
249 return this.resourceTokenServices;
250 }
251
252 private ResourceServerTokenServices tokenServices(HttpSecurity http) {
253 if (resourceTokenServices != null) {
254 return resourceTokenServices;
255 }
256 DefaultTokenServices tokenServices = new DefaultTokenServices();
257 tokenServices.setTokenStore(tokenStore());
258 tokenServices.setSupportRefreshToken(true);
259 tokenServices.setClientDetailsService(clientDetails());
260 this.resourceTokenServices = tokenServices;
261 return tokenServices;
262 }
263
264 private TokenStore tokenStore() {
265 Assert.state(tokenStore != null, "TokenStore cannot be null");
266 return this.tokenStore;
267 }
268
269 public AccessDeniedHandler getAccessDeniedHandler() {
270 return this.accessDeniedHandler;
271 }
272
273 }