diff --git a/spring-boot-security-taglibs/.gitignore b/spring-boot-security-taglibs/.gitignore
new file mode 100644
index 0000000000..83c05e60c8
--- /dev/null
+++ b/spring-boot-security-taglibs/.gitignore
@@ -0,0 +1,13 @@
+*.class
+
+#folders#
+/target
+/neoDb*
+/data
+/src/main/webapp/WEB-INF/classes
+*/META-INF/*
+
+# Packaged files #
+*.jar
+*.war
+*.ear
\ No newline at end of file
diff --git a/spring-boot-security-taglibs/README.md b/spring-boot-security-taglibs/README.md
new file mode 100644
index 0000000000..f7eb314869
--- /dev/null
+++ b/spring-boot-security-taglibs/README.md
@@ -0,0 +1,19 @@
+=========
+
+## Spring Security Login Example Project
+
+###The Course
+The "Learn Spring Security" Classes: http://github.learnspringsecurity.com
+
+### Relevant Articles:
+- [Spring Security Form Login](http://www.baeldung.com/spring-security-login)
+- [Spring Security Logout](http://www.baeldung.com/spring-security-logout)
+- [Spring Security Expressions – hasRole Example](http://www.baeldung.com/spring-security-expressions-basic)
+- [Spring HTTP/HTTPS Channel Security](http://www.baeldung.com/spring-channel-security-https)
+- [Spring Security - Customize the 403 Forbidden/Access Denied Page](http://www.baeldung.com/spring-security-custom-access-denied-page)
+- [Spring Security – Redirect to the Previous URL After Login](http://www.baeldung.com/spring-security-redirect-login)
+
+### Build the Project
+```
+mvn clean install
+```
diff --git a/spring-boot-security-taglibs/pom.xml b/spring-boot-security-taglibs/pom.xml
new file mode 100644
index 0000000000..bd04ec3c0b
--- /dev/null
+++ b/spring-boot-security-taglibs/pom.xml
@@ -0,0 +1,84 @@
+
+ 4.0.0
+
+ spring-boot-security-taglibs
+ jar
+ spring-boot-security-taglibs
+ spring 5 security sample project
+
+
+ com.baeldung
+ parent-boot-2
+ 0.0.1-SNAPSHOT
+ ../parent-boot-2
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+ org.springframework.security
+ spring-security-taglibs
+
+
+
+
+ org.apache.tomcat.embed
+ tomcat-embed-jasper
+ provided
+
+
+ javax.servlet
+ jstl
+
+
+
+ net.sourceforge.htmlunit
+ htmlunit
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.security
+ spring-security-test
+ test
+
+
+
+
+
+ spring-5-security-taglibs
+
+
+ src/main/resources
+ true
+
+
+
+
+
+
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+
+
+
\ No newline at end of file
diff --git a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/Application.java b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/Application.java
new file mode 100644
index 0000000000..eef41bd375
--- /dev/null
+++ b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/Application.java
@@ -0,0 +1,23 @@
+package org.baeldung.security;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+@SpringBootApplication
+public class Application extends SpringBootServletInitializer {
+
+ public Application() {
+ super();
+ }
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
+ return builder.sources(Application.class);
+ }
+}
diff --git a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java
new file mode 100644
index 0000000000..0eb6ee242d
--- /dev/null
+++ b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java
@@ -0,0 +1,18 @@
+package org.baeldung.security;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@Controller
+@RequestMapping("/")
+public class HomeController {
+
+ @RequestMapping("")
+ public String home(HttpServletRequest request, HttpServletResponse response) {
+ return "home";
+ }
+
+}
diff --git a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/SecurityConfig.java b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/SecurityConfig.java
new file mode 100644
index 0000000000..f6df516a0a
--- /dev/null
+++ b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/SecurityConfig.java
@@ -0,0 +1,70 @@
+package org.baeldung.security;
+
+import java.util.HashSet;
+import java.util.Set;
+
+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.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.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+@Configuration
+@EnableWebSecurity
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+ private static final String ROLE_PREFIX = "ROLE_";
+ public static final String DEFAULT_PASSWORD = "password";
+ @Bean
+ static PasswordEncoder bCryptPasswordEncoder() {
+ return new BCryptPasswordEncoder(10);
+ }
+
+ @Bean
+ UserDetailsService customUserDetailsService() {
+ return new UserDetailsService() {
+
+ @Override
+ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+ //authenticate and return dummy user
+ Set authorities = new HashSet();
+ authorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + username));
+ return new User(username, bCryptPasswordEncoder().encode(DEFAULT_PASSWORD), authorities);
+ }
+ };
+ }
+
+ @Override
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+ auth.userDetailsService(customUserDetailsService()).passwordEncoder(bCryptPasswordEncoder());
+
+ }
+
+ @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
+ @Override
+ public AuthenticationManager authenticationManagerBean() throws Exception {
+ return super.authenticationManager();
+ }
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http.csrf();
+ http.headers().frameOptions().sameOrigin();
+
+ http.antMatcher("/**").userDetailsService(customUserDetailsService())
+ .authorizeRequests()
+ .antMatchers("/**").permitAll()
+ .and()
+ .httpBasic();
+ }
+}
diff --git a/spring-boot-security-taglibs/src/main/resources/application.properties b/spring-boot-security-taglibs/src/main/resources/application.properties
new file mode 100644
index 0000000000..9c49bd2137
--- /dev/null
+++ b/spring-boot-security-taglibs/src/main/resources/application.properties
@@ -0,0 +1,8 @@
+#jsp config
+spring.mvc.view.prefix: /WEB-INF/views/
+spring.mvc.view.suffix: .jsp
+spring.http.encoding.charset=UTF-8
+# Enable http encoding support.
+spring.http.encoding.enabled=true
+# Force the encoding to the configured charset on HTTP requests and responses.
+spring.http.encoding.force=true
diff --git a/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp
new file mode 100644
index 0000000000..9f5d8c34a3
--- /dev/null
+++ b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp
@@ -0,0 +1,20 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1"%>
+<%@ taglib prefix="security"
+ uri="http://www.springframework.org/security/tags" %>
+
+
+
+
+
+Home Page
+
+
+
+ AUTHENTICATED
+
+
+ ADMIN ROLE
+
+
+
\ No newline at end of file
diff --git a/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java b/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java
new file mode 100644
index 0000000000..f13b23a10d
--- /dev/null
+++ b/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java
@@ -0,0 +1,27 @@
+package org.baeldung.security;
+
+import static org.junit.Assert.assertTrue;
+
+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.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+public class HomeControllerTest {
+
+ @Autowired
+ private TestRestTemplate restTemplate;
+
+ @Test
+ public void home() throws Exception {
+ String body = this.restTemplate.withBasicAuth("ADMIN", SecurityConfig.DEFAULT_PASSWORD).getForEntity("/", String.class).getBody();
+ System.out.println(body);
+ assertTrue(body.contains("AUTHENTICATED"));
+ assertTrue(body.contains("ADMIN ROLE"));
+ }
+}