Bladeren bron

Spring security

Marcin Jaborski 3 jaren geleden
bovenliggende
commit
b6da3e309e
20 gewijzigde bestanden met toevoegingen van 763 en 3 verwijderingen
  1. 20 0
      IWA/pom.xml
  2. 94 0
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/controllers/AuthRESTController.java
  3. 26 0
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/controllers/ExampleSecurityRESTController.java
  4. 31 0
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/message/request/LoginForm.java
  5. 42 0
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/message/request/SignUpForm.java
  6. 47 0
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/message/response/JwtResponse.java
  7. 18 0
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/message/response/ResponseMessage.java
  8. 40 0
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/model/Role.java
  9. 6 0
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/model/RoleName.java
  10. 67 0
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/model/User.java
  11. 12 0
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/repository/RoleRepository.java
  12. 12 0
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/repository/UserRepository.java
  13. 72 0
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/security/WebSecurityConfig.java
  14. 19 0
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/security/jwt/JwtAuthEntryPoint.java
  15. 57 0
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/security/jwt/JwtAuthTokenFilter.java
  16. 57 0
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/security/jwt/JwtProvider.java
  17. 27 0
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/security/services/UserDetailsServiceImpl.java
  18. 92 0
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/security/services/UserPrinciple.java
  19. 17 3
      IWA/src/main/resources/application.properties
  20. 7 0
      IWA/src/main/resources/data.sql

+ 20 - 0
IWA/pom.xml

@@ -54,6 +54,26 @@
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
         </dependency>
+
+        <!-- spring security -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+
+        <!-- JWT -->
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+            <version>0.9.1</version>
+        </dependency>
+
+        <!-- validation in the model -->
+        <dependency>
+            <groupId>javax.validation</groupId>
+            <artifactId>validation-api</artifactId>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 94 - 0
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/controllers/AuthRESTController.java

@@ -0,0 +1,94 @@
+package pl.dmcs.springbootjsp_iwa.controllers;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.web.bind.annotation.*;
+import pl.dmcs.springbootjsp_iwa.message.request.LoginForm;
+import pl.dmcs.springbootjsp_iwa.message.request.SignUpForm;
+import pl.dmcs.springbootjsp_iwa.message.response.JwtResponse;
+import pl.dmcs.springbootjsp_iwa.message.response.ResponseMessage;
+import pl.dmcs.springbootjsp_iwa.model.Role;
+import pl.dmcs.springbootjsp_iwa.model.RoleName;
+import pl.dmcs.springbootjsp_iwa.model.User;
+import pl.dmcs.springbootjsp_iwa.repository.RoleRepository;
+import pl.dmcs.springbootjsp_iwa.repository.UserRepository;
+import pl.dmcs.springbootjsp_iwa.security.jwt.JwtProvider;
+
+import javax.validation.Valid;
+import java.util.HashSet;
+import java.util.Set;
+
+@RestController
+@CrossOrigin(origins = "http://localhost:4200", maxAge = 3600)
+@RequestMapping("/auth")
+public class AuthRESTController {
+
+    @Autowired
+    AuthenticationManager authenticationManager;
+
+    @Autowired
+    UserRepository userRepository;
+
+    @Autowired
+    RoleRepository roleRepository;
+
+    @Autowired
+    PasswordEncoder passwordEncoder;
+
+    @Autowired
+    JwtProvider jwtProvider;
+
+    @PostMapping("/signin")
+    public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginForm loginRequest) {
+        Authentication authentication = authenticationManager.authenticate(
+                new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
+        SecurityContextHolder.getContext().setAuthentication(authentication);
+
+        String jwt = jwtProvider.generateJwtToken(authentication);
+        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
+
+        return ResponseEntity.ok(new JwtResponse(jwt,userDetails.getUsername(), userDetails.getAuthorities()));
+    }
+
+    @PostMapping("/signup")
+    public ResponseEntity<?> registerUser(@Valid @RequestBody SignUpForm signUpRequest) {
+
+        if (userRepository.existsByUsername(signUpRequest.getUsername())) {
+            return new ResponseEntity<>(new ResponseMessage("Fail -> Username is already taken."), HttpStatus.BAD_REQUEST);
+        }
+
+        // Create user account
+        User user = new User(signUpRequest.getUsername(), passwordEncoder.encode(signUpRequest.getPassword()));
+
+        Set<String> strRoles = signUpRequest.getRole();
+        Set<Role> roles = new HashSet<>();
+
+        strRoles.forEach(role -> {
+            switch (role) {
+                case "admin":
+                    Role adminRole = roleRepository.findByName(RoleName.ROLE_ADMIN)
+                            .orElseThrow(() -> new RuntimeException("Fail -> Cause: Admin Role not found."));
+                    roles.add(adminRole);
+                    break;
+                default:
+                    Role userRole = roleRepository.findByName(RoleName.ROLE_USER)
+                            .orElseThrow(() -> new RuntimeException("Fail -> Cause: User Role not found."));
+                    roles.add(userRole);
+            }
+        });
+
+        user.setRoles(roles);
+        userRepository.save(user);
+
+        return new ResponseEntity<>(new ResponseMessage("User registered successfully."), HttpStatus.OK);
+
+    }
+
+}

+ 26 - 0
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/controllers/ExampleSecurityRESTController.java

@@ -0,0 +1,26 @@
+package pl.dmcs.springbootjsp_iwa.controllers;
+
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@CrossOrigin(origins = "http://localhost:4200", maxAge = 3600)
+@RequestMapping("/exampleSecurity")
+public class ExampleSecurityRESTController {
+
+    @GetMapping("/user")
+    @PreAuthorize("hasRole('USER') or hasRole('ADMIN')")
+    public String userAccess() {
+        return ">>> User Contents!";
+    }
+
+    @GetMapping("/admin")
+    @PreAuthorize("hasRole('ADMIN')")
+    public String adminAccess() {
+        return ">>> Admin Contents";
+    }
+
+}

+ 31 - 0
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/message/request/LoginForm.java

@@ -0,0 +1,31 @@
+package pl.dmcs.springbootjsp_iwa.message.request;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+
+public class LoginForm {
+
+    @NotBlank
+    @Size(min=3, max = 60)
+    private String username;
+
+    @NotBlank
+    @Size(min = 6, max = 40)
+    private String password;
+
+    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;
+    }
+}

+ 42 - 0
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/message/request/SignUpForm.java

@@ -0,0 +1,42 @@
+package pl.dmcs.springbootjsp_iwa.message.request;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+import java.util.Set;
+
+public class SignUpForm {
+
+    @NotBlank
+    @Size(min = 3, max = 50)
+    private String username;
+
+    private Set<String> role;
+
+    @NotBlank
+    @Size(min = 6, max = 40)
+    private String password;
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public Set<String> getRole() {
+        return role;
+    }
+
+    public void setRole(Set<String> role) {
+        this.role = role;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+}

+ 47 - 0
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/message/response/JwtResponse.java

@@ -0,0 +1,47 @@
+package pl.dmcs.springbootjsp_iwa.message.response;
+
+import org.springframework.security.core.GrantedAuthority;
+
+import java.util.Collection;
+
+public class JwtResponse {
+
+    private String token;
+    private String type = "Bearer";
+    private String username;
+    private Collection<? extends GrantedAuthority> authorities;
+
+    public JwtResponse(String token, String username, Collection<? extends GrantedAuthority> authorities) {
+        this.token = token;
+        this.username = username;
+        this.authorities = authorities;
+    }
+
+    public String getAccessToken() {
+        return token;
+    }
+
+    public void setAccessToken(String accessToken) {
+        this.token = accessToken;
+    }
+
+    public String getTokenType() {
+        return type;
+    }
+
+    public void setTokenType(String tokenType) {
+        this.type = tokenType;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+        return authorities;
+    }
+}

+ 18 - 0
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/message/response/ResponseMessage.java

@@ -0,0 +1,18 @@
+package pl.dmcs.springbootjsp_iwa.message.response;
+
+public class ResponseMessage {
+
+    private String message;
+
+    public ResponseMessage(String message) {
+        this.message = message;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+}

+ 40 - 0
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/model/Role.java

@@ -0,0 +1,40 @@
+package pl.dmcs.springbootjsp_iwa.model;
+
+import org.hibernate.annotations.NaturalId;
+
+import javax.persistence.*;
+
+@Entity
+public class Role {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @Enumerated(EnumType.STRING)
+    @NaturalId
+    private RoleName name;
+
+    public Role() {
+    }
+
+    public Role(RoleName name) {
+        this.name = name;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public RoleName getName() {
+        return name;
+    }
+
+    public void setName(RoleName name) {
+        this.name = name;
+    }
+}

+ 6 - 0
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/model/RoleName.java

@@ -0,0 +1,6 @@
+package pl.dmcs.springbootjsp_iwa.model;
+
+public enum RoleName {
+    ROLE_USER,
+    ROLE_ADMIN
+}

+ 67 - 0
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/model/User.java

@@ -0,0 +1,67 @@
+package pl.dmcs.springbootjsp_iwa.model;
+
+import javax.persistence.*;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+import java.util.HashSet;
+import java.util.Set;
+
+@Entity
+@Table(name="users")
+public class User {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @NotBlank
+    @Size(min=3, max = 50)
+    private String username;
+
+    @NotBlank
+    @Size(min=6, max = 100)
+    private String password;
+
+    @ManyToMany(fetch = FetchType.EAGER)
+    private Set<Role> roles = new HashSet<>();
+
+    public User() {
+    }
+
+    public User(@NotBlank @Size(min = 3, max = 50) String username, @NotBlank @Size(min = 6, max = 100) String password) {
+        this.username = username;
+        this.password = password;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    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 Set<Role> getRoles() {
+        return roles;
+    }
+
+    public void setRoles(Set<Role> roles) {
+        this.roles = roles;
+    }
+}

+ 12 - 0
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/repository/RoleRepository.java

@@ -0,0 +1,12 @@
+package pl.dmcs.springbootjsp_iwa.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+import pl.dmcs.springbootjsp_iwa.model.Role;
+import pl.dmcs.springbootjsp_iwa.model.RoleName;
+import java.util.Optional;
+
+@Repository
+public interface RoleRepository extends JpaRepository<Role, Long> {
+    Optional<Role> findByName(RoleName roleName);
+}

+ 12 - 0
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/repository/UserRepository.java

@@ -0,0 +1,12 @@
+package pl.dmcs.springbootjsp_iwa.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+import pl.dmcs.springbootjsp_iwa.model.User;
+import java.util.Optional;
+
+@Repository
+public interface UserRepository extends JpaRepository<User, Long> {
+    Optional<User> findByUsername(String username);
+    Boolean existsByUsername(String username);
+}

+ 72 - 0
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/security/WebSecurityConfig.java

@@ -0,0 +1,72 @@
+package pl.dmcs.springbootjsp_iwa.security;
+
+import org.springframework.beans.factory.annotation.Autowired;
+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.method.configuration.EnableGlobalMethodSecurity;
+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.config.http.SessionCreationPolicy;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+import pl.dmcs.springbootjsp_iwa.security.jwt.JwtAuthEntryPoint;
+import pl.dmcs.springbootjsp_iwa.security.jwt.JwtAuthTokenFilter;
+import pl.dmcs.springbootjsp_iwa.security.services.UserDetailsServiceImpl;
+
+@Configuration
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+
+    @Autowired
+    UserDetailsServiceImpl userDetailsService;
+
+    @Autowired
+    private JwtAuthEntryPoint unauthorizedHandler;
+
+    @Bean
+    public JwtAuthTokenFilter authenticationJwtTokenFilter() {
+        return new JwtAuthTokenFilter();
+    }
+
+    @Override
+    public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
+        authenticationManagerBuilder.userDetailsService(userDetailsService)
+                .passwordEncoder(passwordEncoder());
+    }
+
+    @Bean
+    @Override
+    public AuthenticationManager authenticationManagerBean() throws Exception {
+        return super.authenticationManagerBean();
+    }
+
+    @Bean
+    public PasswordEncoder passwordEncoder() {
+        return new BCryptPasswordEncoder();
+    }
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        http.cors().and().csrf().disable().
+                authorizeRequests()
+                .antMatchers("/auth/**").permitAll()
+                // next line for secured app
+                //.antMatchers("/restApi/students/**").hasAnyRole("ADMIN","USER") //hasRole("ADMIN")
+                // next app for not secured version (lecture with REST)
+                .antMatchers("/students/**").permitAll()
+                .antMatchers("/exampleSecurity/user").hasRole("USER")
+                .antMatchers("/exampleSecurity/admin").hasRole("ADMIN")
+                .anyRequest().authenticated()
+                .and()
+                .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
+                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
+
+        http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
+
+    }
+}

+ 19 - 0
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/security/jwt/JwtAuthEntryPoint.java

@@ -0,0 +1,19 @@
+package pl.dmcs.springbootjsp_iwa.security.jwt;
+
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.AuthenticationEntryPoint;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+@Component
+public class JwtAuthEntryPoint implements AuthenticationEntryPoint {
+
+    @Override
+    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
+        httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Error -> Unauthorized");
+    }
+}

+ 57 - 0
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/security/jwt/JwtAuthTokenFilter.java

@@ -0,0 +1,57 @@
+package pl.dmcs.springbootjsp_iwa.security.jwt;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
+import org.springframework.web.filter.OncePerRequestFilter;
+import pl.dmcs.springbootjsp_iwa.security.services.UserDetailsServiceImpl;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+public class JwtAuthTokenFilter extends OncePerRequestFilter {
+
+    @Autowired
+    private JwtProvider tokenProvider;
+
+    @Autowired
+    private UserDetailsServiceImpl userDetailsService;
+
+    @Override
+    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
+        try {
+
+            String jwt = getJwt(httpServletRequest);
+            if (jwt != null && tokenProvider.validateJwtToken(jwt)) {
+                String username = tokenProvider.getUserNameFromJwtToken(jwt);
+
+                UserDetails userDetails = userDetailsService.loadUserByUsername(username);
+                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
+                        userDetails, null, userDetails.getAuthorities());
+                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
+
+                SecurityContextHolder.getContext().setAuthentication(authentication);
+            }
+        } catch (Exception e) {
+            logger.error("Can NOT set user authentication -> Message: {}", e);
+        }
+
+        filterChain.doFilter(httpServletRequest, httpServletResponse);
+    }
+
+    private String getJwt(HttpServletRequest request) {
+        String authHeader = request.getHeader("Authorization");
+
+        if (authHeader != null && authHeader.startsWith("Bearer ")) {
+            return authHeader.replace("Bearer ", "");
+        }
+
+        return null;
+    }
+
+}

+ 57 - 0
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/security/jwt/JwtProvider.java

@@ -0,0 +1,57 @@
+package pl.dmcs.springbootjsp_iwa.security.jwt;
+
+import io.jsonwebtoken.*;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.security.core.Authentication;
+import org.springframework.stereotype.Component;
+import pl.dmcs.springbootjsp_iwa.security.services.UserPrinciple;
+
+import java.util.Date;
+
+@Component
+public class JwtProvider {
+
+    @Value("${pl.dmcs.rkotas.jwtSecret}")
+    private String jwtSecret;
+
+    @Value("${pl.dmcs.rkotas.jwtExpiration}")
+    private int jwtExpiration;
+
+    public String generateJwtToken(Authentication authentication) {
+        UserPrinciple userPrinciple = (UserPrinciple) authentication.getPrincipal();
+
+        return Jwts.builder()
+                .setSubject(userPrinciple.getUsername())
+                .setIssuedAt(new Date())
+                .setExpiration(new Date((new Date()).getTime() + jwtExpiration*1000))
+                .signWith(SignatureAlgorithm.HS512, jwtSecret)
+                .compact();
+    }
+
+    public boolean validateJwtToken(String authToken) {
+        try {
+            Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
+            return true;
+        } catch (SignatureException e) {
+            System.out.println("Invalid JWT signature -> Message: {} " + e);
+        } catch (MalformedJwtException e) {
+            System.out.println("Invalid JWT token -> Message: {}" + e);
+        } catch (ExpiredJwtException e) {
+            System.out.println("Expired JWT token -> Message: {}" + e);
+        } catch (UnsupportedJwtException e) {
+            System.out.println("Unsupported JWT token -> Message: {}" + e);
+        } catch (IllegalArgumentException e) {
+            System.out.println("JWT claims string is empty -> Message: {}" + e);
+        }
+
+        return false;
+    }
+
+    public String getUserNameFromJwtToken(String token) {
+        return Jwts.parser()
+                .setSigningKey(jwtSecret)
+                .parseClaimsJws(token)
+                .getBody().getSubject();
+    }
+
+}

+ 27 - 0
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/security/services/UserDetailsServiceImpl.java

@@ -0,0 +1,27 @@
+package pl.dmcs.springbootjsp_iwa.security.services;
+
+import org.springframework.beans.factory.annotation.Autowired;
+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 pl.dmcs.springbootjsp_iwa.model.User;
+import pl.dmcs.springbootjsp_iwa.repository.UserRepository;
+
+@Service
+public class UserDetailsServiceImpl  implements UserDetailsService {
+
+    @Autowired
+    UserRepository userRepository;
+
+    @Override
+    @Transactional
+    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+
+        User user = userRepository.findByUsername(username).orElseThrow(
+                () -> new UsernameNotFoundException("User Not Found with -> username: " + username));
+        return UserPrinciple.build(user);
+    }
+
+}

+ 92 - 0
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/security/services/UserPrinciple.java

@@ -0,0 +1,92 @@
+package pl.dmcs.springbootjsp_iwa.security.services;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import pl.dmcs.springbootjsp_iwa.model.User;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+public class UserPrinciple implements UserDetails {
+
+    private Long id;
+
+    private String username;
+
+    @JsonIgnore
+    private String password;
+
+    private Collection<? extends GrantedAuthority> authorities;
+
+    public UserPrinciple(Long id, String username, String password, Collection<? extends GrantedAuthority> authorities) {
+        this.id = id;
+        this.username = username;
+        this.password = password;
+        this.authorities = authorities;
+    }
+
+    public static UserPrinciple build(User user) {
+        List<GrantedAuthority> authorities = user.getRoles().stream().map(role ->
+                new SimpleGrantedAuthority(role.getName().name())
+        ).collect(Collectors.toList());
+
+        return new UserPrinciple(
+                user.getId(),
+                user.getUsername(),
+                user.getPassword(),
+                authorities
+        );
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    @Override
+    public String getUsername() {
+        return username;
+    }
+
+    @Override
+    public String getPassword() {
+        return password;
+    }
+
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+        return authorities;
+    }
+
+    @Override
+    public boolean isAccountNonExpired() {
+        return true;
+    }
+
+    @Override
+    public boolean isAccountNonLocked() {
+        return true;
+    }
+
+    @Override
+    public boolean isCredentialsNonExpired() {
+        return true;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return true;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj == null || getClass() != obj.getClass()) return false;
+
+        UserPrinciple user = (UserPrinciple) obj;
+        return Objects.equals(id, user.id);
+    }
+}

+ 17 - 3
IWA/src/main/resources/application.properties

@@ -8,12 +8,26 @@ spring.datasource.password=admin
 spring.datasource.testWhileIdle = true
 spring.datasource.validateQuery = SELECT 1
 
-spring.jpa.show-sql=true
+# IMPORTANT: to use data.sql file has to be uncommented
+spring.sql.init.mode = always
 
-spring.jpa.hibernate.ddl-auto=update
+# Show or not log for each sql query
+spring.jpa.show-sql = true
 
+# Hibernate ddl auto (create, create-drop, update)
+spring.jpa.hibernate.ddl-auto = update
+
+# Naming strategy
 spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
 
+# Use spring.jpa.properties.* for Hibernate native properties (the prefix is
+# stripped before adding them to the entity manager)
+
+# The SQL dialect makes Hibernate generate better SQL for the chosen database
 spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
 
-spring.jpa.properties.hibernate.jdbc.lab.non_contextual_creation = true
+# Fix Postgres JPA Error (Method org.postgresql.jdbc.PgConnection.createClob() is not yet implemented).
+spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
+
+pl.dmcs.rkotas.jwtSecret = jwtSecretKey
+pl.dmcs.rkotas.jwtExpiration = 3600

+ 7 - 0
IWA/src/main/resources/data.sql

@@ -0,0 +1,7 @@
+-- to insert only if table is empty
+INSERT INTO role (name) SELECT 'ROLE_ADMIN' WHERE NOT EXISTS (SELECT * FROM role WHERE role.name='ROLE_ADMIN');
+INSERT INTO role (name) SELECT 'ROLE_USER' WHERE NOT EXISTS (SELECT * FROM role WHERE role.name='ROLE_USER');
+
+-- FROM role;
+--INSERT INTO role (name) VALUES ('ROLE_ADMIN');
+--INSERT INTO role (name) VALUES ('ROLE_USER');