Merge branch 'master' of https://github.com/eugenp/tutorials into BAEL-4461-3

This commit is contained in:
amit2103 2018-07-18 23:49:59 +05:30
commit f033506f08
21 changed files with 1478 additions and 1044 deletions

View File

@ -1,116 +1,118 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<!-- POM file generated with GWT webAppCreator -->
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>google_web_toolkit</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>com.baeldung.Google_web_toolkit</name>
<!-- POM file generated with GWT webAppCreator -->
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>google-web-toolkit</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<properties>
<dependencyManagement>
<dependencies>
<!-- ensure all GWT deps use the same version (unless overridden) -->
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt</artifactId>
<version>2.8.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- Setting maven.compiler.source to something different to 1.8
needs that you configure the sourceLevel in gwt-maven-plugin since
GWT compiler 2.8 requires 1.8 (see gwt-maven-plugin block below) -->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<dependencies>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-servlet</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-dev</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- Don't let your Mac use a crazy non-standard encoding -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<build>
<!-- Output classes directly into the webapp, so that IDEs and "mvn process-classes"
update them in DevMode -->
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
<dependencyManagement>
<dependencies>
<!-- ensure all GWT deps use the same version (unless overridden) -->
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt</artifactId>
<version>2.8.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<plugins>
<dependencies>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-servlet</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-dev</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- GWT Maven Plugin -->
<plugin>
<groupId>net.ltgt.gwt.maven</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>1.0-rc-8</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test</goal>
</goals>
</execution>
</executions>
<configuration>
<moduleName>com.baeldung.Google_web_toolkit</moduleName>
<moduleShortName>Google_web_toolkit</moduleShortName>
<failOnError>true</failOnError>
<!-- GWT compiler 2.8 requires 1.8, hence define sourceLevel here if
you use a different source language for java compilation -->
<sourceLevel>1.8</sourceLevel>
<!-- Compiler configuration -->
<compilerArgs>
<!-- Ask GWT to create the Story of Your Compile (SOYC) (gwt:compile) -->
<arg>-compileReport</arg>
<arg>-XcompilerMetrics</arg>
</compilerArgs>
<!-- DevMode configuration -->
<warDir>${project.build.directory}/${project.build.finalName}</warDir>
<classpathScope>compile+runtime</classpathScope>
<!-- URL(s) that should be opened by DevMode (gwt:devmode). -->
<startupUrls>
<startupUrl>Google_web_toolkit.html</startupUrl>
</startupUrls>
</configuration>
</plugin>
<build>
<!-- Output classes directly into the webapp, so that IDEs and "mvn process-classes" update them in DevMode -->
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
<!-- Skip normal test execution, we use gwt:test instead -->
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugins>
</plugins>
</build>
<properties>
<!-- GWT Maven Plugin-->
<plugin>
<groupId>net.ltgt.gwt.maven</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>1.0-rc-8</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test</goal>
</goals>
</execution>
</executions>
<configuration>
<moduleName>com.baeldung.Google_web_toolkit</moduleName>
<moduleShortName>Google_web_toolkit</moduleShortName>
<failOnError>true</failOnError>
<!-- GWT compiler 2.8 requires 1.8, hence define sourceLevel here if you use
a different source language for java compilation -->
<sourceLevel>1.8</sourceLevel>
<!-- Compiler configuration -->
<compilerArgs>
<!-- Ask GWT to create the Story of Your Compile (SOYC) (gwt:compile) -->
<arg>-compileReport</arg>
<arg>-XcompilerMetrics</arg>
</compilerArgs>
<!-- DevMode configuration -->
<warDir>${project.build.directory}/${project.build.finalName}</warDir>
<classpathScope>compile+runtime</classpathScope>
<!-- URL(s) that should be opened by DevMode (gwt:devmode). -->
<startupUrls>
<startupUrl>Google_web_toolkit.html</startupUrl>
</startupUrls>
</configuration>
</plugin>
<!-- Setting maven.compiler.source to something different to 1.8 needs
that you configure the sourceLevel in gwt-maven-plugin since GWT compiler
2.8 requires 1.8 (see gwt-maven-plugin block below) -->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!-- Skip normal test execution, we use gwt:test instead -->
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
<!-- Don't let your Mac use a crazy non-standard encoding -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
</project>

1370
pom.xml

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +0,0 @@
package com.baeldung.springbootsecurity.form_login;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = "com.baeldung.springbootsecurity.form_login")
public class SpringBootSecurityApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootSecurityApplication.class, args);
}
}

View File

@ -1,67 +0,0 @@
package com.baeldung.springbootsecurity.form_login.configuration;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
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.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("baeldung")
.password("baeldung")
.roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin()
.failureHandler(customAuthenticationFailureHandler());
}
@Bean
public AuthenticationFailureHandler customAuthenticationFailureHandler() {
return new CustomAuthenticationFailureHandler();
}
/**
* Custom AuthenticationFailureHandler
*/
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {
private final ObjectMapper objectMapper = new ObjectMapper();
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
Map<String, Object> data = new HashMap<>();
data.put("timestamp", Calendar.getInstance().getTime());
data.put("exception", exception.getMessage());
response.getOutputStream().println(objectMapper.writeValueAsString(data));
}
}
}

View File

@ -1,87 +0,0 @@
package com.baeldung.springbootsecurity.form_login;
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.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import javax.servlet.Filter;
import static org.junit.Assert.assertTrue;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.unauthenticated;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = com.baeldung.springbootsecurity.form_login.SpringBootSecurityApplication.class)
public class FormLoginIntegrationTest {
@Autowired
private WebApplicationContext context;
@Autowired
private Filter springSecurityFilterChain;
private MockMvc mvc;
@Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.addFilters(springSecurityFilterChain)
.build();
}
@Test
public void givenRequestWithoutSessionOrCsrfToken_shouldFailWith403() throws Exception {
mvc
.perform(post("/"))
.andExpect(status().isForbidden());
}
@Test
public void givenRequestWithInvalidCsrfToken_shouldFailWith403() throws Exception {
mvc
.perform(post("/").with(csrf().useInvalidToken()))
.andExpect(status().isForbidden());
}
@Test
public void givenRequestWithValidCsrfTokenAndWithoutSessionToken_shouldReceive302WithLocationHeaderToLoginPage() throws Exception {
MvcResult mvcResult = mvc.perform(post("/").with(csrf())).andReturn();
assertTrue(mvcResult.getResponse().getStatus() == 302);
assertTrue(mvcResult.getResponse().getHeader("Location").contains("login"));
}
@Test
public void givenValidRequestWithValidCredentials_shouldLoginSuccessfully() throws Exception {
mvc
.perform(formLogin().user("baeldung").password("baeldung"))
.andExpect(status().isFound())
.andExpect(redirectedUrl("/"))
.andExpect(authenticated().withUsername("baeldung"));
}
@Test
public void givenValidRequestWithInvalidCredentials_shouldFailWith401() throws Exception {
MvcResult result = mvc
.perform(formLogin().user("random").password("random"))
.andExpect(status().isUnauthorized())
.andDo(print())
.andExpect(unauthenticated())
.andReturn();
assertTrue(result.getResponse().getContentAsString().contains("Bad credentials"));
}
}

View File

@ -1,87 +0,0 @@
package com.baeldung.springbootsecurity.form_login;
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.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import javax.servlet.Filter;
import static org.junit.Assert.assertTrue;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.unauthenticated;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = com.baeldung.springbootsecurity.form_login.SpringBootSecurityApplication.class)
public class FormLoginUnitTest {
@Autowired
private WebApplicationContext context;
@Autowired
private Filter springSecurityFilterChain;
private MockMvc mvc;
@Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.addFilters(springSecurityFilterChain)
.build();
}
@Test
public void givenRequestWithoutSessionOrCsrfToken_shouldFailWith403() throws Exception {
mvc
.perform(post("/"))
.andExpect(status().isForbidden());
}
@Test
public void givenRequestWithInvalidCsrfToken_shouldFailWith403() throws Exception {
mvc
.perform(post("/").with(csrf().useInvalidToken()))
.andExpect(status().isForbidden());
}
@Test
public void givenRequestWithValidCsrfTokenAndWithoutSessionToken_shouldReceive302WithLocationHeaderToLoginPage() throws Exception {
MvcResult mvcResult = mvc.perform(post("/").with(csrf())).andReturn();
assertTrue(mvcResult.getResponse().getStatus() == 302);
assertTrue(mvcResult.getResponse().getHeader("Location").contains("login"));
}
@Test
public void givenValidRequestWithValidCredentials_shouldLoginSuccessfully() throws Exception {
mvc
.perform(formLogin().user("baeldung").password("baeldung"))
.andExpect(status().isFound())
.andExpect(redirectedUrl("/"))
.andExpect(authenticated().withUsername("baeldung"));
}
@Test
public void givenValidRequestWithInvalidCredentials_shouldFailWith401() throws Exception {
MvcResult result = mvc
.perform(formLogin().user("random").password("random"))
.andExpect(status().isUnauthorized())
.andDo(print())
.andExpect(unauthenticated())
.andReturn();
assertTrue(result.getResponse().getContentAsString().contains("Bad credentials"));
}
}

View File

@ -6,7 +6,7 @@
<artifactId>spring-data-rest</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>intro-spring-data-rest</name>
<name>spring-data-rest</name>
<description>Intro to Spring Data REST</description>
<parent>

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>spring-rest-hal-browser</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-rest-hal-browser -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-hal-browser</artifactId>
<version>3.0.8.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.197</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,13 @@
package com.baeldung;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class);
}
}

View File

@ -0,0 +1,108 @@
package com.baeldung.config;
import com.baeldung.data.BookRepository;
import com.baeldung.model.Book;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.util.Random;
import java.util.stream.IntStream;
@Component
public class DBLoader implements ApplicationRunner {
private final BookRepository bookRepository;
@Autowired
DBLoader(BookRepository bookRepository){
this.bookRepository = bookRepository;
}
public void run(ApplicationArguments applicationArguments) throws Exception {
String[] templates = {
"Up and running with %s",
"%s Basics",
"%s for Beginners",
"%s for Neckbeards",
"Under the hood: %s",
"Discovering %s",
"A short guide to %s",
"%s with Baeldung"
};
String[] buzzWords = {
"Spring REST Data",
"Java 9",
"Scala",
"Groovy",
"Hibernate",
"Spring HATEOS",
"The HAL Browser",
"Spring webflux",
};
String[] authorFirstName = {
"John %s",
"Steve %s",
"Samantha %s",
"Gale %s",
"Tom %s"
};
String[] authorLastName = {
"Giles",
"Gill",
"Smith",
"Armstrong"
};
String[] blurbs = {
"It was getting dark when the %s %s" ,
"Scott was nearly there when he heard that a %s %s",
"Diana was a lovable Java coder until the %s %s",
"The gripping story of a small %s and the day it %s"
};
String[] blublMiddles = {
"distaster",
"dog",
"cat",
"turtle",
"hurricane"
};
String[] end = {
"hit the school",
"memorised pi to 100 decimal places!",
"became a world champion armwrestler",
"became a Java REST master!!"
};
Random random = new Random();
IntStream.range(0, 100)
.forEach(i -> {
String template = templates[i % templates.length];
String buzzword = buzzWords[i % buzzWords.length];
String blurbStart = blurbs[i % blurbs.length];
String middle = blublMiddles[i % blublMiddles.length];
String ending = end[i % end.length];
String blurb = String.format(blurbStart, middle, ending);
String firstName = authorFirstName[i % authorFirstName.length];
String lastname = authorLastName[i % authorLastName.length];
Book book = new Book(String.format(template, buzzword), String.format(firstName, lastname), blurb, random.nextInt(1000-200) + 200);
bookRepository.save(book);
System.out.println(book);
});
}
}

View File

@ -0,0 +1,23 @@
package com.baeldung.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener;
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter;
import org.springframework.validation.Validator;
@Configuration
public class RestConfig extends RepositoryRestConfigurerAdapter {
//access to global validator
@Autowired
@Lazy
private Validator validator;
@Override
public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) {
validatingListener.addValidator("beforeCreate", validator );
validatingListener.addValidator("beforeSave", validator);
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.data;
import com.baeldung.model.Book;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RestResource;
import org.springframework.stereotype.Repository;
@Repository
public interface BookRepository extends PagingAndSortingRepository<Book, Long> {
@RestResource(rel = "title-contains", path="title-contains")
Page<Book> findByTitleContaining(@Param("query") String query, Pageable page);
@RestResource(rel = "author-contains", path="author-contains", exported = false)
Page<Book> findByAuthorContaining(@Param("query") String query, Pageable page);
}

View File

@ -0,0 +1,86 @@
package com.baeldung.model;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@NotNull
@Column(columnDefinition = "VARCHAR", length = 100)
private String title;
@NotNull
@Column(columnDefinition = "VARCHAR", length = 100)
private String author;
@Column(columnDefinition = "VARCHAR", length = 1000)
private String blurb;
private int pages;
public Book() {
}
public Book(@NotNull String title, @NotNull String author, String blurb, int pages) {
this.title = title;
this.author = author;
this.blurb = blurb;
this.pages = pages;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getBlurb() {
return blurb;
}
public void setBlurb(String blurb) {
this.blurb = blurb;
}
public int getPages() {
return pages;
}
public void setPages(int pages) {
this.pages = pages;
}
@Override
public String toString() {
return "Book{" +
"id=" + id +
", title='" + title + '\'' +
", author='" + author + '\'' +
", blurb='" + blurb + '\'' +
", pages=" + pages +
'}';
}
}

View File

@ -0,0 +1,22 @@
package org.baeldung.security;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Calendar;
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
String jsonPayload = "{\"message\" : \"%s\", \"timestamp\" : \"%s\" }";
httpServletResponse.getOutputStream().println(String.format(jsonPayload, e.getMessage(), Calendar.getInstance().getTime()));
}
}

View File

@ -1,6 +1,7 @@
package org.baeldung.spring;
import org.baeldung.security.CustomAccessDeniedHandler;
import org.baeldung.security.CustomAuthenticationFailureHandler;
import org.baeldung.security.CustomLogoutSuccessHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -10,6 +11,7 @@ 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.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
@Configuration
@ -26,11 +28,11 @@ public class SecSecurityConfig extends WebSecurityConfigurerAdapter {
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth.inMemoryAuthentication()
.withUser("user1").password("user1Pass").roles("USER")
.and()
.withUser("user2").password("user2Pass").roles("USER")
.and()
.withUser("admin").password("adminPass").roles("ADMIN");
.withUser("user1").password("user1Pass").roles("USER")
.and()
.withUser("user2").password("user2Pass").roles("USER")
.and()
.withUser("admin").password("adminPass").roles("ADMIN");
// @formatter:on
}
@ -38,23 +40,24 @@ public class SecSecurityConfig extends WebSecurityConfigurerAdapter {
protected void configure(final HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/anonymous*").anonymous()
.antMatchers("/login*").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/perform_login")
.defaultSuccessUrl("/homepage.html",true)
.failureUrl("/login.html?error=true")
.and()
.logout()
.logoutUrl("/perform_logout")
.deleteCookies("JSESSIONID")
.logoutSuccessHandler(logoutSuccessHandler());
.csrf().disable()
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/anonymous*").anonymous()
.antMatchers("/login*").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/perform_login")
.defaultSuccessUrl("/homepage.html", true)
//.failureUrl("/login.html?error=true")
.failureHandler(authenticationFailureHandler())
.and()
.logout()
.logoutUrl("/perform_logout")
.deleteCookies("JSESSIONID")
.logoutSuccessHandler(logoutSuccessHandler());
//.and()
//.exceptionHandling().accessDeniedPage("/accessDenied");
//.exceptionHandling().accessDeniedHandler(accessDeniedHandler());
@ -71,4 +74,8 @@ public class SecSecurityConfig extends WebSecurityConfigurerAdapter {
return new CustomAccessDeniedHandler();
}
@Bean
public AuthenticationFailureHandler authenticationFailureHandler() {
return new CustomAuthenticationFailureHandler();
}
}

View File

@ -15,20 +15,22 @@
<csrf disabled="true"/>
<form-login login-page='/login.html' login-processing-url="/perform_login" default-target-url="/homepage.html" authentication-failure-url="/login.html?error=true"
always-use-default-target="true"/>
<form-login login-page='/login.html' login-processing-url="/perform_login" default-target-url="/homepage.html"
always-use-default-target="true" authentication-failure-handler-ref="authenticationFailureHandler"/>
<logout logout-url="/perform_logout" delete-cookies="JSESSIONID" success-handler-ref="customLogoutSuccessHandler"/>
<!-- <access-denied-handler error-page="/accessDenied"/> -->
<access-denied-handler ref="customAccessDeniedHandler"/>
</http>
<beans:bean name="customLogoutSuccessHandler" class="org.baeldung.security.CustomLogoutSuccessHandler"/>
<beans:bean name="customAccessDeniedHandler" class="org.baeldung.security.CustomAccessDeniedHandler" />
<beans:bean id="authenticationFailureHandler" name="customAuthenticationFaiureHandler" class="org.baeldung.security.CustomAuthenticationFailureHandler"/>
<authentication-manager>
<authentication-provider>
<user-service>

View File

@ -0,0 +1,63 @@
package org.baeldung.security;
import org.baeldung.spring.SecSecurityConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
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.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import javax.servlet.Filter;
import static org.junit.Assert.assertTrue;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SecSecurityConfig.class})
@WebAppConfiguration
public class FormLoginUnitTest {
@Autowired
private WebApplicationContext context;
@Autowired
private Filter springSecurityFilterChain;
private MockMvc mvc;
@Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.addFilters(springSecurityFilterChain)
.build();
}
@Test
public void givenValidRequestWithValidCredentials_shouldLoginSuccessfully() throws Exception {
mvc
.perform(formLogin("/perform_login").user("user1").password("user1Pass"))
.andExpect(status().isFound())
.andExpect(authenticated().withUsername("user1"));
}
@Test
public void givenValidRequestWithInvalidCredentials_shouldFailWith401() throws Exception {
MvcResult result = mvc
.perform(formLogin("/perform_login").user("random").password("random")).andReturn();
/*.andExpect(status().isUnauthorized())
.andDo(print())
.andExpect(unauthenticated())
.andReturn();*/
assertTrue(result.getResponse().getContentAsString().contains("Bad credentials"));
}
}

View File

@ -1,119 +1,122 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.baeldung</groupId>
<artifactId>gatling</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.baeldung</groupId>
<artifactId>gatling</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>io.gatling.highcharts</groupId>
<artifactId>gatling-charts-highcharts</artifactId>
</dependency>
<dependency>
<groupId>io.gatling</groupId>
<artifactId>gatling-app</artifactId>
</dependency>
<dependency>
<groupId>io.gatling</groupId>
<artifactId>gatling-recorder</artifactId>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
</dependency>
</dependencies>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<build>
<testSourceDirectory>src/test/scala</testSourceDirectory>
<pluginManagement>
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>${scala-maven-plugin.version}</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<args>
<!--<arg>-Ybackend:GenBCode</arg> -->
<arg>-Ydelambdafy:method</arg>
<arg>-target:jvm-1.8</arg>
<arg>-deprecation</arg>
<arg>-feature</arg>
<arg>-unchecked</arg>
<arg>-language:implicitConversions</arg>
<arg>-language:postfixOps</arg>
</args>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>io.gatling</groupId>
<artifactId>gatling-maven-plugin</artifactId>
<version>${gatling-maven-plugin.version}</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>execute</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>io.gatling.highcharts</groupId>
<artifactId>gatling-charts-highcharts</artifactId>
</dependency>
<dependency>
<groupId>io.gatling</groupId>
<artifactId>gatling-app</artifactId>
</dependency>
<dependency>
<groupId>io.gatling</groupId>
<artifactId>gatling-recorder</artifactId>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.gatling</groupId>
<artifactId>gatling-app</artifactId>
<version>${gatling.version}</version>
</dependency>
<dependency>
<groupId>io.gatling</groupId>
<artifactId>gatling-recorder</artifactId>
<version>${gatling.version}</version>
</dependency>
<dependency>
<groupId>io.gatling.highcharts</groupId>
<artifactId>gatling-charts-highcharts</artifactId>
<version>${gatling.version}</version>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<testSourceDirectory>src/test/scala</testSourceDirectory>
<pluginManagement>
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>${scala-maven-plugin.version}</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<args>
<!--<arg>-Ybackend:GenBCode</arg> -->
<arg>-Ydelambdafy:method</arg>
<arg>-target:jvm-1.8</arg>
<arg>-deprecation</arg>
<arg>-feature</arg>
<arg>-unchecked</arg>
<arg>-language:implicitConversions</arg>
<arg>-language:postfixOps</arg>
</args>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>io.gatling</groupId>
<artifactId>gatling-maven-plugin</artifactId>
<version>${gatling-maven-plugin.version}</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>execute</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<encoding>UTF-8</encoding>
<scala.version>2.11.12</scala.version> <!--2.11.12 --> <!--2.12.6 -->
<gatling.version>2.2.5</gatling.version> <!--2.2.5 --> <!--2.3.1 -->
<scala-maven-plugin.version>3.2.2</scala-maven-plugin.version> <!--3.2.2 --> <!--3.3.2 -->
<gatling-maven-plugin.version>2.2.1</gatling-maven-plugin.version> <!--2.2.1 --> <!--2.2.4 -->
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.gatling</groupId>
<artifactId>gatling-app</artifactId>
<version>${gatling.version}</version>
</dependency>
<dependency>
<groupId>io.gatling</groupId>
<artifactId>gatling-recorder</artifactId>
<version>${gatling.version}</version>
</dependency>
<dependency>
<groupId>io.gatling.highcharts</groupId>
<artifactId>gatling-charts-highcharts</artifactId>
<version>${gatling.version}</version>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<encoding>UTF-8</encoding>
<scala.version>2.11.12</scala.version> <!--2.11.12 --> <!--2.12.6 -->
<gatling.version>2.2.5</gatling.version> <!--2.2.5 --> <!--2.3.1 -->
<scala-maven-plugin.version>3.2.2</scala-maven-plugin.version> <!--3.2.2 --> <!--3.3.2 -->
<gatling-maven-plugin.version>2.2.1</gatling-maven-plugin.version> <!--2.2.1 --> <!--2.2.4 -->
</properties>
</project>

View File

@ -15,18 +15,22 @@ public class MockAnnotationUnitTest {
UserRepository mockRepository;
@Test
public void testMockAnnotation() {
public void givenCountMethodMocked_WhenCountInvoked_ThenMockValueReturned() {
Mockito.when(mockRepository.count()).thenReturn(123L);
long userCount = mockRepository.count();
Assert.assertEquals(123L, userCount);
Mockito.verify(mockRepository).count();
}
@Test
public void testMockitoMockMethod() {
public void givenCountMethodOfLocalMockVariableMocked_WhenCountInvoked_ThenMockedValueReturned() {
UserRepository localMockRepository = Mockito.mock(UserRepository.class);
Mockito.when(localMockRepository.count()).thenReturn(111L);
long userCount = localMockRepository.count();
Assert.assertEquals(111L, userCount);
Mockito.verify(localMockRepository).count();
}

View File

@ -20,10 +20,12 @@ public class MockBeanAnnotationIntegrationTest {
ApplicationContext context;
@Test
public void testMockBean() {
public void givenCountMethodMocked_WhenCountInvokedOnBeanFromContext_ThenMockValueReturned() {
Mockito.when(mockRepository.count()).thenReturn(123L);
UserRepository userRepoFromContext = context.getBean(UserRepository.class);
long userCount = userRepoFromContext.count();
Assert.assertEquals(123L, userCount);
Mockito.verify(mockRepository).count();
}