1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.security.oauth2.provider.endpoint;
18
19 import java.io.IOException;
20 import java.util.HashMap;
21 import java.util.Map;
22 import java.util.Set;
23
24 import javax.servlet.Filter;
25 import javax.servlet.FilterChain;
26 import javax.servlet.FilterConfig;
27 import javax.servlet.ServletException;
28 import javax.servlet.ServletRequest;
29 import javax.servlet.ServletResponse;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpServletResponse;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.springframework.security.authentication.AuthenticationDetailsSource;
36 import org.springframework.security.authentication.AuthenticationManager;
37 import org.springframework.security.authentication.BadCredentialsException;
38 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
39 import org.springframework.security.core.Authentication;
40 import org.springframework.security.core.AuthenticationException;
41 import org.springframework.security.core.context.SecurityContext;
42 import org.springframework.security.core.context.SecurityContextHolder;
43 import org.springframework.security.oauth2.common.util.OAuth2Utils;
44 import org.springframework.security.oauth2.provider.AuthorizationRequest;
45 import org.springframework.security.oauth2.provider.OAuth2Authentication;
46 import org.springframework.security.oauth2.provider.OAuth2Request;
47 import org.springframework.security.oauth2.provider.OAuth2RequestFactory;
48 import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint;
49 import org.springframework.security.web.AuthenticationEntryPoint;
50 import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
51 import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 public class TokenEndpointAuthenticationFilter implements Filter {
74
75 private static final Log logger = LogFactory.getLog(TokenEndpointAuthenticationFilter.class);
76
77 private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
78
79 private AuthenticationEntryPoint authenticationEntryPoint = new OAuth2AuthenticationEntryPoint();
80
81 private final AuthenticationManager authenticationManager;
82
83 private final OAuth2RequestFactory oAuth2RequestFactory;
84
85
86
87
88 public TokenEndpointAuthenticationFilter(AuthenticationManager authenticationManager, OAuth2RequestFactory oAuth2RequestFactory) {
89 super();
90 this.authenticationManager = authenticationManager;
91 this.oAuth2RequestFactory = oAuth2RequestFactory;
92 }
93
94
95
96
97
98
99
100 public void setAuthenticationEntryPoint(AuthenticationEntryPoint authenticationEntryPoint) {
101 this.authenticationEntryPoint = authenticationEntryPoint;
102 }
103
104
105
106
107
108
109 public void setAuthenticationDetailsSource(
110 AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource) {
111 this.authenticationDetailsSource = authenticationDetailsSource;
112 }
113
114 public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
115 ServletException {
116
117 final boolean debug = logger.isDebugEnabled();
118 final HttpServletRequest request = (HttpServletRequest) req;
119 final HttpServletResponse response = (HttpServletResponse) res;
120
121 try {
122 Authentication credentials = extractCredentials(request);
123
124 if (credentials != null) {
125
126 if (debug) {
127 logger.debug("Authentication credentials found for '" + credentials.getName() + "'");
128 }
129
130 Authentication authResult = authenticationManager.authenticate(credentials);
131
132 if (debug) {
133 logger.debug("Authentication success: " + authResult.getName());
134 }
135
136 Authentication clientAuth = SecurityContextHolder.getContext().getAuthentication();
137 if (clientAuth == null) {
138 throw new BadCredentialsException(
139 "No client authentication found. Remember to put a filter upstream of the TokenEndpointAuthenticationFilter.");
140 }
141
142 Map<String, String> map = getSingleValueMap(request);
143 map.put(OAuth2Utils.CLIENT_ID, clientAuth.getName());
144 AuthorizationRequest authorizationRequest = oAuth2RequestFactory.createAuthorizationRequest(map);
145
146 authorizationRequest.setScope(getScope(request));
147 if (clientAuth.isAuthenticated()) {
148
149 authorizationRequest.setApproved(true);
150 }
151
152 OAuth2Request storedOAuth2Request = oAuth2RequestFactory.createOAuth2Request(authorizationRequest);
153
154 SecurityContextHolder.getContext().setAuthentication(
155 new OAuth2Authentication(storedOAuth2Request, authResult));
156
157 onSuccessfulAuthentication(request, response, authResult);
158
159 }
160
161 }
162 catch (AuthenticationException failed) {
163 SecurityContextHolder.clearContext();
164
165 if (debug) {
166 logger.debug("Authentication request for failed: " + failed);
167 }
168
169 onUnsuccessfulAuthentication(request, response, failed);
170
171 authenticationEntryPoint.commence(request, response, failed);
172
173 return;
174 }
175
176 chain.doFilter(request, response);
177 }
178
179 private Map<String, String> getSingleValueMap(HttpServletRequest request) {
180 Map<String, String> map = new HashMap<String, String>();
181 Map<String, String[]> parameters = request.getParameterMap();
182 for (String key : parameters.keySet()) {
183 String[] values = parameters.get(key);
184 map.put(key, values != null && values.length > 0 ? values[0] : null);
185 }
186 return map;
187 }
188
189 protected void onSuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
190 Authentication authResult) throws IOException {
191 }
192
193 protected void onUnsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
194 AuthenticationException failed) throws IOException {
195 }
196
197
198
199
200
201
202
203
204
205 protected Authentication extractCredentials(HttpServletRequest request) {
206 String grantType = request.getParameter("grant_type");
207 if (grantType != null && grantType.equals("password")) {
208 UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(
209 request.getParameter("username"), request.getParameter("password"));
210 result.setDetails(authenticationDetailsSource.buildDetails(request));
211 return result;
212 }
213 return null;
214 }
215
216 private Set<String> getScope(HttpServletRequest request) {
217 return OAuth2Utils.parseParameterList(request.getParameter("scope"));
218 }
219
220 public void init(FilterConfig filterConfig) throws ServletException {
221 }
222
223 public void destroy() {
224 }
225
226 }