getDomain() {
+ Authentication auth = SecurityContextHolder.getContext()
+ .getAuthentication();
+ String domain = null;
+ if (auth != null && !auth.getClass().equals(AnonymousAuthenticationToken.class)) {
+ User user = (User) auth.getPrincipal();
+ domain = user.getDomain();
+ }
+ return Optional.ofNullable(domain);
+ }
+}
diff --git a/spring-5-security/src/main/resources/application-extrafields.properties b/spring-5-security/src/main/resources/application-extrafields.properties
new file mode 100644
index 0000000000..ab4134ce3e
--- /dev/null
+++ b/spring-5-security/src/main/resources/application-extrafields.properties
@@ -0,0 +1 @@
+spring.thymeleaf.prefix = classpath:/templatesextrafields/
\ No newline at end of file
diff --git a/spring-5-security/src/main/resources/static/css/main.css b/spring-5-security/src/main/resources/static/css/main.css
new file mode 100644
index 0000000000..9299ee6158
--- /dev/null
+++ b/spring-5-security/src/main/resources/static/css/main.css
@@ -0,0 +1,18 @@
+body {
+ font-family: sans;
+ font-size: 1em;
+}
+
+p.error {
+ font-weight: bold;
+ color: red;
+}
+
+div.logout {
+ float: right;
+}
+
+.formfield {
+ margin: 0.5em;
+ padding: 0.3em;
+}
\ No newline at end of file
diff --git a/spring-5-security/src/main/resources/templatesextrafields/index.html b/spring-5-security/src/main/resources/templatesextrafields/index.html
new file mode 100644
index 0000000000..52f6224dfb
--- /dev/null
+++ b/spring-5-security/src/main/resources/templatesextrafields/index.html
@@ -0,0 +1,24 @@
+
+
+
+ Spring Security - Login With Extra Fields
+
+
+
+
+
+ Logged in user:
|
+ domain:
Some Domain
+
+
+
+
+ Hello Spring Security
+ This is an unsecured page, but you can access the secured pages after authenticating.
+
+
+
diff --git a/spring-5-security/src/main/resources/templatesextrafields/login.html b/spring-5-security/src/main/resources/templatesextrafields/login.html
new file mode 100644
index 0000000000..cafec89c15
--- /dev/null
+++ b/spring-5-security/src/main/resources/templatesextrafields/login.html
@@ -0,0 +1,23 @@
+
+
+
+ Login page
+
+
+
+
+ Login page
+ Example: user / domain / password
+ Invalid user, password, or domain
+
+ Back to home page
+
+
diff --git a/spring-5-security/src/main/resources/templatesextrafields/user/index.html b/spring-5-security/src/main/resources/templatesextrafields/user/index.html
new file mode 100644
index 0000000000..a4c1535100
--- /dev/null
+++ b/spring-5-security/src/main/resources/templatesextrafields/user/index.html
@@ -0,0 +1,13 @@
+
+
+
+ Spring Security - Login With Extra Fields
+
+
+
+
+
+ This is a secured page!
+ Back to home page
+
+
diff --git a/spring-5-security/src/test/java/com/baeldung/securityextrafields/SecurityExtraFieldsTest.java b/spring-5-security/src/test/java/com/baeldung/securityextrafields/SecurityExtraFieldsTest.java
new file mode 100644
index 0000000000..cf0701708d
--- /dev/null
+++ b/spring-5-security/src/test/java/com/baeldung/securityextrafields/SecurityExtraFieldsTest.java
@@ -0,0 +1,103 @@
+package com.baeldung.securityextrafields;
+
+import static org.junit.Assert.assertEquals;
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
+import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+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.context.SpringBootTest;
+import org.springframework.mock.web.MockHttpSession;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.web.FilterChainProxy;
+import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
+import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+@RunWith(SpringRunner.class)
+@SpringJUnitWebConfig
+@SpringBootTest(classes = SpringExtraLoginFieldsApplication.class)
+public class SecurityExtraFieldsTest {
+
+ @Autowired
+ private FilterChainProxy springSecurityFilterChain;
+
+ @Autowired
+ private WebApplicationContext wac;
+
+ private MockMvc mockMvc;
+
+ @Before
+ public void setup() {
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(wac)
+ .apply(springSecurity(springSecurityFilterChain)).build();
+ }
+
+ @Test
+ public void givenRootPathAccess_thenRedirectToIndex() throws Exception {
+ this.mockMvc.perform(get("/"))
+ .andExpect(status().is3xxRedirection())
+ .andExpect(redirectedUrlPattern("/index*"));
+ }
+
+ @Test
+ public void givenSecuredResource_whenAccessUnauthenticated_thenRequiresAuthentication() throws Exception {
+ this.mockMvc.perform(get("/user/index"))
+ .andExpect(status().is3xxRedirection())
+ .andExpect(redirectedUrlPattern("**/login"));
+ }
+
+ @Test
+ public void givenAccessSecuredResource_whenAuthenticated_thenAuthHasExtraFields() throws Exception {
+ MockHttpServletRequestBuilder securedResourceAccess = get("/user/index");
+ MvcResult unauthenticatedResult = mockMvc.perform(securedResourceAccess)
+ .andExpect(status().is3xxRedirection())
+ .andReturn();
+
+ MockHttpSession session = (MockHttpSession) unauthenticatedResult.getRequest()
+ .getSession();
+ String loginUrl = unauthenticatedResult.getResponse()
+ .getRedirectedUrl();
+
+ User user = getUser();
+
+ mockMvc.perform(post(loginUrl)
+ .param("username", user.getUsername())
+ .param("password", user.getPassword())
+ .param("domain", user.getDomain())
+ .session(session)
+ .with(csrf()))
+ .andExpect(status().is3xxRedirection())
+ .andExpect(redirectedUrlPattern("**/user/index"))
+ .andReturn();
+
+ mockMvc.perform(securedResourceAccess.session(session))
+ .andExpect(status().isOk());
+
+ SecurityContext securityContext
+ = (SecurityContext) session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
+ Authentication auth = securityContext.getAuthentication();
+ assertEquals(((User)auth.getPrincipal()).getDomain(), user.getDomain());
+ }
+
+ private User getUser() {
+ Collection extends GrantedAuthority> authorities = new ArrayList<>();
+ return new User("myusername", "mydomain", "password", true, true, true, true, authorities);
+ }
+}
diff --git a/spring-boot-security/README.md b/spring-boot-security/README.md
index 26ab8b2337..a0ddb8de7b 100644
--- a/spring-boot-security/README.md
+++ b/spring-boot-security/README.md
@@ -1,6 +1,8 @@
### Spring Boot Security Auto-Configuration
- mvn clean install
-- uncomment in application.properties spring.profiles.active=basic # for basic auth config
-- uncomment in application.properties spring.profiles.active=form # for form based auth config
-- uncomment actuator dependency simultaneously with the line from main class
+- uncomment actuator dependency simultaneously with the line from basic auth main class
+- uncomment security properties for easy testing. If not random will be generated.
+
+### CURL commands
+- curl -X POST -u baeldung-admin:baeldung -d grant_type=client_credentials -d username=baeldung-admin -d password=baeldung http://localhost:8080/oauth/token
diff --git a/spring-boot-security/pom.xml b/spring-boot-security/pom.xml
index c35191a7fc..c1ec14ff64 100644
--- a/spring-boot-security/pom.xml
+++ b/spring-boot-security/pom.xml
@@ -43,6 +43,10 @@
org.springframework.boot
spring-boot-starter-security
+
+ org.springframework.security.oauth
+ spring-security-oauth2
+
org.springframework.boot
spring-boot-starter-web
diff --git a/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/SpringBootSecurityApplication.java b/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/basic_auth/SpringBootSecurityApplication.java
similarity index 80%
rename from spring-boot-security/src/main/java/com/baeldung/springbootsecurity/SpringBootSecurityApplication.java
rename to spring-boot-security/src/main/java/com/baeldung/springbootsecurity/basic_auth/SpringBootSecurityApplication.java
index 3a85da72e5..2ecad4ae35 100644
--- a/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/SpringBootSecurityApplication.java
+++ b/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/basic_auth/SpringBootSecurityApplication.java
@@ -1,4 +1,4 @@
-package com.baeldung.springbootsecurity;
+package com.baeldung.springbootsecurity.basic_auth;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -7,7 +7,7 @@ import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration
@SpringBootApplication(exclude = {
SecurityAutoConfiguration.class
// ,ManagementWebSecurityAutoConfiguration.class
-})
+}, scanBasePackages = "com.baeldung.springbootsecurity.basic_auth")
public class SpringBootSecurityApplication {
public static void main(String[] args) {
diff --git a/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/config/BasicConfiguration.java b/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/basic_auth/config/BasicAuthConfiguration.java
similarity index 84%
rename from spring-boot-security/src/main/java/com/baeldung/springbootsecurity/config/BasicConfiguration.java
rename to spring-boot-security/src/main/java/com/baeldung/springbootsecurity/basic_auth/config/BasicAuthConfiguration.java
index 1b08e5ee22..993c573fb0 100644
--- a/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/config/BasicConfiguration.java
+++ b/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/basic_auth/config/BasicAuthConfiguration.java
@@ -1,7 +1,6 @@
-package com.baeldung.springbootsecurity.config;
+package com.baeldung.springbootsecurity.basic_auth.config;
import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Profile;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
@@ -9,8 +8,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
@Configuration
@EnableWebSecurity
-@Profile("basic")
-public class BasicConfiguration extends WebSecurityConfigurerAdapter {
+public class BasicAuthConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
diff --git a/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/config/FormLoginConfiguration.java b/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/config/FormLoginConfiguration.java
deleted file mode 100644
index b4902a9ffc..0000000000
--- a/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/config/FormLoginConfiguration.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.baeldung.springbootsecurity.config;
-
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Profile;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-
-@Configuration
-@EnableWebSecurity
-@Profile("form")
-public class FormLoginConfiguration extends WebSecurityConfigurerAdapter {
-
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- auth
- .inMemoryAuthentication()
- .withUser("user")
- .password("password")
- .roles("USER")
- .and()
- .withUser("admin")
- .password("password")
- .roles("USER", "ADMIN");
- }
-
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- http
- .authorizeRequests()
- .anyRequest()
- .authenticated()
- .and()
- .formLogin()
- .and()
- .httpBasic();
- }
-}
diff --git a/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/oauth2resource/SpringBootOAuth2ResourceApplication.java b/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/oauth2resource/SpringBootOAuth2ResourceApplication.java
new file mode 100644
index 0000000000..56231a28bd
--- /dev/null
+++ b/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/oauth2resource/SpringBootOAuth2ResourceApplication.java
@@ -0,0 +1,30 @@
+package com.baeldung.springbootsecurity.oauth2resource;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@EnableResourceServer
+@SpringBootApplication(scanBasePackages = "com.baeldung.springbootsecurity.oauth2resource")
+public class SpringBootOAuth2ResourceApplication {
+
+ public static void main(String[] args) {
+ new SpringApplicationBuilder()
+ .profiles("resource")
+ .sources(SpringBootOAuth2ResourceApplication.class)
+ .build()
+ .run(args);
+ }
+
+ @RestController
+ class SecuredResourceController {
+
+ @GetMapping("/securedResource")
+ public String securedResource() {
+ return "Baeldung Secured Resource OK";
+ }
+
+ }
+}
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
new file mode 100644
index 0000000000..44dabefbb8
--- /dev/null
+++ b/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/oauth2server/SpringBootAuthorizationServerApplication.java
@@ -0,0 +1,30 @@
+package com.baeldung.springbootsecurity.oauth2server;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+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;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.security.Principal;
+
+@EnableResourceServer
+@EnableAuthorizationServer
+@SpringBootApplication(scanBasePackages = "com.baeldung.springbootsecurity.oauth2server")
+public class SpringBootAuthorizationServerApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringBootAuthorizationServerApplication.class, args);
+ }
+
+ @RestController
+ class UserController {
+
+ @GetMapping("/user")
+ public Principal user(Principal user) {
+ return user;
+ }
+
+ }
+}
diff --git a/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/oauth2server/config/AuthorizationServerConfig.java b/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/oauth2server/config/AuthorizationServerConfig.java
new file mode 100644
index 0000000000..b403feb5c1
--- /dev/null
+++ b/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/oauth2server/config/AuthorizationServerConfig.java
@@ -0,0 +1,39 @@
+package com.baeldung.springbootsecurity.oauth2server.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
+import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
+
+@Configuration
+@Profile("authz")
+public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
+
+ @Autowired
+ private AuthenticationManager authenticationManager;
+
+ @Override
+ public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
+ endpoints.authenticationManager(authenticationManager);
+ }
+
+ @Override
+ public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
+ clients
+ .inMemory()
+ .withClient("baeldung")
+ .secret("baeldung")
+ .authorizedGrantTypes("client_credentials", "password", "authorization_code")
+ .scopes("openid", "read")
+ .autoApprove(true)
+ .and()
+ .withClient("baeldung-admin")
+ .secret("baeldung")
+ .authorizedGrantTypes("authorization_code", "client_credentials", "refresh_token")
+ .scopes("read", "write")
+ .autoApprove(true);
+ }
+}
diff --git a/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/oauth2sso/SpringBootOAuth2SsoApplication.java b/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/oauth2sso/SpringBootOAuth2SsoApplication.java
new file mode 100644
index 0000000000..b1cd580f08
--- /dev/null
+++ b/spring-boot-security/src/main/java/com/baeldung/springbootsecurity/oauth2sso/SpringBootOAuth2SsoApplication.java
@@ -0,0 +1,18 @@
+package com.baeldung.springbootsecurity.oauth2sso;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+
+@EnableOAuth2Sso
+@SpringBootApplication(scanBasePackages = "com.baeldung.springbootsecurity.oauth2sso")
+public class SpringBootOAuth2SsoApplication {
+
+ public static void main(String[] args) {
+ new SpringApplicationBuilder()
+ .profiles("sso")
+ .sources(SpringBootOAuth2SsoApplication.class)
+ .build()
+ .run(args);
+ }
+}
diff --git a/spring-boot-security/src/main/resources/application-authz.properties b/spring-boot-security/src/main/resources/application-authz.properties
new file mode 100644
index 0000000000..d29b0cdd3c
--- /dev/null
+++ b/spring-boot-security/src/main/resources/application-authz.properties
@@ -0,0 +1,3 @@
+security.user.password=password
+security.oauth2.client.client-id=client
+security.oauth2.client.client-secret=secret
diff --git a/spring-boot-security/src/main/resources/application-resource.properties b/spring-boot-security/src/main/resources/application-resource.properties
new file mode 100644
index 0000000000..b157b01d51
--- /dev/null
+++ b/spring-boot-security/src/main/resources/application-resource.properties
@@ -0,0 +1,2 @@
+server.port=8081
+security.oauth2.resource.userInfoUri=http://localhost:8080/user
\ No newline at end of file
diff --git a/spring-boot-security/src/main/resources/application-sso.properties b/spring-boot-security/src/main/resources/application-sso.properties
new file mode 100644
index 0000000000..ac6ae0cc93
--- /dev/null
+++ b/spring-boot-security/src/main/resources/application-sso.properties
@@ -0,0 +1,9 @@
+server.port=8082
+security.oauth2.client.clientId=
+security.oauth2.client.clientSecret=
+security.oauth2.client.accessTokenUri=https://graph.facebook.com/oauth/access_token
+security.oauth2.client.userAuthorizationUri=https://www.facebook.com/dialog/oauth
+security.oauth2.client.tokenName=oauth_token
+security.oauth2.client.authenticationScheme=query
+security.oauth2.client.clientAuthenticationScheme=form
+security.oauth2.resource.userInfoUri=https://graph.facebook.com/me
\ No newline at end of file
diff --git a/spring-boot-security/src/main/resources/application.properties b/spring-boot-security/src/main/resources/application.properties
index 6ca2edb175..c2b8d70dc6 100644
--- a/spring-boot-security/src/main/resources/application.properties
+++ b/spring-boot-security/src/main/resources/application.properties
@@ -1,4 +1,4 @@
#spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration
-#spring.profiles.active=form
-#spring.profiles.active=basic
-#security.user.password=password
\ No newline at end of file
+#security.user.password=password
+#security.oauth2.client.client-id=client
+#security.oauth2.client.client-secret=secret
diff --git a/spring-boot-security/src/test/java/com/baeldung/springbootsecurity/FormConfigurationIntegrationTest.java b/spring-boot-security/src/test/java/com/baeldung/springbootsecurity/FormConfigurationIntegrationTest.java
deleted file mode 100644
index 697a4f2868..0000000000
--- a/spring-boot-security/src/test/java/com/baeldung/springbootsecurity/FormConfigurationIntegrationTest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package com.baeldung.springbootsecurity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.context.embedded.LocalServerPort;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.web.client.TestRestTemplate;
-import org.springframework.http.*;
-import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.util.LinkedMultiValueMap;
-import org.springframework.util.MultiValueMap;
-
-import java.util.Collections;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import static org.junit.Assert.*;
-import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
-
-@RunWith(SpringRunner.class)
-@SpringBootTest(webEnvironment = RANDOM_PORT)
-@ActiveProfiles("form")
-public class FormConfigurationIntegrationTest {
-
- @Autowired TestRestTemplate restTemplate;
- @LocalServerPort int port;
-
- @Test
- public void whenLoginPageIsRequested_ThenSuccess() {
- HttpHeaders httpHeaders = new HttpHeaders();
- httpHeaders.setAccept(Collections.singletonList(MediaType.TEXT_HTML));
- ResponseEntity responseEntity = restTemplate.exchange("/login", HttpMethod.GET, new HttpEntity(httpHeaders), String.class);
- assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
- assertTrue(responseEntity
- .getBody()
- .contains("_csrf"));
- }
-
- @Test
- public void whenTryingToLoginWithCorrectCredentials_ThenAuthenticateWithSuccess() {
- HttpHeaders httpHeaders = getHeaders();
- httpHeaders.setAccept(Collections.singletonList(MediaType.TEXT_HTML));
- httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
- MultiValueMap form = getFormSubmitCorrectCredentials();
- ResponseEntity responseEntity = this.restTemplate.exchange("/login", HttpMethod.POST, new HttpEntity<>(form, httpHeaders), String.class);
- assertEquals(responseEntity.getStatusCode(), HttpStatus.FOUND);
- assertTrue(responseEntity
- .getHeaders()
- .getLocation()
- .toString()
- .endsWith(this.port + "/"));
- assertNotNull(responseEntity
- .getHeaders()
- .get("Set-Cookie"));
- }
-
- @Test
- public void whenTryingToLoginWithInorrectCredentials_ThenAuthenticationFailed() {
- HttpHeaders httpHeaders = getHeaders();
- httpHeaders.setAccept(Collections.singletonList(MediaType.TEXT_HTML));
- httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
- MultiValueMap form = getFormSubmitIncorrectCredentials();
- ResponseEntity responseEntity = this.restTemplate.exchange("/login", HttpMethod.POST, new HttpEntity<>(form, httpHeaders), String.class);
- assertEquals(responseEntity.getStatusCode(), HttpStatus.FOUND);
- assertTrue(responseEntity
- .getHeaders()
- .getLocation()
- .toString()
- .endsWith(this.port + "/login?error"));
- assertNull(responseEntity
- .getHeaders()
- .get("Set-Cookie"));
- }
-
- private MultiValueMap getFormSubmitCorrectCredentials() {
- MultiValueMap form = new LinkedMultiValueMap<>();
- form.set("username", "user");
- form.set("password", "password");
- return form;
- }
-
- private MultiValueMap getFormSubmitIncorrectCredentials() {
- MultiValueMap form = new LinkedMultiValueMap<>();
- form.set("username", "user");
- form.set("password", "wrongpassword");
- return form;
- }
-
- private HttpHeaders getHeaders() {
- HttpHeaders headers = new HttpHeaders();
- ResponseEntity page = this.restTemplate.getForEntity("/login", String.class);
- assertEquals(page.getStatusCode(), HttpStatus.OK);
- String cookie = page
- .getHeaders()
- .getFirst("Set-Cookie");
- headers.set("Cookie", cookie);
- Pattern pattern = Pattern.compile("(?s).*name=\"_csrf\".*?value=\"([^\"]+).*");
- Matcher matcher = pattern.matcher(page.getBody());
- assertTrue(matcher.matches());
- headers.set("X-CSRF-TOKEN", matcher.group(1));
- return headers;
- }
-
-}
diff --git a/spring-boot-security/src/test/java/com/baeldung/springbootsecurity/BasicConfigurationIntegrationTest.java b/spring-boot-security/src/test/java/com/baeldung/springbootsecurity/basic_auth/BasicAuthConfigurationIntegrationTest.java
similarity index 86%
rename from spring-boot-security/src/test/java/com/baeldung/springbootsecurity/BasicConfigurationIntegrationTest.java
rename to spring-boot-security/src/test/java/com/baeldung/springbootsecurity/basic_auth/BasicAuthConfigurationIntegrationTest.java
index 63e1c2ac73..4e4244abb7 100644
--- a/spring-boot-security/src/test/java/com/baeldung/springbootsecurity/BasicConfigurationIntegrationTest.java
+++ b/spring-boot-security/src/test/java/com/baeldung/springbootsecurity/basic_auth/BasicAuthConfigurationIntegrationTest.java
@@ -1,5 +1,6 @@
-package com.baeldung.springbootsecurity;
+package com.baeldung.springbootsecurity.basic_auth;
+import com.baeldung.springbootsecurity.basic_auth.SpringBootSecurityApplication;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -8,7 +9,6 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
-import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.IOException;
@@ -20,9 +20,8 @@ import static org.junit.Assert.assertTrue;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@RunWith(SpringRunner.class)
-@SpringBootTest(webEnvironment = RANDOM_PORT)
-@ActiveProfiles("basic")
-public class BasicConfigurationIntegrationTest {
+@SpringBootTest(webEnvironment = RANDOM_PORT, classes = SpringBootSecurityApplication.class)
+public class BasicAuthConfigurationIntegrationTest {
TestRestTemplate restTemplate;
URL base;
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
new file mode 100644
index 0000000000..09df9ce645
--- /dev/null
+++ b/spring-boot-security/src/test/java/com/baeldung/springbootsecurity/oauth2server/CustomConfigAuthorizationServerIntegrationTest.java
@@ -0,0 +1,75 @@
+package com.baeldung.springbootsecurity.oauth2server;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.SpringBootTest;
+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.resource.OAuth2AccessDeniedException;
+import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails;
+import org.springframework.security.oauth2.common.OAuth2AccessToken;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static java.lang.String.format;
+import static java.util.Collections.singletonList;
+import static org.junit.Assert.assertNotNull;
+import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = RANDOM_PORT, classes = SpringBootAuthorizationServerApplication.class)
+@ActiveProfiles("authz")
+public class CustomConfigAuthorizationServerIntegrationTest {
+
+ @Value("${local.server.port}") protected int port;
+
+ @Test
+ public void whenAccessTokenIsRequested_ThenAccessTokenValueIsNotNull() {
+ ClientCredentialsResourceDetails resourceDetails = getClientCredentialsResourceDetails();
+ resourceDetails.setClientId("baeldung");
+ resourceDetails.setClientSecret("baeldung");
+ resourceDetails.setScope(singletonList("read"));
+ DefaultOAuth2ClientContext clientContext = new DefaultOAuth2ClientContext();
+ OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails, clientContext);
+ restTemplate.setMessageConverters(singletonList(new MappingJackson2HttpMessageConverter()));
+ OAuth2AccessToken accessToken = restTemplate.getAccessToken();
+ assertNotNull(accessToken);
+
+ }
+
+ @Test(expected = OAuth2AccessDeniedException.class)
+ public void whenAccessTokenIsRequestedWithInvalidException_ThenExceptionIsThrown() {
+ ClientCredentialsResourceDetails resourceDetails = getClientCredentialsResourceDetails();
+ resourceDetails.setClientId("baeldung");
+ resourceDetails.setClientSecret("baeldung");
+ resourceDetails.setScope(singletonList("write"));
+ DefaultOAuth2ClientContext clientContext = new DefaultOAuth2ClientContext();
+ OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails, clientContext);
+ restTemplate.setMessageConverters(singletonList(new MappingJackson2HttpMessageConverter()));
+ restTemplate.getAccessToken();
+ }
+
+ @Test
+ public void whenAccessTokenIsRequestedByClientWithWriteScope_ThenAccessTokenIsNotNull() {
+ ClientCredentialsResourceDetails resourceDetails = getClientCredentialsResourceDetails();
+ resourceDetails.setClientId("baeldung-admin");
+ resourceDetails.setClientSecret("baeldung");
+ resourceDetails.setScope(singletonList("write"));
+ DefaultOAuth2ClientContext clientContext = new DefaultOAuth2ClientContext();
+ OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails, clientContext);
+ restTemplate.setMessageConverters(singletonList(new MappingJackson2HttpMessageConverter()));
+ OAuth2AccessToken accessToken = restTemplate.getAccessToken();
+ assertNotNull(accessToken);
+ }
+
+ private ClientCredentialsResourceDetails getClientCredentialsResourceDetails() {
+ ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails();
+ resourceDetails.setAccessTokenUri(format("http://localhost:%d/oauth/token", port));
+ resourceDetails.setGrantType("client_credentials");
+ return resourceDetails;
+ }
+
+}
+
diff --git a/spring-boot-security/src/test/java/com/baeldung/springbootsecurity/oauth2server/DefaultConfigAuthorizationServerIntegrationTest.java b/spring-boot-security/src/test/java/com/baeldung/springbootsecurity/oauth2server/DefaultConfigAuthorizationServerIntegrationTest.java
new file mode 100644
index 0000000000..c7b1b4ef6c
--- /dev/null
+++ b/spring-boot-security/src/test/java/com/baeldung/springbootsecurity/oauth2server/DefaultConfigAuthorizationServerIntegrationTest.java
@@ -0,0 +1,44 @@
+package com.baeldung.springbootsecurity.oauth2server;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.SpringBootTest;
+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.security.oauth2.common.OAuth2AccessToken;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static java.lang.String.format;
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
+import static org.junit.Assert.assertNotNull;
+import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = RANDOM_PORT, classes = SpringBootAuthorizationServerApplication.class,
+ properties = { "security.oauth2.client.client-id=client", "security.oauth2.client.client-secret=secret" })
+public class DefaultConfigAuthorizationServerIntegrationTest {
+
+ @Value("${local.server.port}") protected int port;
+
+ @Test
+ public void whenAccessTokenIsRequested_ThenAccessTokenValueIsNotNull() {
+ ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails();
+ resourceDetails.setAccessTokenUri(format("http://localhost:%d/oauth/token", port));
+ resourceDetails.setClientId("client");
+ resourceDetails.setClientSecret("secret");
+ resourceDetails.setGrantType("client_credentials");
+ resourceDetails.setScope(asList("read", "write"));
+ DefaultOAuth2ClientContext clientContext = new DefaultOAuth2ClientContext();
+ OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails, clientContext);
+ restTemplate.setMessageConverters(singletonList(new MappingJackson2HttpMessageConverter()));
+ OAuth2AccessToken accessToken = restTemplate.getAccessToken();
+ assertNotNull(accessToken);
+
+ }
+
+}
+
diff --git a/spring-cloud/README.md b/spring-cloud/README.md
index b24e5b0296..53b7606563 100644
--- a/spring-cloud/README.md
+++ b/spring-cloud/README.md
@@ -19,4 +19,6 @@
### Relevant Articles:
- [Introduction to Spring Cloud Rest Client with Netflix Ribbon](http://www.baeldung.com/spring-cloud-rest-client-with-netflix-ribbon)
- [An Introduction to Spring Cloud Zookeeper](http://www.baeldung.com/spring-cloud-zookeeper)
+- [An Introduction to Spring Cloud Zookeeper](http://www.baeldung.com/spring-cloud-zookeeper)
+- [Spring Cloud Connectors and Heroku](http://www.baeldung.com/spring-cloud-heroku)
+
diff --git a/spring-cloud/spring-cloud-security/README.md b/spring-cloud/spring-cloud-security/README.md
new file mode 100644
index 0000000000..39af52c077
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/README.md
@@ -0,0 +1,29 @@
+# README #
+
+This README would normally document whatever steps are necessary to get your application up and running.
+
+### What is this repository for? ###
+
+* Quick summary
+* Version
+* [Learn Markdown](https://bitbucket.org/tutorials/markdowndemo)
+
+### How do I get set up? ###
+
+* Summary of set up
+* Configuration
+* Dependencies
+* Database configuration
+* How to run tests
+* Deployment instructions
+
+### Contribution guidelines ###
+
+* Writing tests
+* Code review
+* Other guidelines
+
+### Who do I talk to? ###
+
+* Repo owner or admin
+* Other community or team contact
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-security/alias.rtf b/spring-cloud/spring-cloud-security/alias.rtf
new file mode 100644
index 0000000000..15509e1c83
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/alias.rtf
@@ -0,0 +1,28 @@
+myauthkey
+
+
+security:
+ oauth2:
+ resource:
+ jwt:
+ keyValue: |
+ -----BEGIN PUBLIC KEY-----
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjj4JDMgT4OoaXisEd8Nz
+ uiLwum9mh8BH1l9Atpe+uZkepf3Vnv0Bhxn0BGR+kYGwEHZPVpWsHEyTfIRdinaQ
+ vlPaxWJquQW25yYstrCuQTKJvFjSO/cX/V4OGi1RUj76mOpwzkm1Kui3R7Sfh8Zo
+ WO0GiWIFJqNBsZ9b1wOfBMXnge+A+u/qxVNnTFpwCVj6k2Yb4YUsmLNCmND7E3Ra
+ BnrNQWqMU2numhV+ADpmVH08m/+pWdZ896uYu/tvQnz3agvZPcFsEst7LcNAWQFT
+ eNLkfwVfepKWa9jPELemtTLf1MkMppU+Lj1UNCr8x4Y6EupRDZhplVNtqYsPNDpO
+ 7wIDAQAB
+ -----END PUBLIC KEY-----
+
+
+
+jwt:
+ certificate:
+ store:
+ file: classpath:/certificate/my-auth-server.jks
+ password: storepassword
+ key:
+ alias: myauthserver
+ password: keypassword
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-security/authserver/pom.xml b/spring-cloud/spring-cloud-security/authserver/pom.xml
new file mode 100644
index 0000000000..ed88ac046b
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/authserver/pom.xml
@@ -0,0 +1,42 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ authserver
+ 0.0.1-SNAPSHOT
+
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.5.9.RELEASE
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.cloud
+ spring-cloud-starter-oauth2
+ 1.1.2.RELEASE
+
+
+
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/AuthServer.java b/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/AuthServer.java
new file mode 100644
index 0000000000..c5b330b0e3
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/AuthServer.java
@@ -0,0 +1,12 @@
+package com.baeldung;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.*;
+
+@SpringBootApplication
+public class AuthServer {
+
+ public static void main(String[] args) {
+ SpringApplication.run(AuthServer.class, args);
+ }
+}
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/config/AuthServerConfigurer.java b/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/config/AuthServerConfigurer.java
new file mode 100644
index 0000000000..32e445f998
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/config/AuthServerConfigurer.java
@@ -0,0 +1,77 @@
+package com.baeldung.config;
+
+import java.security.KeyPair;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.core.io.Resource;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
+import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
+import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
+import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;
+
+@Configuration
+@EnableAuthorizationServer
+@Order(6)
+public class AuthServerConfigurer
+ extends
+ AuthorizationServerConfigurerAdapter {
+
+ @Value("${jwt.certificate.store.file}")
+ private Resource keystore;
+
+ @Value("${jwt.certificate.store.password}")
+ private String keystorePassword;
+
+ @Value("${jwt.certificate.key.alias}")
+ private String keyAlias;
+
+ @Value("${jwt.certificate.key.password}")
+ private String keyPassword;
+
+ @Autowired
+ private UserDetailsService userDetailsService;
+
+ @Override
+ public void configure(
+ ClientDetailsServiceConfigurer clients)
+ throws Exception {
+ clients
+ .inMemory()
+ .withClient("authserver")
+ .secret("passwordforauthserver")
+ .redirectUris("http://localhost:8080/")
+ .authorizedGrantTypes("authorization_code",
+ "refresh_token")
+ .scopes("myscope")
+ .autoApprove(true)
+ .accessTokenValiditySeconds(30)
+ .refreshTokenValiditySeconds(1800);
+ }
+
+ @Override
+ public void configure(
+ AuthorizationServerEndpointsConfigurer endpoints)
+ throws Exception {
+ endpoints
+ .accessTokenConverter(jwtAccessTokenConverter())
+ .userDetailsService(userDetailsService);
+ }
+
+ @Bean
+ public JwtAccessTokenConverter jwtAccessTokenConverter() {
+ KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(
+ keystore, keystorePassword.toCharArray());
+ KeyPair keyPair = keyStoreKeyFactory.getKeyPair(
+ keyAlias, keyPassword.toCharArray());
+ JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
+ converter.setKeyPair(keyPair);
+ return converter;
+ }
+}
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/config/ResourceServerConfigurer.java b/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/config/ResourceServerConfigurer.java
new file mode 100644
index 0000000000..f97544dc59
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/config/ResourceServerConfigurer.java
@@ -0,0 +1,21 @@
+package com.baeldung.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
+
+/**
+ * Our configuration for the OAuth2 User Info Resource Server.
+ */
+@Configuration
+@EnableResourceServer
+public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {
+ @Override
+ public void configure(HttpSecurity http) throws Exception {
+ http.antMatcher("/user")
+ .authorizeRequests()
+ .anyRequest()
+ .authenticated();
+ }
+}
diff --git a/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/config/WebMvcConfigurer.java b/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/config/WebMvcConfigurer.java
new file mode 100644
index 0000000000..23b56151e7
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/config/WebMvcConfigurer.java
@@ -0,0 +1,14 @@
+package com.baeldung.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+@Configuration
+public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
+
+ @Override
+ public void addViewControllers(ViewControllerRegistry registry) {
+ registry.addViewController("login").setViewName("login");
+ }
+}
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/config/WebSecurityConfigurer.java b/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/config/WebSecurityConfigurer.java
new file mode 100644
index 0000000000..44406b8fa0
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/config/WebSecurityConfigurer.java
@@ -0,0 +1,52 @@
+package com.baeldung.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;
+
+@Configuration
+@EnableWebSecurity
+@EnableOAuth2Client
+public class WebSecurityConfigurer
+ extends
+ WebSecurityConfigurerAdapter {
+
+
+ @Override
+ protected void configure(HttpSecurity http)
+ throws Exception {
+ http
+ .authorizeRequests()
+ .antMatchers("/login**").permitAll()
+ .anyRequest().authenticated()
+ .and().csrf()
+ .and().formLogin().loginPage("/login");
+ }
+
+ @Override
+ protected void configure(
+ AuthenticationManagerBuilder auth) throws Exception {
+ auth
+ .inMemoryAuthentication()
+ .withUser("user").password("user")
+ .roles("USER")
+ .and()
+ .withUser("admin").password("admin")
+ .roles("USER", "ADMIN");
+ }
+
+ @Override
+ @Bean(name = "userDetailsService")
+ public UserDetailsService userDetailsServiceBean()
+ throws Exception {
+ return super.userDetailsServiceBean();
+ }
+
+
+}
diff --git a/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/controller/ResourceController.java b/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/controller/ResourceController.java
new file mode 100644
index 0000000000..739a6f6240
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/controller/ResourceController.java
@@ -0,0 +1,20 @@
+package com.baeldung.controller;
+
+import java.security.Principal;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Because this application is also a User Info Resource Server, we expose info about the logged in user at:
+ *
+ * http://localhost:9090/auth/user
+ */
+@RestController
+public class ResourceController {
+
+ @RequestMapping("/user")
+ public Principal user(Principal user) {
+ return user;
+ }
+
+}
diff --git a/spring-cloud/spring-cloud-security/authserver/src/main/resources/application.yml b/spring-cloud/spring-cloud-security/authserver/src/main/resources/application.yml
new file mode 100644
index 0000000000..1dc63d3f0e
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/authserver/src/main/resources/application.yml
@@ -0,0 +1,21 @@
+# Make the application available at http://localhost:7070/authserver
+server:
+ port: 7070
+ contextPath: /authserver
+
+# Our certificate settings for enabling JWT tokens
+jwt:
+ certificate:
+ store:
+ file: classpath:/certificate/mykeystore.jks
+ password: abirkhan04
+ key:
+ alias: myauthkey
+ password: abirkhan04
+
+
+security:
+ oauth2:
+ resource:
+ filter-order: 3
+
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-security/authserver/src/main/resources/certificate/mykeystore.jks b/spring-cloud/spring-cloud-security/authserver/src/main/resources/certificate/mykeystore.jks
new file mode 100644
index 0000000000..9cf25e3224
Binary files /dev/null and b/spring-cloud/spring-cloud-security/authserver/src/main/resources/certificate/mykeystore.jks differ
diff --git a/spring-cloud/spring-cloud-security/authserver/src/main/resources/templates/login.html b/spring-cloud/spring-cloud-security/authserver/src/main/resources/templates/login.html
new file mode 100644
index 0000000000..f5ab5a6f26
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/authserver/src/main/resources/templates/login.html
@@ -0,0 +1,29 @@
+
+
+
+
+ Baeldung Spring cloud Security
+
+
+
+Login
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-security/mykeystore.jks b/spring-cloud/spring-cloud-security/mykeystore.jks
new file mode 100644
index 0000000000..9cf25e3224
Binary files /dev/null and b/spring-cloud/spring-cloud-security/mykeystore.jks differ
diff --git a/spring-cloud/spring-cloud-security/oauth2client/pom.xml b/spring-cloud/spring-cloud-security/oauth2client/pom.xml
new file mode 100644
index 0000000000..fd1c6964e1
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/oauth2client/pom.xml
@@ -0,0 +1,102 @@
+
+
+ 4.0.0
+ com.baeldung
+ oauth2client
+ 0.0.1-SNAPSHOT
+ jar
+
+ oauth2client
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.5.9.RELEASE
+
+
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ Dalston.SR4
+ pom
+ import
+
+
+
+
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.cloud
+ spring-cloud-starter-oauth2
+
+
+ org.springframework.cloud
+ spring-cloud-starter-zuul
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.webjars
+ jquery
+
+
+ org.webjars
+ bootstrap
+
+
+ org.webjars
+ webjars-locator
+
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.webjars
+ js-cookie
+ 2.1.0
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/spring-cloud/spring-cloud-security/oauth2client/src/main/java/com/baeldung/CloudSite.java b/spring-cloud/spring-cloud-security/oauth2client/src/main/java/com/baeldung/CloudSite.java
new file mode 100644
index 0000000000..a072605ec0
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/oauth2client/src/main/java/com/baeldung/CloudSite.java
@@ -0,0 +1,22 @@
+package com.baeldung;
+
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+
+import com.baeldung.filters.SimpleFilter;
+
+
+@SpringBootApplication
+public class CloudSite {
+ public static void main(String[] args) {
+ SpringApplication.run(CloudSite.class, args);
+ }
+
+ @Bean
+ public SimpleFilter simpleFilter() {
+ return new SimpleFilter();
+ }
+
+}
diff --git a/spring-cloud/spring-cloud-security/oauth2client/src/main/java/com/baeldung/config/SiteSecurityConfigurer.java b/spring-cloud/spring-cloud-security/oauth2client/src/main/java/com/baeldung/config/SiteSecurityConfigurer.java
new file mode 100644
index 0000000000..217edb22fb
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/oauth2client/src/main/java/com/baeldung/config/SiteSecurityConfigurer.java
@@ -0,0 +1,49 @@
+package com.baeldung.config;
+
+import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
+import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.oauth2.client.OAuth2ClientContext;
+import org.springframework.security.oauth2.client.OAuth2RestOperations;
+import org.springframework.security.oauth2.client.OAuth2RestTemplate;
+import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
+import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
+
+@EnableZuulProxy
+@Configuration
+@EnableOAuth2Sso
+public class SiteSecurityConfigurer
+ extends
+ WebSecurityConfigurerAdapter {
+
+ @Override
+ protected void configure(HttpSecurity http)
+ throws Exception {
+ http.antMatcher("/**")
+ .authorizeRequests()
+ .antMatchers("/", "/webjars/**")
+ .permitAll()
+ .anyRequest()
+ .authenticated()
+ .and()
+ .logout()
+ .logoutSuccessUrl("/")
+ .permitAll()
+ .and()
+ .csrf()
+ .csrfTokenRepository(
+ CookieCsrfTokenRepository
+ .withHttpOnlyFalse());
+ }
+
+ @Bean
+ public OAuth2RestOperations restOperations(
+ OAuth2ProtectedResourceDetails resource,
+ OAuth2ClientContext context) {
+ return new OAuth2RestTemplate(resource, context);
+ }
+
+}
diff --git a/spring-cloud/spring-cloud-security/oauth2client/src/main/java/com/baeldung/controller/CloudSiteController.java b/spring-cloud/spring-cloud-security/oauth2client/src/main/java/com/baeldung/controller/CloudSiteController.java
new file mode 100644
index 0000000000..b6bfd0bcf6
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/oauth2client/src/main/java/com/baeldung/controller/CloudSiteController.java
@@ -0,0 +1,30 @@
+package com.baeldung.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.RestOperations;
+import org.springframework.web.servlet.ModelAndView;
+
+@RestController
+public class CloudSiteController {
+
+ @Autowired
+ private RestOperations restOperations;
+
+ @GetMapping("/")
+ @ResponseBody
+ public String helloFromBaeldung() {
+ return "Hello From Baeldung!";
+ }
+
+ @GetMapping("/person")
+ public ModelAndView person() {
+ ModelAndView mav = new ModelAndView("personinfo");
+ String personResourceUrl = "http://localhost:9000/personResource";
+ mav.addObject("person", restOperations.getForObject(personResourceUrl, String.class));
+ return mav;
+ }
+
+}
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-security/oauth2client/src/main/java/com/baeldung/filters/SimpleFilter.java b/spring-cloud/spring-cloud-security/oauth2client/src/main/java/com/baeldung/filters/SimpleFilter.java
new file mode 100644
index 0000000000..98e25ac9c4
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/oauth2client/src/main/java/com/baeldung/filters/SimpleFilter.java
@@ -0,0 +1,39 @@
+package com.baeldung.filters;
+
+import javax.servlet.http.HttpServletRequest;
+import com.netflix.zuul.context.RequestContext;
+import com.netflix.zuul.ZuulFilter;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SimpleFilter extends ZuulFilter {
+
+ private static Logger log = LoggerFactory.getLogger(SimpleFilter.class);
+
+ @Override
+ public String filterType() {
+ return "pre";
+ }
+
+ @Override
+ public int filterOrder() {
+ return 1;
+ }
+
+ @Override
+ public boolean shouldFilter() {
+ return true;
+ }
+
+ @Override
+ public Object run() {
+ RequestContext ctx = RequestContext.getCurrentContext();
+ HttpServletRequest request = ctx.getRequest();
+
+ log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
+
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-security/oauth2client/src/main/resources/application.properties b/spring-cloud/spring-cloud-security/oauth2client/src/main/resources/application.properties
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/spring-cloud/spring-cloud-security/oauth2client/src/main/resources/application.yml b/spring-cloud/spring-cloud-security/oauth2client/src/main/resources/application.yml
new file mode 100644
index 0000000000..06a950d270
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/oauth2client/src/main/resources/application.yml
@@ -0,0 +1,37 @@
+# Make the application available at http://localhost:8080
+# These are default settings, but we add them for clarity.
+server:
+ port: 8080
+ contextPath: /
+
+# Configure the Authorization Server and User Info Resource Server details
+security:
+ oauth2:
+ client:
+ accessTokenUri: http://localhost:7070/authserver/oauth/token
+ userAuthorizationUri: http://localhost:7070/authserver/oauth/authorize
+ clientId: authserver
+ clientSecret: passwordforauthserver
+ resource:
+ userInfoUri: http://localhost:7070/authserver/user
+
+person:
+ url: http://localhost:9000/person
+
+# Proxies the calls to http://localhost:8080/api/* to our REST service at http://localhost:8081/*
+# and automatically includes our OAuth2 token in the request headers
+zuul:
+ routes:
+ resource:
+ path: /api/**
+ url: http://localhost:9000
+ user:
+ path: /user/**
+ url: http://localhost:7070/authserver/user
+
+# Make sure the OAuth2 token is only relayed when using the internal API,
+# do not pass any authentication to the external API
+proxy:
+ auth:
+ routes:
+ api: oauth2
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-security/oauth2client/src/main/resources/templates/personinfo.html b/spring-cloud/spring-cloud-security/oauth2client/src/main/resources/templates/personinfo.html
new file mode 100644
index 0000000000..bc3197e93a
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/oauth2client/src/main/resources/templates/personinfo.html
@@ -0,0 +1,13 @@
+
+
+
+
+Getting Personal Information
+
+
+ Providing Person Information
+
+ Person's information:
+
+
+
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-security/oauth2client/src/test/java/com/example/springoath2/Springoath2ApplicationTests.java b/spring-cloud/spring-cloud-security/oauth2client/src/test/java/com/example/springoath2/Springoath2ApplicationTests.java
new file mode 100644
index 0000000000..5fa51a61c3
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/oauth2client/src/test/java/com/example/springoath2/Springoath2ApplicationTests.java
@@ -0,0 +1,16 @@
+package com.example.springoath2;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class Springoath2ApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/spring-cloud/spring-cloud-security/personresource/pom.xml b/spring-cloud/spring-cloud-security/personresource/pom.xml
new file mode 100644
index 0000000000..783fd41e66
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/personresource/pom.xml
@@ -0,0 +1,74 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ personresource
+ 0.0.1-SNAPSHOT
+ jar
+
+ personresource
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.5.9.RELEASE
+
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ Edgware.RELEASE
+
+
+
+
+ org.springframework.security.oauth
+ spring-security-oauth2
+
+
+ org.springframework.cloud
+ spring-cloud-starter-security
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.security
+ spring-security-jwt
+
+
+ com.google.code.gson
+ gson
+
+
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
+ pom
+ import
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/Application.java b/spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/Application.java
new file mode 100644
index 0000000000..8c087476bf
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/Application.java
@@ -0,0 +1,12 @@
+package com.baeldung;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+}
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/config/ResourceConfigurer.java b/spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/config/ResourceConfigurer.java
new file mode 100644
index 0000000000..977d74093a
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/config/ResourceConfigurer.java
@@ -0,0 +1,25 @@
+package com.baeldung.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
+
+/**
+ * REST API Resource Server.
+ */
+@Configuration
+@EnableWebSecurity
+@EnableResourceServer
+@EnableGlobalMethodSecurity(prePostEnabled = true) // Allow method annotations like @PreAuthorize
+public class ResourceConfigurer extends ResourceServerConfigurerAdapter {
+
+ @Override
+ public void configure(HttpSecurity http) throws Exception {
+ http.httpBasic().disable();
+ http.authorizeRequests().anyRequest().authenticated();
+ }
+
+}
diff --git a/spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/controller/PersonInfoController.java b/spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/controller/PersonInfoController.java
new file mode 100644
index 0000000000..15ffc557fc
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/controller/PersonInfoController.java
@@ -0,0 +1,21 @@
+package com.baeldung.controller;
+
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.baeldung.model.Person;
+import com.google.gson.Gson;
+
+@RestController
+public class PersonInfoController {
+
+ @GetMapping("/personResource")
+ @PreAuthorize("hasAnyRole('ADMIN', 'USER')")
+ public @ResponseBody String personInfo() {
+ Gson gson = new Gson();
+ String person = gson.toJson(new Person("abir", "Dhaka", "Bangladesh", 29, "Male"));
+ return person;
+ }
+}
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/model/Person.java b/spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/model/Person.java
new file mode 100644
index 0000000000..b568291da3
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/model/Person.java
@@ -0,0 +1,59 @@
+package com.baeldung.model;
+
+public class Person {
+
+ private String name;
+ private String city;
+ private String country;
+ private Integer age;
+ private String sex;
+
+ public Person(String name, String city, String country, Integer age, String sex) {
+ this.name = name;
+ this.city = city;
+ this.country = country;
+ this.age = age;
+ this.sex = sex;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public String getCountry() {
+ return country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+
+ public Integer getAge() {
+ return age;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+
+ public String getSex() {
+ return sex;
+ }
+
+ public void setSex(String sex) {
+ this.sex = sex;
+ }
+
+}
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-security/personresource/src/main/resources/application.yml b/spring-cloud/spring-cloud-security/personresource/src/main/resources/application.yml
new file mode 100644
index 0000000000..20a3313a60
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/personresource/src/main/resources/application.yml
@@ -0,0 +1,22 @@
+# Make the application available at http://localhost:9000
+
+server:
+ port: 9000
+
+# Configure the public key to use for verifying the incoming JWT tokens
+security:
+ sessions: NEVER
+ oauth2:
+ resource:
+ userInfoUri: http://localhost:7070/authserver/user
+ jwt:
+ keyValue: |
+ -----BEGIN PUBLIC KEY-----
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhiiifKv6Otf5PyqIE+LQ
+ EiJRRh6q8piPY9Okq+RfRu9Bue0D8hq7aFxcgkLZ6Bg9CAS+w1KdaE5MMeOCVVxv
+ rpRETzVpAsh6GL5nBc679jSqMzjr3V4uty46ilL4VHKSxlZh5Nmz5EMHPI5iwpNs
+ 8U5n3QiwsTk514FXad54xPSPH3i/pDzGSZHrVcwDVaOKn7gFiIqP86vkJB47JZv8
+ T6P5RK7Rj06zoG45DMGWG3DQv6o1/Jm4IJQWj0AUD3bSHqzXkPr7qyMYvkE4kyMH
+ 6aVAsAYMxilZFlJMv2b8N883gdi3LEeOJo8zZr5IWyyROfepdeOL7UkAXddAj+dL
+ WQIDAQAB
+ -----END PUBLIC KEY-----
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-security/personresource/src/test/java/com/baeldung/service/personservice/PersonserviceApplicationTests.java b/spring-cloud/spring-cloud-security/personresource/src/test/java/com/baeldung/service/personservice/PersonserviceApplicationTests.java
new file mode 100644
index 0000000000..e0fe7006d9
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/personresource/src/test/java/com/baeldung/service/personservice/PersonserviceApplicationTests.java
@@ -0,0 +1,16 @@
+package com.baeldung.service.personservice;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class PersonserviceApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/spring-cloud/spring-cloud-security/pubkey.txt b/spring-cloud/spring-cloud-security/pubkey.txt
new file mode 100644
index 0000000000..2c391ba2dd
--- /dev/null
+++ b/spring-cloud/spring-cloud-security/pubkey.txt
@@ -0,0 +1,30 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhiiifKv6Otf5PyqIE+LQ
+EiJRRh6q8piPY9Okq+RfRu9Bue0D8hq7aFxcgkLZ6Bg9CAS+w1KdaE5MMeOCVVxv
+rpRETzVpAsh6GL5nBc679jSqMzjr3V4uty46ilL4VHKSxlZh5Nmz5EMHPI5iwpNs
+8U5n3QiwsTk514FXad54xPSPH3i/pDzGSZHrVcwDVaOKn7gFiIqP86vkJB47JZv8
+T6P5RK7Rj06zoG45DMGWG3DQv6o1/Jm4IJQWj0AUD3bSHqzXkPr7qyMYvkE4kyMH
+6aVAsAYMxilZFlJMv2b8N883gdi3LEeOJo8zZr5IWyyROfepdeOL7UkAXddAj+dL
+WQIDAQAB
+-----END PUBLIC KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDfzCCAmegAwIBAgIEDqsC7jANBgkqhkiG9w0BAQsFADBwMQswCQYDVQQGEwI4
+ODETMBEGA1UECBMKQmFuZ2xhZGVzaDEOMAwGA1UEBxMFRGhha2ExETAPBgNVBAoT
+CEJhZWxkdW5nMRUwEwYDVQQLEwxCYWVsZHVuZ2Jsb2cxEjAQBgNVBAMTCWxvY2Fs
+aG9zdDAeFw0xNzEyMjUxNDE0MDhaFw0xODAzMjUxNDE0MDhaMHAxCzAJBgNVBAYT
+Ajg4MRMwEQYDVQQIEwpCYW5nbGFkZXNoMQ4wDAYDVQQHEwVEaGFrYTERMA8GA1UE
+ChMIQmFlbGR1bmcxFTATBgNVBAsTDEJhZWxkdW5nYmxvZzESMBAGA1UEAxMJbG9j
+YWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhiiifKv6Otf5
+PyqIE+LQEiJRRh6q8piPY9Okq+RfRu9Bue0D8hq7aFxcgkLZ6Bg9CAS+w1KdaE5M
+MeOCVVxvrpRETzVpAsh6GL5nBc679jSqMzjr3V4uty46ilL4VHKSxlZh5Nmz5EMH
+PI5iwpNs8U5n3QiwsTk514FXad54xPSPH3i/pDzGSZHrVcwDVaOKn7gFiIqP86vk
+JB47JZv8T6P5RK7Rj06zoG45DMGWG3DQv6o1/Jm4IJQWj0AUD3bSHqzXkPr7qyMY
+vkE4kyMH6aVAsAYMxilZFlJMv2b8N883gdi3LEeOJo8zZr5IWyyROfepdeOL7UkA
+XddAj+dLWQIDAQABoyEwHzAdBgNVHQ4EFgQUHLFYkq36Wami5qsVRe/1eQedmdgw
+DQYJKoZIhvcNAQELBQADggEBABL3lYyuRd6Hv8DPus/zQL0bRl6gVsEzczwmWMUA
+3NJZbUHAD/KC732aArvKIKykkbLG6K/Mhnfuu8YBfWzTvGgY3Ww+ka2sJFOsUW7r
+sa6OBtNHh4zhDYN2Weza+4jnRLxtkzFbm6v2sheFkyB1NywCwFE/6p1Z6KTG8RyJ
+gw/OHl6rb+Y/T6cOeeTCFUN/v+qRVSB9I/MjSK5wRNbFT+MyNUeL6gsiyIvxSZbj
+y4vrjGHkXasSmwkfvgw67mJMk4XTGrVLjIXUTyzbdSmodcv8N6nrsIk4SBYCnTrI
+E/5NtNgbOFGwovde5yNrZIjjAC1VGOmVFhcxFJpwT6ZkSks=
+-----END CERTIFICATE-----
diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/src/main/java/com/baeldung/spring/cloud/eureka/client/EurekaClientApplication.java b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/src/main/java/com/baeldung/spring/cloud/eureka/client/EurekaClientApplication.java
index 906d6e4cfd..9bbb121408 100644
--- a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/src/main/java/com/baeldung/spring/cloud/eureka/client/EurekaClientApplication.java
+++ b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/src/main/java/com/baeldung/spring/cloud/eureka/client/EurekaClientApplication.java
@@ -21,12 +21,17 @@ public class EurekaClientApplication implements GreetingController {
@Value("${spring.application.name}")
private String appName;
+ @Value("${server.port}")
+ private String portNumber;
+
public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class, args);
}
@Override
public String greeting() {
- return String.format("Hello from '%s'!", eurekaClient.getApplication(appName).getName());
+ System.out.println("Request received on port number " + portNumber);
+ return String.format("Hello from '%s with Port Number %s'!", eurekaClient.getApplication(appName)
+ .getName(), portNumber);
}
}
diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/src/main/resources/application.yml b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/src/main/resources/application.yml
index 08624aa159..9fa929e16b 100644
--- a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/src/main/resources/application.yml
+++ b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/src/main/resources/application.yml
@@ -3,7 +3,7 @@ spring:
name: spring-cloud-eureka-client
server:
- port: 0
+ port: 8081
eureka:
client:
diff --git a/spring-data-elasticsearch/pom.xml b/spring-data-elasticsearch/pom.xml
index 520707a432..688506450f 100644
--- a/spring-data-elasticsearch/pom.xml
+++ b/spring-data-elasticsearch/pom.xml
@@ -45,6 +45,24 @@
${spring-data-elasticsearch.version}
+
+ com.spatial4j
+ spatial4j
+ 0.4.1
+
+
+
+ com.vividsolutions
+ jts
+ 1.13
+
+
+ xerces
+ xercesImpl
+
+
+
+
org.springframework
spring-test
diff --git a/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/GeoQueriesTest.java b/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/GeoQueriesTest.java
new file mode 100644
index 0000000000..19514ce4c2
--- /dev/null
+++ b/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/GeoQueriesTest.java
@@ -0,0 +1,179 @@
+package com.baeldung.elasticsearch;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
+import org.elasticsearch.action.index.IndexResponse;
+import org.elasticsearch.action.search.SearchResponse;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.geo.ShapeRelation;
+import org.elasticsearch.common.geo.builders.ShapeBuilder;
+import org.elasticsearch.common.unit.DistanceUnit;
+import org.elasticsearch.index.query.QueryBuilder;
+import org.elasticsearch.index.query.QueryBuilders;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.baeldung.spring.data.es.config.Config;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = Config.class)
+public class GeoQueriesTest {
+
+ public static final String WONDERS_OF_WORLD = "wonders-of-world";
+ public static final String WONDERS = "Wonders";
+ @Autowired
+ private ElasticsearchTemplate elasticsearchTemplate;
+
+ @Autowired
+ private Client client;
+
+ @Before
+ public void setUp() {
+ String jsonObject = "{\"Wonders\":{\"properties\":{\"name\":{\"type\":\"string\",\"index\":\"not_analyzed\"},\"region\":{\"type\":\"geo_shape\",\"tree\":\"quadtree\",\"precision\":\"1m\"},\"location\":{\"type\":\"geo_point\"}}}}";
+ CreateIndexRequest req = new CreateIndexRequest(WONDERS_OF_WORLD);
+ req.mapping(WONDERS, jsonObject);
+ client.admin()
+ .indices()
+ .create(req)
+ .actionGet();
+ }
+
+ @Test
+ public void givenGeoShapeData_whenExecutedGeoShapeQuery_thenResultNonEmpty() {
+ String jsonObject = "{\"name\":\"Agra\",\"region\":{\"type\":\"envelope\",\"coordinates\":[[75,25],[80.1,30.2]]}}";
+ IndexResponse response = client.prepareIndex(WONDERS_OF_WORLD, WONDERS)
+ .setSource(jsonObject)
+ .get();
+ String tajMahalId = response.getId();
+ client.admin()
+ .indices()
+ .prepareRefresh(WONDERS_OF_WORLD)
+ .get();
+
+ QueryBuilder qb = QueryBuilders.geoShapeQuery("region", ShapeBuilder.newEnvelope()
+ .topLeft(74.00, 24.0)
+ .bottomRight(81.1, 31.2))
+ .relation(ShapeRelation.WITHIN);
+
+ SearchResponse searchResponse = client.prepareSearch(WONDERS_OF_WORLD)
+ .setTypes(WONDERS)
+ .setQuery(qb)
+ .execute()
+ .actionGet();
+ List ids = Arrays.stream(searchResponse.getHits()
+ .getHits())
+ .map(hit -> {
+ return hit.getId();
+ })
+ .collect(Collectors.toList());
+ assertTrue(ids.contains(tajMahalId));
+ }
+
+ @Test
+ public void givenGeoPointData_whenExecutedGeoBoundingBoxQuery_thenResultNonEmpty() {
+ String jsonObject = "{\"name\":\"Pyramids of Giza\",\"location\":[31.131302,29.976480]}";
+ IndexResponse response = client.prepareIndex(WONDERS_OF_WORLD, WONDERS)
+ .setSource(jsonObject)
+ .get();
+ String pyramidsOfGizaId = response.getId();
+ client.admin()
+ .indices()
+ .prepareRefresh(WONDERS_OF_WORLD)
+ .get();
+
+ QueryBuilder qb = QueryBuilders.geoBoundingBoxQuery("location")
+ .bottomLeft(28, 30)
+ .topRight(31, 32);
+
+ SearchResponse searchResponse = client.prepareSearch(WONDERS_OF_WORLD)
+ .setTypes(WONDERS)
+ .setQuery(qb)
+ .execute()
+ .actionGet();
+ List ids = Arrays.stream(searchResponse.getHits()
+ .getHits())
+ .map(hit -> {
+ return hit.getId();
+ })
+ .collect(Collectors.toList());
+ assertTrue(ids.contains(pyramidsOfGizaId));
+ }
+
+ @Test
+ public void givenGeoPointData_whenExecutedGeoDistanceQuery_thenResultNonEmpty() {
+ String jsonObject = "{\"name\":\"Lighthouse of alexandria\",\"location\":[31.131302,29.976480]}";
+ IndexResponse response = client.prepareIndex(WONDERS_OF_WORLD, WONDERS)
+ .setSource(jsonObject)
+ .get();
+ String lighthouseOfAlexandriaId = response.getId();
+ client.admin()
+ .indices()
+ .prepareRefresh(WONDERS_OF_WORLD)
+ .get();
+
+ QueryBuilder qb = QueryBuilders.geoDistanceQuery("location")
+ .point(29.976, 31.131)
+ .distance(10, DistanceUnit.MILES);
+
+ SearchResponse searchResponse = client.prepareSearch(WONDERS_OF_WORLD)
+ .setTypes(WONDERS)
+ .setQuery(qb)
+ .execute()
+ .actionGet();
+ List ids = Arrays.stream(searchResponse.getHits()
+ .getHits())
+ .map(hit -> {
+ return hit.getId();
+ })
+ .collect(Collectors.toList());
+ assertTrue(ids.contains(lighthouseOfAlexandriaId));
+ }
+
+ @Test
+ public void givenGeoPointData_whenExecutedGeoPolygonQuery_thenResultNonEmpty() {
+ String jsonObject = "{\"name\":\"The Great Rann of Kutch\",\"location\":[69.859741,23.733732]}";
+ IndexResponse response = client.prepareIndex(WONDERS_OF_WORLD, WONDERS)
+ .setSource(jsonObject)
+ .get();
+ String greatRannOfKutchid = response.getId();
+ client.admin()
+ .indices()
+ .prepareRefresh(WONDERS_OF_WORLD)
+ .get();
+
+ QueryBuilder qb = QueryBuilders.geoPolygonQuery("location")
+ .addPoint(22.733, 68.859)
+ .addPoint(24.733, 68.859)
+ .addPoint(23, 70.859);
+
+ SearchResponse searchResponse = client.prepareSearch(WONDERS_OF_WORLD)
+ .setTypes(WONDERS)
+ .setQuery(qb)
+ .execute()
+ .actionGet();
+ List ids = Arrays.stream(searchResponse.getHits()
+ .getHits())
+ .map(hit -> {
+ return hit.getId();
+ })
+ .collect(Collectors.toList());
+ assertTrue(ids.contains(greatRannOfKutchid));
+ }
+
+ @After
+ public void destroy() {
+ elasticsearchTemplate.deleteIndex(WONDERS_OF_WORLD);
+ }
+
+}
diff --git a/spring-ejb/README.md b/spring-ejb/README.md
new file mode 100644
index 0000000000..8fa8833f3a
--- /dev/null
+++ b/spring-ejb/README.md
@@ -0,0 +1,3 @@
+### Relevant Articles
+
+- [Integration Guide for Spring and EJB](http://www.baeldung.com/spring-ejb)
diff --git a/spring-mvc-xml/src/main/resources/contentManagementWebMvcConfig.xml b/spring-mvc-xml/src/main/resources/contentManagementWebMvcConfig.xml
index 41422d8954..75d5c1ecd6 100644
--- a/spring-mvc-xml/src/main/resources/contentManagementWebMvcConfig.xml
+++ b/spring-mvc-xml/src/main/resources/contentManagementWebMvcConfig.xml
@@ -4,11 +4,11 @@
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
+ http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-4.2.xsd
+ http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/mvc
- http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd">
+ http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
diff --git a/spring-mvc-xml/src/main/resources/webMvcConfig.xml b/spring-mvc-xml/src/main/resources/webMvcConfig.xml
index c471adf331..37aebe1d1d 100644
--- a/spring-mvc-xml/src/main/resources/webMvcConfig.xml
+++ b/spring-mvc-xml/src/main/resources/webMvcConfig.xml
@@ -3,11 +3,11 @@
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
+ http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-4.2.xsd
+ http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/mvc
- http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd"
+ http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd"
>
diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/mvc-servlet.xml b/spring-mvc-xml/src/main/webapp/WEB-INF/mvc-servlet.xml
index 47e2769902..032457da43 100644
--- a/spring-mvc-xml/src/main/webapp/WEB-INF/mvc-servlet.xml
+++ b/spring-mvc-xml/src/main/webapp/WEB-INF/mvc-servlet.xml
@@ -2,9 +2,9 @@
+ http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
@@ -58,4 +58,4 @@
-
\ No newline at end of file
+
diff --git a/spring-rest-simple/README.md b/spring-rest-simple/README.md
index 916676feb5..982e16d5a5 100644
--- a/spring-rest-simple/README.md
+++ b/spring-rest-simple/README.md
@@ -5,3 +5,4 @@
- [The Guide to RestTemplate](http://www.baeldung.com/rest-template)
- [Spring RequestMapping](http://www.baeldung.com/spring-requestmapping)
- [ETags for REST with Spring](http://www.baeldung.com/etags-for-rest-with-spring)
+- [Spring and Apache FileUpload](http://www.baeldung.com/spring-apache-file-upload)
diff --git a/spring-security-mvc-custom/src/main/java/org/baeldung/web/controller/LoginController.java b/spring-security-mvc-custom/src/main/java/org/baeldung/web/controller/LoginController.java
new file mode 100644
index 0000000000..c67a6f667e
--- /dev/null
+++ b/spring-security-mvc-custom/src/main/java/org/baeldung/web/controller/LoginController.java
@@ -0,0 +1,43 @@
+package org.baeldung.web.controller;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@Controller
+@RequestMapping(value = "/custom")
+public class LoginController {
+
+ @Autowired
+ private AuthenticationManager authManager;
+
+ public LoginController() {
+ super();
+ }
+
+ // API
+
+ // custom login
+
+ @RequestMapping(value = "/login", method = RequestMethod.POST)
+ public void login(@RequestParam("username") final String username, @RequestParam("password") final String password, final HttpServletRequest request) {
+ UsernamePasswordAuthenticationToken authReq =
+ new UsernamePasswordAuthenticationToken(username, password);
+ Authentication auth = authManager.authenticate(authReq);
+ SecurityContext sc = SecurityContextHolder.getContext();
+ sc.setAuthentication(auth);
+ HttpSession session = request.getSession(true);
+ session.setAttribute("SPRING_SECURITY_CONTEXT", sc);
+ }
+
+}
\ No newline at end of file
diff --git a/spring-security-mvc-custom/src/main/java/org/baeldung/web/controller/PrintUserController.java b/spring-security-mvc-custom/src/main/java/org/baeldung/web/controller/PrintUserController.java
new file mode 100644
index 0000000000..78f164c7f1
--- /dev/null
+++ b/spring-security-mvc-custom/src/main/java/org/baeldung/web/controller/PrintUserController.java
@@ -0,0 +1,27 @@
+package org.baeldung.web.controller;
+
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+@Controller
+@RequestMapping(value = "/custom")
+public class PrintUserController {
+
+ public PrintUserController() {
+ super();
+ }
+
+ // API
+
+ // print user
+
+ @RequestMapping(value = "/print", method = RequestMethod.GET)
+ public void printUser() {
+ SecurityContext sc = SecurityContextHolder.getContext();
+ System.out.println("Logged User: "+sc.getAuthentication().getName());
+ }
+
+}
\ No newline at end of file
diff --git a/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/ManualSecurityConfig.java b/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/ManualSecurityConfig.java
new file mode 100644
index 0000000000..874856095c
--- /dev/null
+++ b/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/ManualSecurityConfig.java
@@ -0,0 +1,58 @@
+package org.baeldung.security.spring;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.BeanIds;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+@Configuration
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+public class ManualSecurityConfig extends WebSecurityConfigurerAdapter {
+
+ public ManualSecurityConfig() {
+ super();
+ }
+
+ // java config
+
+ @Override
+ protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
+ auth.inMemoryAuthentication().withUser("user1").password("user1Pass").authorities("ROLE_USER").and().withUser("admin").password("adminPass").authorities("ROLE_ADMIN");
+ }
+
+ @Override
+ public void configure(final WebSecurity web) throws Exception {
+ web.ignoring().antMatchers("/resources/**");
+ }
+
+ @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
+ @Override
+ public AuthenticationManager authenticationManagerBean() throws Exception {
+ return super.authenticationManagerBean();
+ }
+
+ @Override
+ protected void configure(final HttpSecurity http) throws Exception {
+ // @formatter:off
+ http
+ .authorizeRequests()
+ .mvcMatchers("/custom/login").permitAll()
+ .anyRequest().authenticated()
+ .and()
+ .httpBasic()
+ .and()
+ .headers().cacheControl().disable()
+ .and()
+ .csrf().disable()
+ ;
+ // @formatter:on
+ }
+
+}
diff --git a/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/ManualSecurityIntegrationTest.java b/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/ManualSecurityIntegrationTest.java
new file mode 100644
index 0000000000..afc86bd74c
--- /dev/null
+++ b/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/ManualSecurityIntegrationTest.java
@@ -0,0 +1,58 @@
+package org.baeldung.security.spring;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import javax.servlet.http.HttpSession;
+
+import org.baeldung.spring.MvcConfig;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mock.web.MockHttpSession;
+import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@WebAppConfiguration
+@ContextConfiguration(classes = { MvcConfig.class, ManualSecurityConfig.class })
+public class ManualSecurityIntegrationTest {
+
+ @Autowired
+ WebApplicationContext wac;
+
+ private MockMvc mockMvc;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mockMvc = MockMvcBuilders.webAppContextSetup(wac).apply(SecurityMockMvcConfigurers.springSecurity()).build();
+ }
+
+ /**
+ * Execute custom login and access the endpoint
+ */
+ @Test
+ public void whenLoginIsSuccessFulThenEndpointCanBeAccessedAndCurrentUserPrinted() throws Exception {
+
+ mockMvc.perform(get("/custom/print"))
+ .andExpect(status().isUnauthorized());
+
+ HttpSession session = mockMvc.perform(post("/custom/login").param("username", "user1").param("password", "user1Pass"))
+ .andExpect(status().isOk())
+ .andReturn()
+ .getRequest()
+ .getSession();
+
+ mockMvc.perform(get("/custom/print").session((MockHttpSession) session))
+ .andExpect(status().is2xxSuccessful());
+ }
+
+}
diff --git a/spring-security-openid/pom.xml b/spring-security-openid/pom.xml
index 2149334a5c..4c8112a163 100644
--- a/spring-security-openid/pom.xml
+++ b/spring-security-openid/pom.xml
@@ -11,12 +11,12 @@
spring-security-openid
Spring OpenID sample project
-
- parent-boot-5
- com.baeldung
- 0.0.1-SNAPSHOT
- ../parent-boot-5
-
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.0.0.M7
+
+
@@ -37,13 +37,36 @@
org.springframework.security.oauth
spring-security-oauth2
+ 2.2.1.RELEASE
org.springframework.security
spring-security-jwt
+ 1.0.9.RELEASE
-
+
+
+
+ spring-milestones
+ Spring Milestones
+ https://repo.spring.io/milestone
+
+ false
+
+
+
+
+
+ spring-milestones
+ Spring Milestones
+ https://repo.spring.io/milestone
+
+ false
+
+
+
+
diff --git a/spring-security-openid/src/main/java/org/baeldung/config/SpringOpenidApplication.java b/spring-security-openid/src/main/java/org/baeldung/config/SpringOpenidApplication.java
index ed57088c56..1acdba0623 100644
--- a/spring-security-openid/src/main/java/org/baeldung/config/SpringOpenidApplication.java
+++ b/spring-security-openid/src/main/java/org/baeldung/config/SpringOpenidApplication.java
@@ -2,7 +2,7 @@ package org.baeldung.config;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.web.support.SpringBootServletInitializer;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class SpringOpenidApplication extends SpringBootServletInitializer {
diff --git a/testing-modules/README.md b/testing-modules/README.md
index 3fbeea6188..ccf63a9815 100644
--- a/testing-modules/README.md
+++ b/testing-modules/README.md
@@ -1,3 +1,6 @@
## Testing Modules
+### Relevant Articles:
+
+- [Quick Guide to BDDMockito](http://www.baeldung.com/bdd-mockito)