[BAEL-9552] - Create spring-security-modules folder
This commit is contained in:
22
spring-security-modules/spring-security-mvc-ldap/README.md
Normal file
22
spring-security-modules/spring-security-mvc-ldap/README.md
Normal file
@@ -0,0 +1,22 @@
|
||||
## Spring Security LDAP
|
||||
|
||||
This module contains articles about Spring Security LDAP
|
||||
|
||||
### The Course
|
||||
|
||||
The "Learn Spring Security" Classes: http://github.learnspringsecurity.com
|
||||
|
||||
### Relevant Article:
|
||||
|
||||
- [Spring Security – security none, filters none, access permitAll](https://www.baeldung.com/security-none-filters-none-access-permitAll)
|
||||
- [Intro to Spring Security LDAP](https://www.baeldung.com/spring-security-ldap)
|
||||
|
||||
### Notes
|
||||
|
||||
- the project uses Spring Boot - simply run 'SampleLDAPApplication.java' to start up Spring Boot with a Tomcat container and embedded LDAP server.
|
||||
- Once started, open 'http://localhost:8080'
|
||||
- This will display the publicly available Home Page
|
||||
- Navigate to 'Secure Page' to trigger authentication
|
||||
- Username: 'baeldung', password: 'password'
|
||||
- This will authenticate you, and display your allocated roles (as defined in the 'users.ldif' file)
|
||||
|
||||
62
spring-security-modules/spring-security-mvc-ldap/pom.xml
Normal file
62
spring-security-modules/spring-security-mvc-ldap/pom.xml
Normal file
@@ -0,0 +1,62 @@
|
||||
<?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>
|
||||
<artifactId>spring-security-mvc-ldap</artifactId>
|
||||
<version>0.1-SNAPSHOT</version>
|
||||
<name>spring-security-mvc-ldap</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-1</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-1</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- Spring Boot Dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- LDAP Dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-ldap</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<!-- Is the ApacheDS server - 1.5.6 and 1.5.7 don't work -->
|
||||
<groupId>org.apache.directory.server</groupId>
|
||||
<artifactId>apacheds-server-jndi</artifactId>
|
||||
<version>${apacheds.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>spring-security-mvc-ldap</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<apacheds.version>1.5.5</apacheds.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.baeldung;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.web.support.SpringBootServletInitializer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
|
||||
/**
|
||||
* Main Application Class - uses Spring Boot. Just run this as a normal Java
|
||||
* class to run up a Jetty Server (on http://localhost:8080)
|
||||
*
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class SampleLDAPApplication extends SpringBootServletInitializer {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SampleLDAPApplication.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public WebMvcConfigurerAdapter adapter() {
|
||||
return new WebMvcConfigurerAdapter() {
|
||||
@Override
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
registry.addViewController("/login")
|
||||
.setViewName("login");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package org.baeldung.controller;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
/**
|
||||
* Spring Controller Definitions.
|
||||
*/
|
||||
@Controller
|
||||
public class MyController {
|
||||
|
||||
@RequestMapping("/")
|
||||
public String init(Map<String, Object> model, Principal principal) {
|
||||
model.put("title", "PUBLIC AREA");
|
||||
model.put("message", "Any user can view this page");
|
||||
model.put("username", getUserName(principal));
|
||||
model.put("userroles", getUserRoles(principal));
|
||||
return "home";
|
||||
}
|
||||
|
||||
@RequestMapping("/secure")
|
||||
public String secure(Map<String, Object> model, Principal principal) {
|
||||
model.put("title", "SECURE AREA");
|
||||
model.put("message", "Only Authorised Users Can See This Page");
|
||||
model.put("username", getUserName(principal));
|
||||
model.put("userroles", getUserRoles(principal));
|
||||
return "home";
|
||||
}
|
||||
|
||||
private String getUserName(Principal principal) {
|
||||
if (principal == null) {
|
||||
return "anonymous";
|
||||
} else {
|
||||
|
||||
final UserDetails currentUser = (UserDetails) ((Authentication) principal).getPrincipal();
|
||||
Collection<? extends GrantedAuthority> authorities = currentUser.getAuthorities();
|
||||
for (GrantedAuthority grantedAuthority : authorities) {
|
||||
System.out.println(grantedAuthority.getAuthority());
|
||||
}
|
||||
return principal.getName();
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<String> getUserRoles(Principal principal) {
|
||||
if (principal == null) {
|
||||
return Arrays.asList("none");
|
||||
} else {
|
||||
|
||||
Set<String> roles = new HashSet<String>();
|
||||
|
||||
final UserDetails currentUser = (UserDetails) ((Authentication) principal).getPrincipal();
|
||||
Collection<? extends GrantedAuthority> authorities = currentUser.getAuthorities();
|
||||
for (GrantedAuthority grantedAuthority : authorities) {
|
||||
roles.add(grantedAuthority.getAuthority());
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.baeldung.security;
|
||||
|
||||
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.WebSecurityConfigurerAdapter;
|
||||
|
||||
/**
|
||||
* Security Configuration - LDAP and HTTP Authorizations.
|
||||
*/
|
||||
@Configuration
|
||||
// @ImportResource({ "classpath:webSecurityConfig.xml" }) //=> uncomment to use equivalent xml config
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth.ldapAuthentication().userSearchBase("ou=people").userSearchFilter("(uid={0})").groupSearchBase("ou=groups").groupSearchFilter("(member={0})").contextSource().root("dc=baeldung,dc=com").ldif("classpath:users.ldif");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http.authorizeRequests().antMatchers("/", "/home").permitAll().anyRequest().authenticated();
|
||||
http.formLogin().loginPage("/login").permitAll().and().logout().logoutSuccessUrl("/");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework" level="WARN" />
|
||||
<logger name="org.springframework.transaction" level="WARN" />
|
||||
|
||||
<!-- in order to debug some marshalling issues, this needs to be TRACE -->
|
||||
<logger name="org.springframework.web.servlet.mvc" level="WARN" />
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
13
spring-security-modules/spring-security-mvc-ldap/src/main/resources/static/css/bootstrap.min.css
vendored
Normal file
13
spring-security-modules/spring-security-mvc-ldap/src/main/resources/static/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title>Error</title>
|
||||
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}"
|
||||
href="../../css/bootstrap.min.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="navbar">
|
||||
<div class="navbar-inner">
|
||||
<a class="brand" href="http://www.thymeleaf.org"> Thymeleaf -
|
||||
Plain </a>
|
||||
<ul class="nav">
|
||||
<li><a th:href="@{/}" href="home.html"> Home </a></li>
|
||||
<li><a th:href="@{/secure}" href="secure.html"> Secure Page </a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<h1 th:text="${title}"></h1>
|
||||
<div id="created" th:text="${#dates.format(timestamp)}"></div>
|
||||
<div>
|
||||
There was an unexpected error (type=<span th:text="${error}">Bad</span>, status=<span th:text="${status}">500</span>).
|
||||
</div>
|
||||
<div th:text="${message}">Fake content</div>
|
||||
<div>
|
||||
Please contact the operator with the above information.
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title th:text="${title}">Title</title>
|
||||
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}"
|
||||
href="../../css/bootstrap.min.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<div class="navbar">
|
||||
<div class="navbar-inner">
|
||||
<a class="brand" href="http://www.thymeleaf.org"> Thymeleaf -
|
||||
Plain </a>
|
||||
<ul class="nav">
|
||||
<li><a th:href="@{/}" href="home.html"> Home </a></li>
|
||||
<li><a th:href="@{/secure}" href="home.html"> Secure Page </a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="content">
|
||||
<p>
|
||||
<h1 th:text="${title}"></h1>
|
||||
<h2 th:text="${message}"></h2>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div id="footer">
|
||||
<p>
|
||||
Logged in as: <span th:text="${username}"></span>, Roles: <span th:text="${userroles}"></span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title>Login</title>
|
||||
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}"
|
||||
href="../../css/bootstrap.min.css" />
|
||||
</head>
|
||||
<body onload="document.f.username.focus();">
|
||||
<div class="container">
|
||||
<div class="navbar">
|
||||
<div class="navbar-inner">
|
||||
<a class="brand" href="http://www.thymeleaf.org"> Thymeleaf -
|
||||
Plain </a>
|
||||
<ul class="nav">
|
||||
<li><a th:href="@{/}" href="home.html"> Home </a></li>
|
||||
<li><a th:href="@{/secure}" href="home.html"> Secure Page </a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<p th:if="${param.logout}" class="alert">You have been logged out</p>
|
||||
<p th:if="${param.error}" class="alert alert-error">There was an error, please try again</p>
|
||||
<h2>Login with Username and Password</h2>
|
||||
<form name="form" th:action="@{/login}" method="POST">
|
||||
<fieldset>
|
||||
<input type="text" name="username" value="" placeholder="Username" />
|
||||
<input type="password" name="password" placeholder="Password" />
|
||||
</fieldset>
|
||||
<input type="submit" id="login" value="Login"
|
||||
class="btn btn-primary" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,31 @@
|
||||
dn: ou=groups,dc=baeldung,dc=com
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: groups
|
||||
|
||||
dn: ou=people,dc=baeldung,dc=com
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: people
|
||||
|
||||
dn: uid=baeldung,ou=people,dc=baeldung,dc=com
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
cn: Jim Beam
|
||||
sn: Beam
|
||||
uid: baeldung
|
||||
userPassword: password
|
||||
|
||||
dn: cn=admin,ou=groups,dc=baeldung,dc=com
|
||||
objectclass: top
|
||||
objectclass: groupOfNames
|
||||
cn: admin
|
||||
member: uid=baeldung,ou=people,dc=baeldung,dc=com
|
||||
|
||||
dn: cn=user,ou=groups,dc=baeldung,dc=com
|
||||
objectclass: top
|
||||
objectclass: groupOfNames
|
||||
cn: user
|
||||
member: uid=baeldung,ou=people,dc=baeldung,dc=com
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/security
|
||||
http://www.springframework.org/schema/security/spring-security.xsd
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"
|
||||
>
|
||||
|
||||
<http auto-config="true" use-expressions="true">
|
||||
<intercept-url pattern="/" access="permitAll"/>
|
||||
<intercept-url pattern="/home" access="permitAll"/>
|
||||
<intercept-url pattern="/login" access="permitAll"/>
|
||||
<intercept-url pattern="/secure" access="isAuthenticated()"/>
|
||||
|
||||
<form-login login-page='/login' default-target-url="/" authentication-failure-url="/login?error" />
|
||||
<logout logout-success-url="/" />
|
||||
</http>
|
||||
|
||||
<authentication-manager>
|
||||
<ldap-authentication-provider
|
||||
user-search-base="ou=people"
|
||||
user-search-filter="(uid={0})"
|
||||
group-search-base="ou=groups"
|
||||
group-search-filter="(member={0})"
|
||||
>
|
||||
</ldap-authentication-provider>
|
||||
</authentication-manager>
|
||||
|
||||
<ldap-server root="dc=baeldung,dc=com" ldif="users.ldif"/>
|
||||
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.baeldung;
|
||||
|
||||
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(classes = SampleLDAPApplication.class)
|
||||
public class SpringContextTest {
|
||||
|
||||
@Test
|
||||
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
||||
}
|
||||
}
|
||||
13
spring-security-modules/spring-security-mvc-ldap/src/test/resources/.gitignore
vendored
Normal file
13
spring-security-modules/spring-security-mvc-ldap/src/test/resources/.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
*.class
|
||||
|
||||
#folders#
|
||||
/target
|
||||
/neoDb*
|
||||
/data
|
||||
/src/main/webapp/WEB-INF/classes
|
||||
*/META-INF/*
|
||||
|
||||
# Packaged files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
Reference in New Issue
Block a user