From d3775947204d814dcc1ab8f75d99d1c4b5512bba Mon Sep 17 00:00:00 2001 From: Maximilian Leopold Date: Sun, 24 Mar 2019 15:09:28 +0100 Subject: [PATCH] Implemented Login --- build.gradle | 7 +++ .../hhn/labsw/bugageocaching/Application.java | 11 +++- .../config/WebSecurityConfig.java | 52 +++++++++++++++++++ .../bugageocaching/controller/Controller.java | 21 ++++++++ .../labsw/bugageocaching/entities/Role.java | 44 ++++++++++++++++ .../labsw/bugageocaching/entities/User.java | 41 ++++++++------- .../repositories/BearbeitetRepository.java | 3 +- .../CacheAccesDefinitionRepository.java | 3 +- .../repositories/CacheRepository.java | 3 +- .../repositories/RewardRepository.java | 3 +- .../repositories/RoleRepository.java | 7 +++ .../repositories/StationRepository.java | 3 +- .../repositories/TeamRepository.java | 3 +- .../repositories/UserRepository.java | 4 +- .../service/SecurityService.java | 8 +++ .../service/SecurityServiceImpl.java | 48 +++++++++++++++++ .../service/UserDetailsServiceImpl.java | 37 +++++++++++++ .../bugageocaching/service/UserService.java | 10 ++++ .../service/UserServiceImpl.java | 33 ++++++++++++ 19 files changed, 314 insertions(+), 27 deletions(-) create mode 100644 src/main/java/hhn/labsw/bugageocaching/config/WebSecurityConfig.java create mode 100644 src/main/java/hhn/labsw/bugageocaching/entities/Role.java create mode 100644 src/main/java/hhn/labsw/bugageocaching/repositories/RoleRepository.java create mode 100644 src/main/java/hhn/labsw/bugageocaching/service/SecurityService.java create mode 100644 src/main/java/hhn/labsw/bugageocaching/service/SecurityServiceImpl.java create mode 100644 src/main/java/hhn/labsw/bugageocaching/service/UserDetailsServiceImpl.java create mode 100644 src/main/java/hhn/labsw/bugageocaching/service/UserService.java create mode 100644 src/main/java/hhn/labsw/bugageocaching/service/UserServiceImpl.java diff --git a/build.gradle b/build.gradle index 5724707..26ee00d 100644 --- a/build.gradle +++ b/build.gradle @@ -34,6 +34,13 @@ dependencies { //JSON Parser implementation 'com.google.code.gson:gson:2.8.5' + + compile 'org.springframework.boot:spring-boot-starter-tomcat' + compile 'org.springframework.boot:spring-boot-starter-security' + compile 'org.springframework.boot:spring-boot-starter-actuator' + compile 'org.springframework.boot:spring-boot-starter-aop' + compile group: 'org.springframework.boot', name: 'spring-boot-starter-mail', version: '1.2.0.RELEASE' + } node { diff --git a/src/main/java/hhn/labsw/bugageocaching/Application.java b/src/main/java/hhn/labsw/bugageocaching/Application.java index 8362492..0212443 100644 --- a/src/main/java/hhn/labsw/bugageocaching/Application.java +++ b/src/main/java/hhn/labsw/bugageocaching/Application.java @@ -3,11 +3,18 @@ package hhn.labsw.bugageocaching; 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 { +public class Application{ - public static void main(String[] args) { + /**@Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(Application.class); + }**/ + + public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, args); } } diff --git a/src/main/java/hhn/labsw/bugageocaching/config/WebSecurityConfig.java b/src/main/java/hhn/labsw/bugageocaching/config/WebSecurityConfig.java new file mode 100644 index 0000000..7af8e75 --- /dev/null +++ b/src/main/java/hhn/labsw/bugageocaching/config/WebSecurityConfig.java @@ -0,0 +1,52 @@ +package hhn.labsw.bugageocaching.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +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.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +@Configuration +@EnableWebSecurity +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Qualifier("userDetailsServiceImpl") + @Autowired + private UserDetailsService userDetailsService; + + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .antMatchers("/allCaches").permitAll() + .anyRequest().authenticated() + .and() + .formLogin() + .defaultSuccessUrl("/allCaches") + .permitAll() + .and() + .logout() + .permitAll(); + } + + @Bean + public AuthenticationManager customAuthenticationManager() throws Exception { + return authenticationManager(); + } + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder()); + } +} diff --git a/src/main/java/hhn/labsw/bugageocaching/controller/Controller.java b/src/main/java/hhn/labsw/bugageocaching/controller/Controller.java index c524e99..be59059 100644 --- a/src/main/java/hhn/labsw/bugageocaching/controller/Controller.java +++ b/src/main/java/hhn/labsw/bugageocaching/controller/Controller.java @@ -3,7 +3,14 @@ package hhn.labsw.bugageocaching.controller; import com.google.gson.Gson; import hhn.labsw.bugageocaching.entities.*; import hhn.labsw.bugageocaching.repositories.*; +import hhn.labsw.bugageocaching.service.SecurityService; +import hhn.labsw.bugageocaching.service.UserService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; import java.util.Optional; @@ -32,6 +39,13 @@ public class Controller { @Autowired UserRepository userRepository; + @Autowired + private UserService userService; + + @Autowired + private SecurityService securityService; + + @RequestMapping("/allCaches") @ResponseBody public String getAllCaches(){ @@ -63,4 +77,11 @@ public class Controller { return bearbeitet; } + + @RequestMapping("/securityCheck") + @ResponseBody + public String securityCheck(){ + return "Angemeldet"; + } + } diff --git a/src/main/java/hhn/labsw/bugageocaching/entities/Role.java b/src/main/java/hhn/labsw/bugageocaching/entities/Role.java new file mode 100644 index 0000000..47da1bd --- /dev/null +++ b/src/main/java/hhn/labsw/bugageocaching/entities/Role.java @@ -0,0 +1,44 @@ +package hhn.labsw.bugageocaching.entities; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.ManyToMany; +import java.util.Set; + +@Entity +public class Role { + + @Id + @GeneratedValue + int id; + + private String name; + + @ManyToMany(mappedBy = "roles") + private Set users; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Set getUsers() { + return users; + } + + public void setUsers(Set users) { + this.users = users; + } +} diff --git a/src/main/java/hhn/labsw/bugageocaching/entities/User.java b/src/main/java/hhn/labsw/bugageocaching/entities/User.java index eb0e75d..7c0abe4 100644 --- a/src/main/java/hhn/labsw/bugageocaching/entities/User.java +++ b/src/main/java/hhn/labsw/bugageocaching/entities/User.java @@ -1,6 +1,7 @@ package hhn.labsw.bugageocaching.entities; import javax.persistence.*; +import java.util.Set; @Entity @Table @@ -14,14 +15,18 @@ public class User { private String lastname; private String username; private int rankingPointsSum; - private String discriminator; //should be Admin or Cacher private String email; private String password; - private String salt; @ManyToOne private Team team; + @ManyToMany + Set roles; + + @Transient + private String passwordConfirm; + public int getId() { return id; } @@ -62,14 +67,6 @@ public class User { this.rankingPointsSum = rankingPointsSum; } - public String getDiscriminator() { - return discriminator; - } - - public void setDiscriminator(String discriminator) { - this.discriminator = discriminator; - } - public String getEmail() { return email; } @@ -86,14 +83,6 @@ public class User { this.password = password; } - public String getSalt() { - return salt; - } - - public void setSalt(String salt) { - this.salt = salt; - } - public Team getTeam() { return team; } @@ -101,4 +90,20 @@ public class User { public void setTeam(Team team) { this.team = team; } + + public Set getRoles() { + return roles; + } + + public void setRoles(Set roles) { + this.roles = roles; + } + + public String getPasswordConfirm() { + return passwordConfirm; + } + + public void setPasswordConfirm(String passwordConfirm) { + this.passwordConfirm = passwordConfirm; + } } diff --git a/src/main/java/hhn/labsw/bugageocaching/repositories/BearbeitetRepository.java b/src/main/java/hhn/labsw/bugageocaching/repositories/BearbeitetRepository.java index fb4a270..ac5484c 100644 --- a/src/main/java/hhn/labsw/bugageocaching/repositories/BearbeitetRepository.java +++ b/src/main/java/hhn/labsw/bugageocaching/repositories/BearbeitetRepository.java @@ -1,7 +1,8 @@ package hhn.labsw.bugageocaching.repositories; import hhn.labsw.bugageocaching.entities.Bearbeitet; +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.CrudRepository; -public interface BearbeitetRepository extends CrudRepository { +public interface BearbeitetRepository extends JpaRepository { } diff --git a/src/main/java/hhn/labsw/bugageocaching/repositories/CacheAccesDefinitionRepository.java b/src/main/java/hhn/labsw/bugageocaching/repositories/CacheAccesDefinitionRepository.java index 2a01cab..a807947 100644 --- a/src/main/java/hhn/labsw/bugageocaching/repositories/CacheAccesDefinitionRepository.java +++ b/src/main/java/hhn/labsw/bugageocaching/repositories/CacheAccesDefinitionRepository.java @@ -1,7 +1,8 @@ package hhn.labsw.bugageocaching.repositories; import hhn.labsw.bugageocaching.entities.CacheAccesDefinition; +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.CrudRepository; -public interface CacheAccesDefinitionRepository extends CrudRepository { +public interface CacheAccesDefinitionRepository extends JpaRepository { } diff --git a/src/main/java/hhn/labsw/bugageocaching/repositories/CacheRepository.java b/src/main/java/hhn/labsw/bugageocaching/repositories/CacheRepository.java index b480c64..9ac29b1 100644 --- a/src/main/java/hhn/labsw/bugageocaching/repositories/CacheRepository.java +++ b/src/main/java/hhn/labsw/bugageocaching/repositories/CacheRepository.java @@ -1,7 +1,8 @@ package hhn.labsw.bugageocaching.repositories; import hhn.labsw.bugageocaching.entities.Cache; +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.CrudRepository; -public interface CacheRepository extends CrudRepository { +public interface CacheRepository extends JpaRepository { } diff --git a/src/main/java/hhn/labsw/bugageocaching/repositories/RewardRepository.java b/src/main/java/hhn/labsw/bugageocaching/repositories/RewardRepository.java index ca51b18..0756cec 100644 --- a/src/main/java/hhn/labsw/bugageocaching/repositories/RewardRepository.java +++ b/src/main/java/hhn/labsw/bugageocaching/repositories/RewardRepository.java @@ -1,7 +1,8 @@ package hhn.labsw.bugageocaching.repositories; import hhn.labsw.bugageocaching.entities.Reward; +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.CrudRepository; -public interface RewardRepository extends CrudRepository { +public interface RewardRepository extends JpaRepository { } diff --git a/src/main/java/hhn/labsw/bugageocaching/repositories/RoleRepository.java b/src/main/java/hhn/labsw/bugageocaching/repositories/RoleRepository.java new file mode 100644 index 0000000..b5f8798 --- /dev/null +++ b/src/main/java/hhn/labsw/bugageocaching/repositories/RoleRepository.java @@ -0,0 +1,7 @@ +package hhn.labsw.bugageocaching.repositories; + +import hhn.labsw.bugageocaching.entities.Role; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface RoleRepository extends JpaRepository { +} diff --git a/src/main/java/hhn/labsw/bugageocaching/repositories/StationRepository.java b/src/main/java/hhn/labsw/bugageocaching/repositories/StationRepository.java index c902ec5..146c9bb 100644 --- a/src/main/java/hhn/labsw/bugageocaching/repositories/StationRepository.java +++ b/src/main/java/hhn/labsw/bugageocaching/repositories/StationRepository.java @@ -1,7 +1,8 @@ package hhn.labsw.bugageocaching.repositories; import hhn.labsw.bugageocaching.entities.Station; +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.CrudRepository; -public interface StationRepository extends CrudRepository { +public interface StationRepository extends JpaRepository { } diff --git a/src/main/java/hhn/labsw/bugageocaching/repositories/TeamRepository.java b/src/main/java/hhn/labsw/bugageocaching/repositories/TeamRepository.java index edf1d5d..77c69d9 100644 --- a/src/main/java/hhn/labsw/bugageocaching/repositories/TeamRepository.java +++ b/src/main/java/hhn/labsw/bugageocaching/repositories/TeamRepository.java @@ -1,7 +1,8 @@ package hhn.labsw.bugageocaching.repositories; import hhn.labsw.bugageocaching.entities.Team; +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.CrudRepository; -public interface TeamRepository extends CrudRepository { +public interface TeamRepository extends JpaRepository { } diff --git a/src/main/java/hhn/labsw/bugageocaching/repositories/UserRepository.java b/src/main/java/hhn/labsw/bugageocaching/repositories/UserRepository.java index f899608..a56391e 100644 --- a/src/main/java/hhn/labsw/bugageocaching/repositories/UserRepository.java +++ b/src/main/java/hhn/labsw/bugageocaching/repositories/UserRepository.java @@ -1,7 +1,9 @@ package hhn.labsw.bugageocaching.repositories; import hhn.labsw.bugageocaching.entities.User; +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.CrudRepository; -public interface UserRepository extends CrudRepository { +public interface UserRepository extends JpaRepository { + User findByUsername(String username); } diff --git a/src/main/java/hhn/labsw/bugageocaching/service/SecurityService.java b/src/main/java/hhn/labsw/bugageocaching/service/SecurityService.java new file mode 100644 index 0000000..aed5944 --- /dev/null +++ b/src/main/java/hhn/labsw/bugageocaching/service/SecurityService.java @@ -0,0 +1,8 @@ +package hhn.labsw.bugageocaching.service; + +public interface SecurityService { + + String findLoggedInUsername(); + + void autoLogin(String username, String password); +} diff --git a/src/main/java/hhn/labsw/bugageocaching/service/SecurityServiceImpl.java b/src/main/java/hhn/labsw/bugageocaching/service/SecurityServiceImpl.java new file mode 100644 index 0000000..9bdd3f6 --- /dev/null +++ b/src/main/java/hhn/labsw/bugageocaching/service/SecurityServiceImpl.java @@ -0,0 +1,48 @@ +package hhn.labsw.bugageocaching.service; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.stereotype.Service; + +@Service +public class SecurityServiceImpl implements SecurityService{ + + @Autowired + private AuthenticationManager authenticationManager; + + @Qualifier("userDetailsServiceImpl") + @Autowired + private UserDetailsService userDetailsService; + + private static final Logger logger = LoggerFactory.getLogger(SecurityServiceImpl.class); + + @Override + public String findLoggedInUsername() { + Object userDetails = SecurityContextHolder.getContext().getAuthentication().getDetails(); + if (userDetails instanceof UserDetails) { + return ((UserDetails)userDetails).getUsername(); + } + + return null; + } + + @Override + public void autoLogin(String username, String password) { + UserDetails userDetails = userDetailsService.loadUserByUsername(username); + UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities()); + + authenticationManager.authenticate(usernamePasswordAuthenticationToken); + + if (usernamePasswordAuthenticationToken.isAuthenticated()) { + SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); + logger.debug(String.format("Auto login %s successfully!", username)); + } + } +} diff --git a/src/main/java/hhn/labsw/bugageocaching/service/UserDetailsServiceImpl.java b/src/main/java/hhn/labsw/bugageocaching/service/UserDetailsServiceImpl.java new file mode 100644 index 0000000..c261830 --- /dev/null +++ b/src/main/java/hhn/labsw/bugageocaching/service/UserDetailsServiceImpl.java @@ -0,0 +1,37 @@ +package hhn.labsw.bugageocaching.service; + +import hhn.labsw.bugageocaching.entities.Role; +import hhn.labsw.bugageocaching.entities.User; +import hhn.labsw.bugageocaching.repositories.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashSet; +import java.util.Set; + +@Service +public class UserDetailsServiceImpl implements UserDetailsService { + + @Autowired + private UserRepository userRepository; + + @Override + @Transactional(readOnly = true) + public UserDetails loadUserByUsername(String username) { + User user = userRepository.findByUsername(username); + if (user == null) throw new UsernameNotFoundException(username); + + Set grantedAuthorities = new HashSet<>(); + for (Role role : user.getRoles()){ + grantedAuthorities.add(new SimpleGrantedAuthority(role.getName())); + } + + return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), grantedAuthorities); + } +} diff --git a/src/main/java/hhn/labsw/bugageocaching/service/UserService.java b/src/main/java/hhn/labsw/bugageocaching/service/UserService.java new file mode 100644 index 0000000..e5e1c0b --- /dev/null +++ b/src/main/java/hhn/labsw/bugageocaching/service/UserService.java @@ -0,0 +1,10 @@ +package hhn.labsw.bugageocaching.service; + +import hhn.labsw.bugageocaching.entities.User; + +public interface UserService { + void save(User user); + + User findByUsername(String username); + +} diff --git a/src/main/java/hhn/labsw/bugageocaching/service/UserServiceImpl.java b/src/main/java/hhn/labsw/bugageocaching/service/UserServiceImpl.java new file mode 100644 index 0000000..6374d36 --- /dev/null +++ b/src/main/java/hhn/labsw/bugageocaching/service/UserServiceImpl.java @@ -0,0 +1,33 @@ +package hhn.labsw.bugageocaching.service; + +import hhn.labsw.bugageocaching.entities.User; +import hhn.labsw.bugageocaching.repositories.RoleRepository; +import hhn.labsw.bugageocaching.repositories.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.stereotype.Service; + +import java.util.HashSet; + +@Service +public class UserServiceImpl implements UserService { + + @Autowired + private UserRepository userRepository; + @Autowired + private RoleRepository roleRepository; + @Autowired + private BCryptPasswordEncoder bCryptPasswordEncoder; + + @Override + public void save(User user) { + user.setPassword(bCryptPasswordEncoder.encode(user.getPassword())); + user.setRoles(new HashSet<>(roleRepository.findAll())); + userRepository.save(user); + } + + @Override + public User findByUsername(String username) { + return userRepository.findByUsername(username); + } +}