diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java index 9af98ab6e..c683e0f3d 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java @@ -111,7 +111,7 @@ public OAuth2Authentication loadAuthentication(String accessToken) throws Authen } // gh-838 - if (!Boolean.TRUE.equals(map.get("active"))) { + if (map.containsKey("active") && !"true".equals(String.valueOf(map.get("active")))) { logger.debug("check_token returned active attribute: " + map.get("active")); throw new InvalidTokenException(accessToken); } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/RemoteTokenServicesTest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/RemoteTokenServicesTest.java index 709755ff5..5d156fbeb 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/RemoteTokenServicesTest.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/RemoteTokenServicesTest.java @@ -53,7 +53,7 @@ public void setUp() { // gh-838 @Test - public void loadAuthenticationWhenIntrospectionResponseContainsActiveTrueThenReturnAuthentication() throws Exception { + public void loadAuthenticationWhenIntrospectionResponseContainsActiveTrueBooleanThenReturnAuthentication() throws Exception { Map responseAttrs = new HashMap(); responseAttrs.put("active", true); // "active" is the only required attribute as per RFC 7662 (https://tools.ietf.org/search/rfc7662#section-2.2) ResponseEntity response = new ResponseEntity(responseAttrs, HttpStatus.OK); @@ -65,6 +65,19 @@ public void loadAuthenticationWhenIntrospectionResponseContainsActiveTrueThenRet assertNotNull(authentication); } + @Test + public void loadAuthenticationWhenIntrospectionResponseContainsActiveTrueStringThenReturnAuthentication() throws Exception { + Map responseAttrs = new HashMap(); + responseAttrs.put("active", "true"); // "active" is the only required attribute as per RFC 7662 (https://tools.ietf.org/search/rfc7662#section-2.2) + ResponseEntity response = new ResponseEntity(responseAttrs, HttpStatus.OK); + RestTemplate restTemplate = mock(RestTemplate.class); + when(restTemplate.exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), any(Class.class))).thenReturn(response); + this.remoteTokenServices.setRestTemplate(restTemplate); + + OAuth2Authentication authentication = this.remoteTokenServices.loadAuthentication("access-token-1234"); + assertNotNull(authentication); + } + // gh-838 @Test(expected = InvalidTokenException.class) public void loadAuthenticationWhenIntrospectionResponseContainsActiveFalseThenThrowInvalidTokenException() throws Exception { @@ -79,14 +92,15 @@ public void loadAuthenticationWhenIntrospectionResponseContainsActiveFalseThenTh } // gh-838 - @Test(expected = InvalidTokenException.class) - public void loadAuthenticationWhenIntrospectionResponseMissingActiveAttributeThenThrowInvalidTokenException() throws Exception { + @Test + public void loadAuthenticationWhenIntrospectionResponseMissingActiveAttributeThenReturnAuthentication() throws Exception { Map responseAttrs = new HashMap(); ResponseEntity response = new ResponseEntity(responseAttrs, HttpStatus.OK); RestTemplate restTemplate = mock(RestTemplate.class); when(restTemplate.exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), any(Class.class))).thenReturn(response); this.remoteTokenServices.setRestTemplate(restTemplate); - this.remoteTokenServices.loadAuthentication("access-token-1234"); + OAuth2Authentication authentication = this.remoteTokenServices.loadAuthentication("access-token-1234"); + assertNotNull(authentication); } } \ No newline at end of file