@ -16,8 +16,8 @@
@@ -16,8 +16,8 @@
package sample ;
import java.io.IOException ;
import java.util.ArrayList ;
import java.util.List ;
import java.util.stream.Collectors ;
import com.gargoylesoftware.htmlunit.WebClient ;
import com.gargoylesoftware.htmlunit.WebResponse ;
@ -27,17 +27,13 @@ import com.gargoylesoftware.htmlunit.html.HtmlPage;
@@ -27,17 +27,13 @@ import com.gargoylesoftware.htmlunit.html.HtmlPage;
import org.junit.Before ;
import org.junit.Test ;
import org.junit.runner.RunWith ;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc ;
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.Bean ;
import org.springframework.context.annotation.Import ;
import org.springframework.http.HttpStatus ;
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService ;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService ;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService ;
import org.springframework.security.test.context.support.WithMockUser ;
import org.springframework.test.context.junit4.SpringRunner ;
import org.springframework.web.util.UriComponentsBuilder ;
@ -47,30 +43,30 @@ import static org.mockito.ArgumentMatchers.any;
@@ -47,30 +43,30 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when ;
/ * *
* Consent page integration tests for the sample Authorization Server serving a custom Consent page
* Consent page integration tests for the sample Authorization Server serving a custom Consent page .
*
* @author Dmitriy Dubson
* /
@RunWith ( SpringRunner . class )
@SpringBootTest ( webEnvironment = SpringBootTest . WebEnvironment . RANDOM_PORT )
@Import ( { OAuth2AuthorizationServerCustomConsentPageApplicationTests . InMemoryOAuth2AuthorizationServiceTestConfiguration . class } )
@AutoConfigureMockMvc
public class OAuth2AuthorizationServerCustomConsentPageApplicationTests {
public class OAuth2AuthorizationServerCustomConsentTests {
@Autowired
private WebClient webClient ;
@MockBean
private OAuth2AuthorizationConsentService mockA uthorizationConsentService;
private OAuth2AuthorizationConsentService a uthorizationConsentService;
private final String testConsentResultEndpoint = "http://127.0.0.1/login/oauth2/code/messaging-client-oidc" ;
private final String redirectUri = "http://127.0.0.1/login/oauth2/code/messaging-client-oidc" ;
private final String authorizeEndpoint = UriComponentsBuilder
private final String authorizationRequestUri = UriComponentsBuilder
. fromPath ( "/oauth2/authorize" )
. queryParam ( "response_type" , "code" )
. queryParam ( "client_id" , "messaging-client" )
. queryParam ( "scope" , "openid message.read message.write" )
. queryParam ( "state" , "state" )
. queryParam ( "redirect_uri" , testConsentResultEndpoint )
. queryParam ( "redirect_uri" , this . redirectUri )
. toUriString ( ) ;
@Before
@ -78,24 +74,28 @@ public class OAuth2AuthorizationServerCustomConsentPageApplicationTests {
@@ -78,24 +74,28 @@ public class OAuth2AuthorizationServerCustomConsentPageApplicationTests {
this . webClient . getOptions ( ) . setThrowExceptionOnFailingStatusCode ( false ) ;
this . webClient . getOptions ( ) . setRedirectEnabled ( true ) ;
this . webClient . getCookieManager ( ) . clearCookies ( ) ;
when ( mockA uthorizationConsentService. findById ( any ( ) , any ( ) ) ) . thenReturn ( null ) ;
when ( this . a uthorizationConsentService. findById ( any ( ) , any ( ) ) ) . thenReturn ( null ) ;
}
@Test
@WithMockUser ( "user1" )
public void whenUserConsentsToAllScopesThenReturnAuthorizationCode ( ) throws IOException {
final HtmlPage consentPage = webClient . getPage ( authorizeEndpoint ) ;
final HtmlPage consentPage = this . webClient . getPage ( this . authorizationRequestUri ) ;
assertThat ( consentPage . getTitleText ( ) ) . isEqualTo ( "Custom consent page - Consent required" ) ;
List < HtmlCheckBoxInput > scopes = consentPage . querySelectorAll ( "input[name='scope']" ) . stream ( )
. map ( scope - > ( HtmlCheckBoxInput ) scope ) . collect ( Collectors . toList ( ) ) ;
List < HtmlCheckBoxInput > scopes = new ArrayList < > ( ) ;
consentPage . querySelectorAll ( "input[name='scope']" ) . forEach ( scope - >
scopes . add ( ( HtmlCheckBoxInput ) scope ) ) ;
for ( HtmlCheckBoxInput scope : scopes ) {
scope . click ( ) ;
}
assertThat ( scopes . stream ( ) . map ( DomElement : : getId ) . collect ( Collectors . toList ( ) ) )
. containsExactlyInAnyOrder ( "openid" , "message.read" , "message.write" ) ;
assertThat ( scopes . stream ( ) . allMatch ( HtmlCheckBoxInput : : isChecked ) ) . isTrue ( ) ;
List < String > scopeIds = new ArrayList < > ( ) ;
scopes . forEach ( scope - > {
assertThat ( scope . isChecked ( ) ) . isTrue ( ) ;
scopeIds . add ( scope . getId ( ) ) ;
} ) ;
assertThat ( scopeIds ) . containsExactlyInAnyOrder ( "openid" , "message.read" , "message.write" ) ;
DomElement submitConsentButton = consentPage . querySelector ( "button[id='submit-consent']" ) ;
this . webClient . getOptions ( ) . setRedirectEnabled ( false ) ;
@ -103,14 +103,14 @@ public class OAuth2AuthorizationServerCustomConsentPageApplicationTests {
@@ -103,14 +103,14 @@ public class OAuth2AuthorizationServerCustomConsentPageApplicationTests {
WebResponse approveConsentResponse = submitConsentButton . click ( ) . getWebResponse ( ) ;
assertThat ( approveConsentResponse . getStatusCode ( ) ) . isEqualTo ( HttpStatus . MOVED_PERMANENTLY . value ( ) ) ;
String location = approveConsentResponse . getResponseHeaderValue ( "location" ) ;
assertThat ( location ) . startsWith ( testConsentResultEndpoint ) ;
assertThat ( location ) . startsWith ( this . redirectUri ) ;
assertThat ( location ) . contains ( "code=" ) ;
}
@Test
@WithMockUser ( "user1" )
public void whenUserCancelsApproving ConsentThenReturnA nAccessDeniedError ( ) throws IOException {
final HtmlPage consentPage = webClient . getPage ( authorizeEndpoint ) ;
public void whenUserCancelsConsentThenReturnAccessDeniedError ( ) throws IOException {
final HtmlPage consentPage = this . webClient . getPage ( this . authorizationRequestUri ) ;
assertThat ( consentPage . getTitleText ( ) ) . isEqualTo ( "Custom consent page - Consent required" ) ;
DomElement cancelConsentButton = consentPage . querySelector ( "button[id='cancel-consent']" ) ;
@ -119,14 +119,8 @@ public class OAuth2AuthorizationServerCustomConsentPageApplicationTests {
@@ -119,14 +119,8 @@ public class OAuth2AuthorizationServerCustomConsentPageApplicationTests {
WebResponse cancelConsentResponse = cancelConsentButton . click ( ) . getWebResponse ( ) ;
assertThat ( cancelConsentResponse . getStatusCode ( ) ) . isEqualTo ( HttpStatus . MOVED_PERMANENTLY . value ( ) ) ;
String location = cancelConsentResponse . getResponseHeaderValue ( "location" ) ;
assertThat ( location ) . startsWith ( this . redirectUri ) ;
assertThat ( location ) . contains ( "error=access_denied" ) ;
}
@TestConfiguration
static class InMemoryOAuth2AuthorizationServiceTestConfiguration {
@Bean
public OAuth2AuthorizationService authorizationService ( ) {
return new InMemoryOAuth2AuthorizationService ( ) ;
}
}
}