-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat (Add AuthSecurity): token JWT Auth Spring
Add token based authentication. For be able to POST, PUT and DELETE it necessary be autheticated. First get the JWT token then use the token for requests.
- Loading branch information
SAMUEL BRISTOT LOLI
committed
May 15, 2022
1 parent
1869ba3
commit c17735e
Showing
29 changed files
with
528 additions
and
16 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
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
35 changes: 35 additions & 0 deletions
35
src/main/java/com/samuelapp/demoshop/config/ValidationHandler.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,35 @@ | ||
package com.samuelapp.demoshop.config; | ||
|
||
import com.samuelapp.demoshop.model.dto.FormErrorDto; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.context.MessageSource; | ||
import org.springframework.context.i18n.LocaleContextHolder; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.validation.FieldError; | ||
import org.springframework.web.bind.MethodArgumentNotValidException; | ||
import org.springframework.web.bind.annotation.ExceptionHandler; | ||
import org.springframework.web.bind.annotation.ResponseStatus; | ||
import org.springframework.web.bind.annotation.RestControllerAdvice; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
@RestControllerAdvice | ||
public class ValidationHandler { | ||
|
||
@Autowired | ||
private MessageSource messageSource; | ||
|
||
@ResponseStatus(HttpStatus.BAD_REQUEST) | ||
@ExceptionHandler(MethodArgumentNotValidException.class) | ||
public List<FormErrorDto> handle(MethodArgumentNotValidException exception) { | ||
List<FormErrorDto> dto = new ArrayList<>(); | ||
List<FieldError> fieldErrors = exception.getBindingResult().getFieldErrors(); | ||
fieldErrors.forEach(e -> { | ||
String message = messageSource.getMessage(e, LocaleContextHolder.getLocale()); | ||
FormErrorDto error = new FormErrorDto(message, e.getField()); | ||
dto.add(error); | ||
}); | ||
return dto; | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
src/main/java/com/samuelapp/demoshop/config/security/AuthenticationService.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,20 @@ | ||
package com.samuelapp.demoshop.config.security; | ||
|
||
import com.samuelapp.demoshop.model.User; | ||
import com.samuelapp.demoshop.repository.UserRepository; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.security.core.userdetails.UserDetailsService; | ||
import org.springframework.security.core.userdetails.UsernameNotFoundException; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
public class AuthenticationService implements UserDetailsService { | ||
|
||
@Autowired | ||
UserRepository userRepository; | ||
|
||
@Override | ||
public User loadUserByUsername(String username) throws UsernameNotFoundException { | ||
return userRepository.findByEmail(username).orElseThrow(()->new UsernameNotFoundException("User not found")); | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
src/main/java/com/samuelapp/demoshop/config/security/SecurityConfiguration.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,58 @@ | ||
package com.samuelapp.demoshop.config.security; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.http.HttpMethod; | ||
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.builders.WebSecurity; | ||
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.web.authentication.UsernamePasswordAuthenticationFilter; | ||
|
||
@EnableWebSecurity | ||
@Configuration | ||
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { | ||
|
||
@Autowired | ||
private AuthenticationService authenticationService; | ||
|
||
@Autowired | ||
private TokenService tokenService; | ||
|
||
//Config about Authentication | ||
@Override | ||
protected void configure(AuthenticationManagerBuilder auth) throws Exception { | ||
auth.userDetailsService(authenticationService).passwordEncoder(new BCryptPasswordEncoder()); | ||
} | ||
|
||
@Override | ||
@Bean | ||
protected AuthenticationManager authenticationManager() throws Exception { | ||
return super.authenticationManager(); | ||
} | ||
|
||
//Config about Authorization | ||
@Override | ||
protected void configure(HttpSecurity http) throws Exception { | ||
http.headers().disable().csrf().disable().authorizeRequests() | ||
.antMatchers(HttpMethod.GET,"/").permitAll() | ||
.antMatchers(HttpMethod.GET,"/swagger-ui/**").permitAll() | ||
.antMatchers(HttpMethod.GET,"swagger-ui/index.html").permitAll() | ||
.antMatchers(HttpMethod.POST,"/auth").permitAll() | ||
.antMatchers(HttpMethod.GET,"/employees/**").permitAll() | ||
.antMatchers(HttpMethod.GET, "/h2-console/**").permitAll() | ||
.anyRequest().authenticated() | ||
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) | ||
.and().addFilterBefore(new TokenAuthFilter(tokenService), UsernamePasswordAuthenticationFilter.class); | ||
} | ||
|
||
//Config about static resources (js, css, images..) | ||
@Override | ||
public void configure(WebSecurity web) throws Exception { | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
src/main/java/com/samuelapp/demoshop/config/security/TokenAuthFilter.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,36 @@ | ||
package com.samuelapp.demoshop.config.security; | ||
|
||
import com.samuelapp.demoshop.config.security.TokenService; | ||
import org.springframework.web.filter.OncePerRequestFilter; | ||
|
||
import javax.servlet.FilterChain; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
import java.io.IOException; | ||
|
||
public class TokenAuthFilter extends OncePerRequestFilter { | ||
|
||
private TokenService tokenService; | ||
|
||
public TokenAuthFilter(TokenService tokenService) { | ||
this.tokenService = tokenService; | ||
} | ||
|
||
@Override | ||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { | ||
String token = getTokenRequest(request); | ||
if (tokenService.ValidateToken(token)) | ||
tokenService.authenticateToken(token); | ||
filterChain.doFilter(request,response); | ||
} | ||
|
||
private String getTokenRequest(HttpServletRequest request) { | ||
String token = request.getHeader("Authorization"); | ||
if (token==null || token.isEmpty() || !token.startsWith("Bearer ")){ | ||
return null; | ||
} | ||
return token.substring(7, token.length()); | ||
} | ||
|
||
} |
59 changes: 59 additions & 0 deletions
59
src/main/java/com/samuelapp/demoshop/config/security/TokenService.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,59 @@ | ||
package com.samuelapp.demoshop.config.security; | ||
|
||
import com.samuelapp.demoshop.model.User; | ||
import com.samuelapp.demoshop.repository.UserRepository; | ||
import io.jsonwebtoken.*; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.beans.factory.annotation.Value; | ||
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.UsernameNotFoundException; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.Date; | ||
import java.util.Optional; | ||
|
||
@Service | ||
public class TokenService { | ||
|
||
@Value("${demoshop.jwt.expiration}") | ||
private String expiration; | ||
|
||
@Value("${demoshop.jwt.secret}") | ||
private String secret; | ||
|
||
@Autowired | ||
UserRepository userRepository; | ||
|
||
public String buildToken(Authentication authenticate) { | ||
User user = (User) authenticate.getPrincipal(); | ||
Date today = new Date(); | ||
Date expirationDate = new Date(today.getTime()+Long.parseLong(expiration)); | ||
|
||
return Jwts.builder() | ||
.setIssuer("API demoShop") | ||
.setSubject(String.valueOf(user.getId())) | ||
.setIssuedAt(today) | ||
.setExpiration(expirationDate) | ||
.signWith(SignatureAlgorithm.HS256,secret) | ||
.compact(); | ||
} | ||
|
||
public Boolean ValidateToken(String token) { | ||
try { | ||
Jwts.parser().setSigningKey(secret).parseClaimsJws(token); | ||
return true; | ||
} catch (Exception e) { | ||
return false; | ||
} | ||
} | ||
|
||
public void authenticateToken(String token) { | ||
Claims body = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody(); | ||
Optional<User> optionalUser = userRepository.findById(Integer.valueOf(body.getSubject())); | ||
User user = optionalUser.orElseThrow(()-> new UsernameNotFoundException("User not found")); | ||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(user,null,user.getAuthorities()); | ||
SecurityContextHolder.getContext().setAuthentication(authentication); | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
src/main/java/com/samuelapp/demoshop/controler/AuthController.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,27 @@ | ||
package com.samuelapp.demoshop.controler; | ||
|
||
import com.samuelapp.demoshop.model.dto.LoginDto; | ||
import com.samuelapp.demoshop.model.dto.TokenDto; | ||
import com.samuelapp.demoshop.service.AuthService; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import javax.validation.Valid; | ||
|
||
@RestController | ||
@RequestMapping("/auth") | ||
public class AuthController { | ||
|
||
@Autowired | ||
AuthService authService; | ||
|
||
@PostMapping | ||
public ResponseEntity<TokenDto> authenticate(@RequestBody @Valid LoginDto loginDto){ | ||
TokenDto token = authService.Authenticate(loginDto); | ||
return ResponseEntity.ok(token); | ||
} | ||
} |
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
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,30 @@ | ||
package com.samuelapp.demoshop.model; | ||
|
||
import lombok.EqualsAndHashCode; | ||
import lombok.Getter; | ||
import lombok.Setter; | ||
import org.springframework.security.core.GrantedAuthority; | ||
|
||
import javax.persistence.*; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
|
||
@Entity(name = "role") | ||
@Getter | ||
@Setter | ||
public class Role implements GrantedAuthority { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private int id; | ||
|
||
private String name; | ||
|
||
@ManyToMany(mappedBy = "roles") | ||
private Set<User> users = new HashSet<User>(); | ||
|
||
@Override | ||
public String getAuthority() { | ||
return name; | ||
} | ||
} |
Oops, something went wrong.