1
2
3
4
5
6
7
8
9
10
11
12
13 package org.springframework.security.oauth2.provider.client;
14
15 import java.io.IOException;
16
17 import javax.servlet.FilterChain;
18 import javax.servlet.ServletException;
19 import javax.servlet.http.HttpServletRequest;
20 import javax.servlet.http.HttpServletResponse;
21
22 import org.springframework.security.authentication.BadCredentialsException;
23 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
24 import org.springframework.security.core.Authentication;
25 import org.springframework.security.core.AuthenticationException;
26 import org.springframework.security.core.context.SecurityContextHolder;
27 import org.springframework.security.oauth2.common.exceptions.BadClientCredentialsException;
28 import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint;
29 import org.springframework.security.web.AuthenticationEntryPoint;
30 import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
31 import org.springframework.security.web.authentication.AuthenticationFailureHandler;
32 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
33 import org.springframework.security.web.util.matcher.RequestMatcher;
34 import org.springframework.web.HttpRequestMethodNotSupportedException;
35
36
37
38
39
40
41
42
43
44
45 public class ClientCredentialsTokenEndpointFilter extends AbstractAuthenticationProcessingFilter {
46
47 private AuthenticationEntryPoint authenticationEntryPoint = new OAuth2AuthenticationEntryPoint();
48
49 private boolean allowOnlyPost = false;
50
51 public ClientCredentialsTokenEndpointFilter() {
52 this("/oauth/token");
53 }
54
55 public ClientCredentialsTokenEndpointFilter(String path) {
56 super(path);
57 setRequiresAuthenticationRequestMatcher(new ClientCredentialsRequestMatcher(path));
58
59 ((OAuth2AuthenticationEntryPoint) authenticationEntryPoint).setTypeName("Form");
60 }
61
62 public void setAllowOnlyPost(boolean allowOnlyPost) {
63 this.allowOnlyPost = allowOnlyPost;
64 }
65
66
67
68
69 public void setAuthenticationEntryPoint(AuthenticationEntryPoint authenticationEntryPoint) {
70 this.authenticationEntryPoint = authenticationEntryPoint;
71 }
72
73 @Override
74 public void afterPropertiesSet() {
75 super.afterPropertiesSet();
76 setAuthenticationFailureHandler(new AuthenticationFailureHandler() {
77 public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
78 AuthenticationException exception) throws IOException, ServletException {
79 if (exception instanceof BadCredentialsException) {
80 exception = new BadCredentialsException(exception.getMessage(), new BadClientCredentialsException());
81 }
82 authenticationEntryPoint.commence(request, response, exception);
83 }
84 });
85 setAuthenticationSuccessHandler(new AuthenticationSuccessHandler() {
86 public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
87 Authentication authentication) throws IOException, ServletException {
88
89 }
90 });
91 }
92
93 @Override
94 public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
95 throws AuthenticationException, IOException, ServletException {
96
97 if (allowOnlyPost && !"POST".equalsIgnoreCase(request.getMethod())) {
98 throw new HttpRequestMethodNotSupportedException(request.getMethod(), new String[] { "POST" });
99 }
100
101 String clientId = request.getParameter("client_id");
102 String clientSecret = request.getParameter("client_secret");
103
104
105
106 Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
107 if (authentication != null && authentication.isAuthenticated()) {
108 return authentication;
109 }
110
111 if (clientId == null) {
112 throw new BadCredentialsException("No client credentials presented");
113 }
114
115 if (clientSecret == null) {
116 clientSecret = "";
117 }
118
119 clientId = clientId.trim();
120 UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(clientId,
121 clientSecret);
122
123 return this.getAuthenticationManager().authenticate(authRequest);
124
125 }
126
127 @Override
128 protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
129 FilterChain chain, Authentication authResult) throws IOException, ServletException {
130 super.successfulAuthentication(request, response, chain, authResult);
131 chain.doFilter(request, response);
132 }
133
134 protected static class ClientCredentialsRequestMatcher implements RequestMatcher {
135
136 private String path;
137
138 public ClientCredentialsRequestMatcher(String path) {
139 this.path = path;
140
141 }
142
143 @Override
144 public boolean matches(HttpServletRequest request) {
145 String uri = request.getRequestURI();
146 int pathParamIndex = uri.indexOf(';');
147
148 if (pathParamIndex > 0) {
149
150 uri = uri.substring(0, pathParamIndex);
151 }
152
153 String clientId = request.getParameter("client_id");
154
155 if (clientId == null) {
156
157 return false;
158 }
159
160 if ("".equals(request.getContextPath())) {
161 return uri.endsWith(path);
162 }
163
164 return uri.endsWith(request.getContextPath() + path);
165 }
166
167 }
168
169 }