-
Notifications
You must be signed in to change notification settings - Fork 184
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 57ce676
Showing
29 changed files
with
906 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.idea | ||
*.iml | ||
target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
Example Spring Boot Security | ||
============================ | ||
|
||
The application showing how to use Spring Boot with Spring Security for common needs, such as: | ||
|
||
* Customized login form | ||
* DAO-based authentication | ||
* Basic "remember me" authentication | ||
* URL-based security | ||
* Method-level security | ||
|
||
See the [Spring Boot Security Application](http://kielczewski.eu/12/2014/spring-boot-security-application/) article for | ||
commentary. | ||
|
||
Requirements | ||
------------ | ||
* [Java Platform (JDK) 8](http://www.oracle.com/technetwork/java/javase/downloads/index.html) | ||
* [Apache Maven 3.x](http://maven.apache.org/) | ||
|
||
Quick start | ||
----------- | ||
1. `mvn spring-boot:run` | ||
3. Point your browser to [http://localhost:8080/](http://localhost:8080/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xmlns="http://maven.apache.org/POM/4.0.0" | ||
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>eu.kielczewski.example</groupId> | ||
<artifactId>example-spring-boot-security</artifactId> | ||
<version>1.0-SNAPSHOT</version> | ||
<packaging>war</packaging> | ||
|
||
<parent> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-parent</artifactId> | ||
<version>1.2.0.RELEASE</version> | ||
</parent> | ||
|
||
<name>Spring Boot Security Example</name> | ||
<url>http://kielczewski.eu/12/2014/spring-boot-security-application/</url> | ||
|
||
<properties> | ||
<java.version>1.8</java.version> | ||
</properties> | ||
|
||
<dependencies> | ||
|
||
<!-- Spring Boot --> | ||
|
||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-test</artifactId> | ||
<scope>test</scope> | ||
<exclusions> | ||
<exclusion> | ||
<groupId>org.springframework</groupId> | ||
<artifactId>spring-test</artifactId> | ||
</exclusion> | ||
</exclusions> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-freemarker</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-security</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-data-jpa</artifactId> | ||
</dependency> | ||
|
||
<!-- HSQLDB --> | ||
|
||
<dependency> | ||
<groupId>org.hsqldb</groupId> | ||
<artifactId>hsqldb</artifactId> | ||
</dependency> | ||
|
||
</dependencies> | ||
|
||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package eu.kielczewski.example; | ||
|
||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
import org.springframework.boot.builder.SpringApplicationBuilder; | ||
import org.springframework.boot.context.web.SpringBootServletInitializer; | ||
|
||
@SpringBootApplication | ||
public class Application extends SpringBootServletInitializer { | ||
|
||
public static void main(String[] args) { | ||
SpringApplication.run(Application.class, args); | ||
} | ||
|
||
@Override | ||
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { | ||
return application.sources(Application.class); | ||
} | ||
|
||
} |
51 changes: 51 additions & 0 deletions
51
src/main/java/eu/kielczewski/example/config/SecurityConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package eu.kielczewski.example.config; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.autoconfigure.security.SecurityProperties; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.core.annotation.Order; | ||
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.configuration.WebSecurityConfigurerAdapter; | ||
import org.springframework.security.core.userdetails.UserDetailsService; | ||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | ||
|
||
@Configuration | ||
@EnableGlobalMethodSecurity(prePostEnabled = true) | ||
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) | ||
class SecurityConfig extends WebSecurityConfigurerAdapter { | ||
|
||
@Autowired | ||
private UserDetailsService userDetailsService; | ||
|
||
@Override | ||
protected void configure(HttpSecurity http) throws Exception { | ||
http.authorizeRequests() | ||
.antMatchers("/", "/public/**").permitAll() | ||
.antMatchers("/users/**").hasAuthority("ADMIN") | ||
.anyRequest().fullyAuthenticated() | ||
.and() | ||
.formLogin() | ||
.loginPage("/login") | ||
.failureUrl("/login?error") | ||
.usernameParameter("email") | ||
.permitAll() | ||
.and() | ||
.logout() | ||
.logoutUrl("/logout") | ||
.deleteCookies("remember-me") | ||
.logoutSuccessUrl("/") | ||
.permitAll() | ||
.and() | ||
.rememberMe(); | ||
} | ||
|
||
@Override | ||
public void configure(AuthenticationManagerBuilder auth) throws Exception { | ||
auth | ||
.userDetailsService(userDetailsService) | ||
.passwordEncoder(new BCryptPasswordEncoder()); | ||
} | ||
|
||
} |
21 changes: 21 additions & 0 deletions
21
src/main/java/eu/kielczewski/example/controller/CurrentUserControllerAdvice.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package eu.kielczewski.example.controller; | ||
|
||
import eu.kielczewski.example.domain.CurrentUser; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.web.bind.annotation.ControllerAdvice; | ||
import org.springframework.web.bind.annotation.ModelAttribute; | ||
|
||
@ControllerAdvice | ||
public class CurrentUserControllerAdvice { | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(CurrentUserControllerAdvice.class); | ||
|
||
@ModelAttribute("currentUser") | ||
public CurrentUser getCurrentUser(Authentication authentication) { | ||
return (authentication == null) ? null : (CurrentUser) authentication.getPrincipal(); | ||
} | ||
|
||
|
||
} |
23 changes: 23 additions & 0 deletions
23
src/main/java/eu/kielczewski/example/controller/ExceptionHandlerControllerAdvice.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package eu.kielczewski.example.controller; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.web.bind.annotation.ControllerAdvice; | ||
import org.springframework.web.bind.annotation.ExceptionHandler; | ||
import org.springframework.web.bind.annotation.ResponseStatus; | ||
|
||
import java.util.NoSuchElementException; | ||
|
||
@ControllerAdvice | ||
public class ExceptionHandlerControllerAdvice { | ||
|
||
private static Logger LOGGER = LoggerFactory.getLogger(ExceptionHandlerControllerAdvice.class); | ||
|
||
@ExceptionHandler(NoSuchElementException.class) | ||
@ResponseStatus(HttpStatus.NOT_FOUND) | ||
public String handleNoSuchElementException(NoSuchElementException e) { | ||
return e.getMessage(); | ||
} | ||
|
||
} |
19 changes: 19 additions & 0 deletions
19
src/main/java/eu/kielczewski/example/controller/HomeController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package eu.kielczewski.example.controller; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
|
||
@Controller | ||
public class HomeController { | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(HomeController.class); | ||
|
||
@RequestMapping("/") | ||
public String getHomePage() { | ||
LOGGER.debug("Getting home page"); | ||
return "home"; | ||
} | ||
|
||
} |
24 changes: 24 additions & 0 deletions
24
src/main/java/eu/kielczewski/example/controller/LoginController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package eu.kielczewski.example.controller; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
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; | ||
import org.springframework.web.servlet.ModelAndView; | ||
|
||
import java.util.Optional; | ||
|
||
@Controller | ||
public class LoginController { | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(LoginController.class); | ||
|
||
@RequestMapping(value = "/login", method = RequestMethod.GET) | ||
public ModelAndView getLoginPage(@RequestParam Optional<String> error) { | ||
LOGGER.debug("Getting login page, error={}", error); | ||
return new ModelAndView("login", "error", error); | ||
} | ||
|
||
} |
74 changes: 74 additions & 0 deletions
74
src/main/java/eu/kielczewski/example/controller/UserController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package eu.kielczewski.example.controller; | ||
|
||
import eu.kielczewski.example.domain.UserCreateForm; | ||
import eu.kielczewski.example.domain.validator.UserCreateFormValidator; | ||
import eu.kielczewski.example.service.user.UserService; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.dao.DataIntegrityViolationException; | ||
import org.springframework.security.access.prepost.PreAuthorize; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.validation.BindingResult; | ||
import org.springframework.web.bind.WebDataBinder; | ||
import org.springframework.web.bind.annotation.*; | ||
import org.springframework.web.servlet.ModelAndView; | ||
|
||
import javax.validation.Valid; | ||
import java.util.NoSuchElementException; | ||
|
||
@Controller | ||
public class UserController { | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class); | ||
private final UserService userService; | ||
private final UserCreateFormValidator userCreateFormValidator; | ||
|
||
@Autowired | ||
public UserController(UserService userService, UserCreateFormValidator userCreateFormValidator) { | ||
this.userService = userService; | ||
this.userCreateFormValidator = userCreateFormValidator; | ||
} | ||
|
||
@InitBinder("form") | ||
public void initBinder(WebDataBinder binder) { | ||
binder.addValidators(userCreateFormValidator); | ||
} | ||
|
||
@PreAuthorize("@currentUserServiceImpl.canAccessUser(principal, #id)") | ||
@RequestMapping("/user/{id}") | ||
public ModelAndView getUserPage(@PathVariable Long id) { | ||
LOGGER.debug("Getting user page for user={}", id); | ||
return new ModelAndView("user", "user", userService.getUserById(id) | ||
.orElseThrow(() -> new NoSuchElementException(String.format("User=%s not found", id)))); | ||
} | ||
|
||
@PreAuthorize("hasAuthority('ADMIN')") | ||
@RequestMapping(value = "/user/create", method = RequestMethod.GET) | ||
public ModelAndView getUserCreatePage() { | ||
LOGGER.debug("Getting user create form"); | ||
return new ModelAndView("user_create", "form", new UserCreateForm()); | ||
} | ||
|
||
@PreAuthorize("hasAuthority('ADMIN')") | ||
@RequestMapping(value = "/user/create", method = RequestMethod.POST) | ||
public String handleUserCreateForm(@Valid @ModelAttribute("form") UserCreateForm form, BindingResult bindingResult) { | ||
LOGGER.debug("Processing user create form={}, bindingResult={}", form, bindingResult); | ||
if (bindingResult.hasErrors()) { | ||
// failed validation | ||
return "user_create"; | ||
} | ||
try { | ||
userService.create(form); | ||
} catch (DataIntegrityViolationException e) { | ||
// probably email already exists - very rare case when multiple admins are adding same user | ||
// at the same time and form validation has passed for more than one of them. | ||
LOGGER.warn("Exception occurred when trying to save the user, assuming duplicate email", e); | ||
bindingResult.reject("email.exists", "Email already exists"); | ||
return "user_create"; | ||
} | ||
// ok, redirect | ||
return "redirect:/users"; | ||
} | ||
|
||
} |
29 changes: 29 additions & 0 deletions
29
src/main/java/eu/kielczewski/example/controller/UsersController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package eu.kielczewski.example.controller; | ||
|
||
import eu.kielczewski.example.service.user.UserService; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.servlet.ModelAndView; | ||
|
||
@Controller | ||
public class UsersController { | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(UsersController.class); | ||
private final UserService userService; | ||
|
||
@Autowired | ||
public UsersController(UserService userService) { | ||
this.userService = userService; | ||
} | ||
|
||
@RequestMapping("/users") | ||
public ModelAndView getUsersPage() { | ||
LOGGER.debug("Getting users page"); | ||
return new ModelAndView("users", "users", userService.getAllUsers()); | ||
} | ||
|
||
|
||
} |
Oops, something went wrong.