-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WebSocketAuthenticatorService & AuthChannelInterceptorAdapter tests
- Loading branch information
1 parent
12aa47c
commit f910619
Showing
8 changed files
with
202 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
100 changes: 100 additions & 0 deletions
100
...al/web/config/security/websocket/interceptor/AuthChannelInterceptorAdapterWebAppTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package org.araymond.joal.web.config.security.websocket.interceptor; | ||
|
||
import org.araymond.joal.TestConstant; | ||
import org.araymond.joal.web.config.WebSocketConfig; | ||
import org.araymond.joal.web.config.security.WebSecurityConfig; | ||
import org.araymond.joal.web.config.security.websocket.services.WebSocketAuthenticatorService; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
import org.mockito.Mockito; | ||
import org.springframework.boot.context.embedded.LocalServerPort; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
import org.springframework.boot.test.context.TestConfiguration; | ||
import org.springframework.boot.test.mock.mockito.MockBean; | ||
import org.springframework.context.annotation.Import; | ||
import org.springframework.messaging.simp.config.ChannelRegistration; | ||
import org.springframework.messaging.simp.stomp.StompHeaders; | ||
import org.springframework.messaging.simp.stomp.StompSession; | ||
import org.springframework.messaging.simp.stomp.StompSessionHandlerAdapter; | ||
import org.springframework.test.context.junit4.SpringRunner; | ||
import org.springframework.web.socket.WebSocketHttpHeaders; | ||
import org.springframework.web.socket.client.standard.StandardWebSocketClient; | ||
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer; | ||
import org.springframework.web.socket.config.annotation.StompEndpointRegistry; | ||
import org.springframework.web.socket.messaging.WebSocketStompClient; | ||
|
||
import javax.inject.Inject; | ||
import java.util.concurrent.ExecutionException; | ||
import java.util.concurrent.TimeUnit; | ||
import java.util.concurrent.TimeoutException; | ||
|
||
import static org.assertj.core.api.Assertions.*; | ||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.mockito.Mockito.times; | ||
import static org.mockito.Mockito.verify; | ||
|
||
|
||
@RunWith(SpringRunner.class) | ||
@SpringBootTest( | ||
classes = { | ||
AuthChannelInterceptorAdapter.class, | ||
WebSocketConfig.class, | ||
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration.class, | ||
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration.class, | ||
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration.class, | ||
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration.class, | ||
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration.class, | ||
org.springframework.boot.autoconfigure.web.HttpEncodingAutoConfiguration.class, | ||
org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration.class, | ||
org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration.class, | ||
org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration.class, | ||
org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration.class, | ||
org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration.class, | ||
}, | ||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, | ||
properties = { | ||
"spring.main.web-environment=true", | ||
"joal.ui.path.prefix=" + TestConstant.UI_PATH_PREFIX, | ||
"joal.ui.secret-token=" + TestConstant.UI_SECRET_TOKEN | ||
} | ||
) | ||
@Import(AuthChannelInterceptorAdapterWebAppTest.TestWebSocketAuthenticationConfig.class) | ||
public class AuthChannelInterceptorAdapterWebAppTest { | ||
|
||
@LocalServerPort | ||
private int port; | ||
|
||
@MockBean | ||
private WebSocketAuthenticatorService authenticatorService; | ||
|
||
@TestConfiguration | ||
public static class TestWebSocketAuthenticationConfig extends AbstractWebSocketMessageBrokerConfigurer { | ||
private final AuthChannelInterceptorAdapter authChannelInterceptorAdapter; | ||
@Inject | ||
public TestWebSocketAuthenticationConfig(final AuthChannelInterceptorAdapter authChannelInterceptorAdapter) { | ||
this.authChannelInterceptorAdapter = authChannelInterceptorAdapter; | ||
} | ||
@Override | ||
public void registerStompEndpoints(final StompEndpointRegistry registry) { | ||
// Endpoints are already registered on WebSocketConfig, no need to add more. | ||
} | ||
@Override | ||
public void configureClientInboundChannel(final ChannelRegistration registration) { | ||
registration.interceptors(this.authChannelInterceptorAdapter); | ||
} | ||
} | ||
|
||
@Test | ||
public void shouldCallAuthServiceWhenUserTriesToConnect() throws InterruptedException, ExecutionException, TimeoutException { | ||
final WebSocketStompClient stompClient = new WebSocketStompClient(new StandardWebSocketClient()); | ||
|
||
final StompHeaders stompHeaders = new StompHeaders(); | ||
stompHeaders.add(AuthChannelInterceptorAdapter.USERNAME_HEADER, "john"); | ||
stompHeaders.add(AuthChannelInterceptorAdapter.TOKEN_HEADER, TestConstant.UI_SECRET_TOKEN); | ||
|
||
stompClient.connect("ws://localhost:" + port + "/" + TestConstant.UI_PATH_PREFIX, new WebSocketHttpHeaders(), stompHeaders, new StompSessionHandlerAdapter() { | ||
}).get(10, TimeUnit.SECONDS); | ||
|
||
verify(authenticatorService, times(1)).getAuthenticatedOrFail("john", TestConstant.UI_SECRET_TOKEN); | ||
} | ||
} |
85 changes: 85 additions & 0 deletions
85
...aymond/joal/web/config/security/websocket/services/WebSocketAuthenticatorServiceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package org.araymond.joal.web.config.security.websocket.services; | ||
|
||
import org.araymond.joal.TestConstant; | ||
import org.assertj.core.api.Condition; | ||
import org.junit.Test; | ||
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; | ||
import org.springframework.security.authentication.BadCredentialsException; | ||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; | ||
|
||
import static org.assertj.core.api.Assertions.*; | ||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
|
||
public class WebSocketAuthenticatorServiceTest { | ||
|
||
@Test | ||
public void shouldThrowExceptionOnNullOrEmptyUsername() { | ||
final WebSocketAuthenticatorService authService = new WebSocketAuthenticatorService(TestConstant.UI_SECRET_TOKEN); | ||
assertThatThrownBy(() -> authService.getAuthenticatedOrFail(" ", TestConstant.UI_SECRET_TOKEN)) | ||
.isInstanceOf(AuthenticationCredentialsNotFoundException.class) | ||
.hasMessageContaining("Username"); | ||
|
||
assertThatThrownBy(() -> authService.getAuthenticatedOrFail("", TestConstant.UI_SECRET_TOKEN)) | ||
.isInstanceOf(AuthenticationCredentialsNotFoundException.class) | ||
.hasMessageContaining("Username"); | ||
|
||
assertThatThrownBy(() -> authService.getAuthenticatedOrFail(null, TestConstant.UI_SECRET_TOKEN)) | ||
.isInstanceOf(AuthenticationCredentialsNotFoundException.class) | ||
.hasMessageContaining("Username"); | ||
} | ||
|
||
@Test | ||
public void shouldThrowExceptionOnNullOrEmptyToken() { | ||
final WebSocketAuthenticatorService authService = new WebSocketAuthenticatorService(TestConstant.UI_SECRET_TOKEN); | ||
assertThatThrownBy(() -> authService.getAuthenticatedOrFail("john", " ")) | ||
.isInstanceOf(AuthenticationCredentialsNotFoundException.class) | ||
.hasMessageContaining("Authentication token"); | ||
|
||
assertThatThrownBy(() -> authService.getAuthenticatedOrFail("john", "")) | ||
.isInstanceOf(AuthenticationCredentialsNotFoundException.class) | ||
.hasMessageContaining("Authentication token"); | ||
|
||
assertThatThrownBy(() -> authService.getAuthenticatedOrFail("john", null)) | ||
.isInstanceOf(AuthenticationCredentialsNotFoundException.class) | ||
.hasMessageContaining("Authentication token"); | ||
} | ||
|
||
@Test | ||
public void shouldThrowExceptionIfTokenDoesNotMatches() { | ||
final WebSocketAuthenticatorService authService = new WebSocketAuthenticatorService(TestConstant.UI_SECRET_TOKEN); | ||
assertThatThrownBy(() -> authService.getAuthenticatedOrFail("john", "nop")) | ||
.isInstanceOf(BadCredentialsException.class) | ||
.hasMessageContaining("Authentication token does not match"); | ||
} | ||
|
||
@Test | ||
public void shouldReturnAuthenticationTokenOnSuccess() { | ||
final WebSocketAuthenticatorService authService = new WebSocketAuthenticatorService(TestConstant.UI_SECRET_TOKEN); | ||
|
||
final UsernamePasswordAuthenticationToken authToken = authService.getAuthenticatedOrFail("john", TestConstant.UI_SECRET_TOKEN); | ||
|
||
assertThat(authToken.getName()).isEqualTo("john"); | ||
} | ||
|
||
@Test | ||
public void shouldReturnInstanceOfUsernamePasswordAuthenticationTokenOnSuccess() { | ||
// This is not a useless test, Spring security chain test if the instance of the returned AuthToken is UsernamePasswordAuthenticationToken | ||
final WebSocketAuthenticatorService authService = new WebSocketAuthenticatorService(TestConstant.UI_SECRET_TOKEN); | ||
|
||
final UsernamePasswordAuthenticationToken authToken = authService.getAuthenticatedOrFail("john", TestConstant.UI_SECRET_TOKEN); | ||
|
||
assertThat(authToken).isInstanceOf(UsernamePasswordAuthenticationToken.class); | ||
} | ||
|
||
@Test | ||
public void shouldDefineAtLeastOneGrantedAuthorityOnSuccess() { | ||
// This is not a useless test, Spring security chain test if there is at least one granted authority, if there is none, we are considered as non authenticated | ||
final WebSocketAuthenticatorService authService = new WebSocketAuthenticatorService(TestConstant.UI_SECRET_TOKEN); | ||
|
||
final UsernamePasswordAuthenticationToken authToken = authService.getAuthenticatedOrFail("john", TestConstant.UI_SECRET_TOKEN); | ||
|
||
assertThat(authToken.getAuthorities().size()).isGreaterThanOrEqualTo(1); | ||
} | ||
|
||
} |