15
15
*/
16
16
package org .springframework .security .oauth2 .server .authorization .web ;
17
17
18
+ import java .nio .charset .StandardCharsets ;
19
+
18
20
import javax .servlet .FilterChain ;
19
21
import javax .servlet .http .HttpServletRequest ;
20
22
import javax .servlet .http .HttpServletResponse ;
33
35
import org .springframework .security .authentication .AuthenticationManager ;
34
36
import org .springframework .security .core .Authentication ;
35
37
import org .springframework .security .core .context .SecurityContextHolder ;
38
+ import org .springframework .security .crypto .codec .Hex ;
36
39
import org .springframework .security .oauth2 .core .ClientAuthenticationMethod ;
37
40
import org .springframework .security .oauth2 .core .OAuth2AuthenticationException ;
38
41
import org .springframework .security .oauth2 .core .OAuth2Error ;
@@ -130,6 +133,7 @@ public void doFilterWhenRequestDoesNotMatchThenNotProcessed() throws Exception {
130
133
this .filter .doFilter (request , response , filterChain );
131
134
132
135
verify (filterChain ).doFilter (any (HttpServletRequest .class ), any (HttpServletResponse .class ));
136
+ verifyNoInteractions (this .authenticationConverter );
133
137
}
134
138
135
139
@ Test
@@ -142,6 +146,7 @@ public void doFilterWhenRequestMatchesAndEmptyCredentialsThenNotProcessed() thro
142
146
this .filter .doFilter (request , response , filterChain );
143
147
144
148
verify (filterChain ).doFilter (any (HttpServletRequest .class ), any (HttpServletResponse .class ));
149
+ verifyNoInteractions (this .authenticationManager );
145
150
}
146
151
147
152
@ Test
@@ -164,6 +169,46 @@ public void doFilterWhenRequestMatchesAndInvalidCredentialsThenInvalidRequestErr
164
169
assertThat (error .getErrorCode ()).isEqualTo (OAuth2ErrorCodes .INVALID_REQUEST );
165
170
}
166
171
172
+ // gh-889
173
+ @ Test
174
+ public void doFilterWhenRequestMatchesAndClientIdContainsNonPrintableASCIIThenInvalidRequestError () throws Exception {
175
+ // Hex 00 -> null
176
+ String clientId = new String (Hex .decode ("00" ), StandardCharsets .UTF_8 );
177
+ assertWhenInvalidClientIdThenInvalidRequestError (clientId );
178
+
179
+ // Hex 0a61 -> line feed + a
180
+ clientId = new String (Hex .decode ("0a61" ), StandardCharsets .UTF_8 );
181
+ assertWhenInvalidClientIdThenInvalidRequestError (clientId );
182
+
183
+ // Hex 1b -> escape
184
+ clientId = new String (Hex .decode ("1b" ), StandardCharsets .UTF_8 );
185
+ assertWhenInvalidClientIdThenInvalidRequestError (clientId );
186
+
187
+ // Hex 1b61 -> escape + a
188
+ clientId = new String (Hex .decode ("1b61" ), StandardCharsets .UTF_8 );
189
+ assertWhenInvalidClientIdThenInvalidRequestError (clientId );
190
+ }
191
+
192
+ private void assertWhenInvalidClientIdThenInvalidRequestError (String clientId ) throws Exception {
193
+ when (this .authenticationConverter .convert (any (HttpServletRequest .class ))).thenReturn (
194
+ new OAuth2ClientAuthenticationToken (clientId , ClientAuthenticationMethod .CLIENT_SECRET_BASIC , "secret" , null ));
195
+
196
+ MockHttpServletRequest request = new MockHttpServletRequest ("POST" , this .filterProcessesUrl );
197
+ request .setServletPath (this .filterProcessesUrl );
198
+ MockHttpServletResponse response = new MockHttpServletResponse ();
199
+ FilterChain filterChain = mock (FilterChain .class );
200
+
201
+ this .filter .doFilter (request , response , filterChain );
202
+
203
+ verifyNoInteractions (filterChain );
204
+ verifyNoInteractions (this .authenticationManager );
205
+
206
+ assertThat (SecurityContextHolder .getContext ().getAuthentication ()).isNull ();
207
+ assertThat (response .getStatus ()).isEqualTo (HttpStatus .BAD_REQUEST .value ());
208
+ OAuth2Error error = readError (response );
209
+ assertThat (error .getErrorCode ()).isEqualTo (OAuth2ErrorCodes .INVALID_REQUEST );
210
+ }
211
+
167
212
@ Test
168
213
public void doFilterWhenRequestMatchesAndBadCredentialsThenInvalidClientError () throws Exception {
169
214
when (this .authenticationConverter .convert (any (HttpServletRequest .class ))).thenReturn (
@@ -179,6 +224,7 @@ public void doFilterWhenRequestMatchesAndBadCredentialsThenInvalidClientError()
179
224
this .filter .doFilter (request , response , filterChain );
180
225
181
226
verifyNoInteractions (filterChain );
227
+ verify (this .authenticationManager ).authenticate (any ());
182
228
183
229
assertThat (SecurityContextHolder .getContext ().getAuthentication ()).isNull ();
184
230
assertThat (response .getStatus ()).isEqualTo (HttpStatus .UNAUTHORIZED .value ());
0 commit comments