Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 27 additions & 28 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.alexmond</groupId>
<version>0.0.1-SNAPSHOT</version>
<artifactId>boot-sample-root</artifactId>
<packaging>pom</packaging>
<name>Spring boot samples root</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<spring-boot-admin.version>3.2.3</spring-boot-admin.version>
</properties>
<modules>
<module>spring-boot-rest-sample</module>
<module>spring-boot-config-sample</module>
<module>spring-boot-data-jpa-flyway</module>
<module>spring-boot-cloud</module>
<module>spring-boot-openapi-root</module>
<module>spring-boot-thymeleaf</module>
<module>spring-boot-config-dependency</module>
<module>spring-boot-security-root</module>
</modules>
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.alexmond</groupId>
<version>0.0.1-SNAPSHOT</version>
<artifactId>boot-sample-root</artifactId>
<packaging>pom</packaging>
<name>Spring boot samples root</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.3</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<properties>
<spring-boot-admin.version>3.2.3</spring-boot-admin.version>
</properties>
<modules>
<module>spring-boot-rest-sample</module>
<module>spring-boot-config-sample</module>
<module>spring-boot-data-jpa-flyway</module>
<module>spring-boot-cloud</module>
<module>spring-boot-openapi-root</module>
<module>spring-boot-thymeleaf</module>
<module>spring-boot-config-dependency</module>
<module>spring-boot-security-root</module>
</modules>
</project>
1 change: 1 addition & 0 deletions spring-boot-security-root/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<modules>
<module>spring-boot-custom-auth-server</module>
<module>simple-boot-auth-client</module>
<module>spring-boot-auth-roles</module>
</modules>

</project>
46 changes: 46 additions & 0 deletions spring-boot-security-root/spring-boot-auth-roles/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.alexmond</groupId>
<artifactId>spring-boot-security-root</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.alexmond.sample.auth</groupId>
<artifactId>spring-boot-auth-roles</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-auth-roles</name>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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-security</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>5.3.3</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>font-awesome</artifactId>
<version>6.5.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org;

/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.alexmond.sample.auth;

import java.util.List;

public class AppUser {
private String username;
private String password;
private List<String> roles;

public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }

public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }

public List<String> getRoles() { return roles; }
public void setRoles(List<String> roles) { this.roles = roles; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.alexmond.sample.auth;

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);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.alexmond.sample.auth;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {
private final Users users;

public SecurityConfig(Users users) {
this.users = users;
}

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(auth -> auth
.requestMatchers("/", "/login", "/webjars/**", "/css/**", "/js/**").permitAll()
.requestMatchers("/user").hasAnyRole("USER", "ADMIN")
.requestMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated()
)
.formLogin(form -> form
.loginPage("/login")
.defaultSuccessUrl("/", true)
.permitAll()
)
.logout(logout -> logout
.logoutUrl("/logout")
.logoutSuccessUrl("/")
.permitAll()
)
.httpBasic(Customizer.withDefaults());
return http.build();
}

@Bean
public UserDetailsService userDetailsService() {
return new InMemoryUserDetailsManager(users.getUserDetails());
}

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.alexmond.sample.auth;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Component
@ConfigurationProperties("users")
public class Users {
public List<AppUser> appUsers;

public Collection<UserDetails> getUserDetails() {
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
Collection<UserDetails> userDetails = new ArrayList<>();
if (appUsers != null) {
for (AppUser appUser : appUsers) {
userDetails.add(User.withUsername(appUser.getUsername())
.password(appUser.getPassword())
.roles(appUser.getRoles().toArray(new String[0]))
.build());
}
}
return userDetails;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.alexmond.sample.auth;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class WebController {
@GetMapping("/")
public String index() {
return "index";
}

@GetMapping("/user")
public String user() {
return "user";
}

@GetMapping("/admin")
public String admin() {
return "admin";
}

@GetMapping("/login")
public String login() {
return "login";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
users:
appUsers:
- username: user
password: "{noop}password"
roles: ["USER"]
- username: admin
password: "{noop}password"
roles: ["ADMIN", "USER"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Page</title>
<link th:href="@{/webjars/bootstrap/css/bootstrap.min.css}" rel="stylesheet">
<link th:href="@{/webjars/font-awesome/css/all.min.css}" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="/">Auth Roles Demo</a>
<div class="navbar-nav ms-auto">
<form th:action="@{/logout}" method="post" style="display:inline;">
<button class="btn btn-outline-light" type="submit">Logout</button>
</form>
</div>
</div>
</nav>
<div class="container mt-4">
<h1>Admin Page</h1>
<p>This page is accessible to users with the ADMIN role only.</p>
<a class="btn btn-secondary" th:href="@{/}">Back to Home</a>
</div>
<script th:src="@{/webjars/bootstrap/js/bootstrap.bundle.min.js}"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Index</title>
<link th:href="@{/webjars/bootstrap/css/bootstrap.min.css}" rel="stylesheet">
<link th:href="@{/webjars/font-awesome/css/all.min.css}" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="/">Auth Roles Demo</a>
<div class="navbar-nav ms-auto">
<span th:if="${#authorization.expression('isAuthenticated()')}">
<form th:action="@{/logout}" method="post" style="display:inline;">
<button class="btn btn-outline-light" type="submit">Logout</button>
</form>
</span>
<span th:if="${!#authorization.expression('isAuthenticated()')}">
<a class="btn btn-outline-light" th:href="@{/login}">Login</a>
</span>
</div>
</div>
</nav>
<div class="container mt-4">
<h1>Welcome to the Auth Roles Demo</h1>
<p>This is the public index page. Anyone can access this page.</p>
<div>
<a class="btn btn-primary" th:href="@{/user}">User Page</a>
<a class="btn btn-danger" th:href="@{/admin}">Admin Page</a>
</div>
</div>
<script th:src="@{/webjars/bootstrap/js/bootstrap.bundle.min.js}"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
<link th:href="@{/webjars/bootstrap/css/bootstrap.min.css}" rel="stylesheet">
<link th:href="@{/webjars/font-awesome/css/all.min.css}" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<div class="row justify-content-center">
<div class="col-md-4">
<div class="card">
<div class="card-header text-center">
<h3>Login</h3>
</div>
<div class="card-body">
<form th:action="@{/login}" method="post">
<div class="mb-3">
<label for="username" class="form-label">Username</label>
<input type="text" class="form-control" id="username" name="username" required autofocus>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password" required>
</div>
<div th:if="${param.error}" class="alert alert-danger" role="alert">
Invalid username or password.
</div>
<button type="submit" class="btn btn-primary w-100">Login</button>
</form>
</div>
</div>
</div>
</div>
</div>
<script th:src="@{/webjars/bootstrap/js/bootstrap.bundle.min.js}"></script>
</body>
</html>
Loading