View Javadoc
1   /*
2    * Copyright 2008-2009 Web Cohesion
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.security.oauth.provider.filter;
18  
19  import org.springframework.security.access.AccessDeniedException;
20  import org.springframework.security.core.Authentication;
21  import org.springframework.security.core.context.SecurityContextHolder;
22  import org.springframework.security.oauth.provider.ConsumerAuthentication;
23  import org.springframework.security.oauth.provider.DefaultAuthenticationHandler;
24  import org.springframework.security.oauth.provider.ExtraTrustConsumerDetails;
25  import org.springframework.security.oauth.provider.InvalidOAuthParametersException;
26  import org.springframework.security.oauth.provider.OAuthAuthenticationHandler;
27  import org.springframework.security.oauth.provider.token.OAuthAccessProviderToken;
28  import org.springframework.security.oauth.provider.token.OAuthProviderToken;
29  import org.springframework.util.StringUtils;
30  
31  import javax.servlet.FilterChain;
32  import javax.servlet.ServletException;
33  import javax.servlet.http.HttpServletRequest;
34  import javax.servlet.http.HttpServletResponse;
35  import java.io.IOException;
36  
37  /**
38   * Processing filter for requests to protected resources. This filter attempts to load the OAuth authentication
39   * request into the security context using a presented access token.  Default behavior of this filter allows
40   * the request to continue even if OAuth credentials are not presented (allowing another filter to potentially
41   * load a different authentication request into the security context). If the protected resource is available
42   * ONLY via OAuth access token, set <code>ignoreMissingCredentials</code> to <code>false</code>. 
43   *
44   * @author Ryan Heaton
45   * @author Andrew McCall
46   */
47  public class ProtectedResourceProcessingFilter extends OAuthProviderProcessingFilter {
48  
49    private boolean allowAllMethods = true;
50    private OAuthAuthenticationHandler authHandler = new DefaultAuthenticationHandler();
51  
52    public ProtectedResourceProcessingFilter() {
53      //we're going to ignore missing credentials by default.  This is to allow a chance for the resource to
54      //be accessed by some other means of authentication.
55      setIgnoreMissingCredentials(true);
56    }
57  
58    @Override
59    protected boolean allowMethod(String method) {
60      return allowAllMethods || super.allowMethod(method);
61    }
62  
63    protected void onValidSignature(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
64      ConsumerAuthenticationringframework/security/oauth/provider/ConsumerAuthentication.html#ConsumerAuthentication">ConsumerAuthentication authentication = (ConsumerAuthentication) SecurityContextHolder.getContext().getAuthentication();
65      String token = authentication.getConsumerCredentials().getToken();
66      OAuthAccessProviderToken accessToken = null;
67      if (StringUtils.hasText(token)) {
68        OAuthProviderToken authToken = getTokenServices().getToken(token);
69        if (authToken == null) {
70          throw new AccessDeniedException("Invalid access token.");
71        }
72        else if (!authToken.isAccessToken()) {
73          throw new AccessDeniedException("Token should be an access token.");
74        }
75        else if (authToken instanceof OAuthAccessProviderToken) {
76          accessToken = (OAuthAccessProviderToken) authToken;
77        }
78      }
79      else if ((!(authentication.getConsumerDetails() instanceof ExtraTrustConsumerDetails)) ||
80        ((ExtraTrustConsumerDetails)authentication.getConsumerDetails()).isRequiredToObtainAuthenticatedToken()) {
81        throw new InvalidOAuthParametersException(messages.getMessage("ProtectedResourceProcessingFilter.missingToken", "Missing auth token."));
82      }
83  
84      Authentication userAuthentication = authHandler.createAuthentication(request, authentication, accessToken);
85      SecurityContextHolder.getContext().setAuthentication(userAuthentication);
86  
87      chain.doFilter(request, response);
88    }
89  
90    @Override
91    protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
92      return true;
93    }
94  
95    @Override
96    public void setFilterProcessesUrl(String filterProcessesUrl) {
97      throw new UnsupportedOperationException("The OAuth protected resource processing filter doesn't support a filter processes URL.");
98    }
99  
100   /**
101    * Whether to allow all methods.
102    *
103    * @return Whether to allow all methods.
104    */
105   public boolean isAllowAllMethods() {
106     return allowAllMethods;
107   }
108 
109   /**
110    * Whether to allow all methods.
111    *
112    * @param allowAllMethods Whether to allow all methods.
113    */
114   public void setAllowAllMethods(boolean allowAllMethods) {
115     this.allowAllMethods = allowAllMethods;
116   }
117 
118   /**
119    * The authentication handler.
120    *
121    * @return The authentication handler.
122    */
123   public OAuthAuthenticationHandler getAuthHandler() {
124     return authHandler;
125   }
126 
127   /**
128    * The authentication handler.
129    *
130    * @param authHandler The authentication handler.
131    */
132   public void setAuthHandler(OAuthAuthenticationHandler authHandler) {
133     this.authHandler = authHandler;
134   }
135 }