From 33849011c8fb318f638469bb4590a68ae60cd25a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Filipe=20Sabino=20Esperancinha?= Date: Sun, 26 Jan 2020 23:21:45 +0100 Subject: [PATCH] [BAEL-3339] - Creates @CurrentSecurityContext example (#8469) * [BAEL-3339] - Creates @CurrentSecurityContext example * [BAEL-3339] - Adds principal example * [BAEL-3339] - Code refactoring and improvements * [BAEL-3339] - Code cleanup * [BAEL-3339] - Authentication to return token details * [BAEL-3339] - Code cleanup --- spring-boot-security/pom.xml | 10 +++++ ...ingBootAuthorizationServerApplication.java | 17 +++++++++ ...figAuthorizationServerIntegrationTest.java | 37 +++++++++++++++++++ .../OAuth2IntegrationTestSupport.java | 21 ++++++++++- 4 files changed, 84 insertions(+), 1 deletion(-) diff --git a/spring-boot-security/pom.xml b/spring-boot-security/pom.xml index c9113e263f..92397d42f8 100644 --- a/spring-boot-security/pom.xml +++ b/spring-boot-security/pom.xml @@ -24,6 +24,16 @@ spring-security-oauth2 2.4.0.RELEASE + + org.springframework.security + spring-security-core + 5.2.1.RELEASE + + + commons-io + commons-io + 2.6 + org.springframework.security.oauth.boot spring-security-oauth2-autoconfigure diff --git a/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/oauth2server/SpringBootAuthorizationServerApplication.java b/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/oauth2server/SpringBootAuthorizationServerApplication.java index 44dabefbb8..04f046ff78 100644 --- a/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/oauth2server/SpringBootAuthorizationServerApplication.java +++ b/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/oauth2server/SpringBootAuthorizationServerApplication.java @@ -1,7 +1,11 @@ package com.baeldung.springbootsecurity.oauth2server; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.annotation.CurrentSecurityContext; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.web.bind.annotation.GetMapping; @@ -14,6 +18,8 @@ import java.security.Principal; @SpringBootApplication(scanBasePackages = "com.baeldung.springbootsecurity.oauth2server") public class SpringBootAuthorizationServerApplication { + private static final Logger logger = LoggerFactory.getLogger(SpringBootAuthorizationServerApplication.class); + public static void main(String[] args) { SpringApplication.run(SpringBootAuthorizationServerApplication.class, args); } @@ -26,5 +32,16 @@ public class SpringBootAuthorizationServerApplication { return user; } + @GetMapping("/authentication") + public Object getAuthentication(@CurrentSecurityContext(expression = "authentication") Authentication authentication) { + logger.info("authentication -> {}", authentication); + return authentication.getDetails(); + } + + @GetMapping("/principal") + public String getPrincipal(@CurrentSecurityContext(expression = "authentication.principal") Principal principal) { + logger.info("principal -> {}", principal); + return principal.getName(); + } } } diff --git a/spring-boot-security/src/test/java/com/baeldung/springbootsecurity/oauth2server/CustomConfigAuthorizationServerIntegrationTest.java b/spring-boot-security/src/test/java/com/baeldung/springbootsecurity/oauth2server/CustomConfigAuthorizationServerIntegrationTest.java index cc953eef5a..104e115b18 100644 --- a/spring-boot-security/src/test/java/com/baeldung/springbootsecurity/oauth2server/CustomConfigAuthorizationServerIntegrationTest.java +++ b/spring-boot-security/src/test/java/com/baeldung/springbootsecurity/oauth2server/CustomConfigAuthorizationServerIntegrationTest.java @@ -1,8 +1,10 @@ package com.baeldung.springbootsecurity.oauth2server; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.security.oauth2.client.OAuth2RestTemplate; import org.springframework.security.oauth2.client.resource.OAuth2AccessDeniedException; import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails; @@ -10,8 +12,13 @@ import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; +import java.net.URL; +import java.util.regex.Pattern; + import static java.util.Collections.singletonList; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; @RunWith(SpringRunner.class) @@ -19,6 +26,14 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen @ActiveProfiles("authz") public class CustomConfigAuthorizationServerIntegrationTest extends OAuth2IntegrationTestSupport { + @LocalServerPort + private int port; + + @Before + public void setUp() throws Exception { + base = new URL("http://localhost:" + port); + } + @Test public void givenOAuth2Context_whenAccessTokenIsRequested_ThenAccessTokenValueIsNotNull() { ClientCredentialsResourceDetails resourceDetails = getClientCredentialsResourceDetails("baeldung", singletonList("read")); @@ -27,7 +42,29 @@ public class CustomConfigAuthorizationServerIntegrationTest extends OAuth2Integr OAuth2AccessToken accessToken = restTemplate.getAccessToken(); assertNotNull(accessToken); + } + @Test + public void givenOAuth2Context_whenAccessingAuthentication_ThenRespondTokenDetails() { + ClientCredentialsResourceDetails resourceDetails = getClientCredentialsResourceDetails("baeldung", singletonList("read")); + OAuth2RestTemplate restTemplate = getOAuth2RestTemplate(resourceDetails); + + String authentication = executeGetRequest(restTemplate, "/authentication"); + + Pattern pattern = Pattern.compile("\\{\"remoteAddress\":\".*" + + "\",\"sessionId\":null,\"tokenValue\":\".*" + + "\",\"tokenType\":\"Bearer\",\"decodedDetails\":null}"); + assertTrue("authentication", pattern.matcher(authentication).matches()); + } + + @Test + public void givenOAuth2Context_whenAccessingPrincipal_ThenRespondBaeldung() { + ClientCredentialsResourceDetails resourceDetails = getClientCredentialsResourceDetails("baeldung", singletonList("read")); + OAuth2RestTemplate restTemplate = getOAuth2RestTemplate(resourceDetails); + + String principal = executeGetRequest(restTemplate, "/principal"); + + assertEquals("baeldung", principal); } @Test(expected = OAuth2AccessDeniedException.class) diff --git a/spring-boot-security/src/test/java/com/baeldung/springbootsecurity/oauth2server/OAuth2IntegrationTestSupport.java b/spring-boot-security/src/test/java/com/baeldung/springbootsecurity/oauth2server/OAuth2IntegrationTestSupport.java index 3eef206c7d..a005965998 100644 --- a/spring-boot-security/src/test/java/com/baeldung/springbootsecurity/oauth2server/OAuth2IntegrationTestSupport.java +++ b/spring-boot-security/src/test/java/com/baeldung/springbootsecurity/oauth2server/OAuth2IntegrationTestSupport.java @@ -1,19 +1,33 @@ package com.baeldung.springbootsecurity.oauth2server; +import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext; import org.springframework.security.oauth2.client.OAuth2RestTemplate; import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails; +import org.springframework.web.client.RequestCallback; +import org.springframework.web.client.ResponseExtractor; +import java.net.URL; +import java.nio.charset.Charset; import java.util.List; import static java.lang.String.format; import static java.util.Collections.singletonList; +import static org.springframework.http.HttpMethod.GET; public class OAuth2IntegrationTestSupport { - @Value("${local.server.port}") protected int port; + public static final ResponseExtractor EXTRACT_BODY_AS_STRING = clientHttpResponse -> + IOUtils.toString(clientHttpResponse.getBody(), Charset.defaultCharset()); + private static final RequestCallback DO_NOTHING_CALLBACK = request -> { + }; + + @Value("${local.server.port}") + protected int port; + + protected URL base; protected ClientCredentialsResourceDetails getClientCredentialsResourceDetails(final String clientId, final List scopes) { ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails(); @@ -31,4 +45,9 @@ public class OAuth2IntegrationTestSupport { restTemplate.setMessageConverters(singletonList(new MappingJackson2HttpMessageConverter())); return restTemplate; } + + protected String executeGetRequest(OAuth2RestTemplate restTemplate, String path) { + return restTemplate.execute(base.toString() + path, GET, DO_NOTHING_CALLBACK, EXTRACT_BODY_AS_STRING); + } + }