[EDIT] MODIFICACION EN EL USO DE TOKEN

parent 93e5a4ae
package web.multitask.trismegistoservices.api; package web.multitask.trismegistoservices.api;
import lombok.AllArgsConstructor;
import org.json.JSONObject; import org.json.JSONObject;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
...@@ -13,6 +12,7 @@ import web.multitask.trismegistoservices.utils.JWTokenUtil; ...@@ -13,6 +12,7 @@ import web.multitask.trismegistoservices.utils.JWTokenUtil;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
...@@ -57,7 +57,7 @@ class JWTokenApi { ...@@ -57,7 +57,7 @@ class JWTokenApi {
return ResponseEntity.status(401).body(response.toMap()); return ResponseEntity.status(401).body(response.toMap());
} else { } else {
boolean onelife = json.optBoolean("onelife", false); boolean onelife = json.optBoolean("onelife", false);
String generatedToken = jwtTokenUtil.generateToken((User) userDetails, json.optBigInteger("ms", onelife ? BigInteger.valueOf(0) : BigInteger.valueOf(3600000))); String generatedToken = jwtTokenUtil.generateToken((User) userDetails, json.optBigInteger("ms", onelife ? BigInteger.valueOf(0) : BigInteger.valueOf(3600000)),onelife);
if(onelife){ if(onelife){
tokenSingleton.addToken(generatedToken); tokenSingleton.addToken(generatedToken);
} }
...@@ -74,8 +74,16 @@ class JWTokenApi { ...@@ -74,8 +74,16 @@ class JWTokenApi {
JSONObject json = new JSONObject(token); JSONObject json = new JSONObject(token);
JSONObject response = new JSONObject(); JSONObject response = new JSONObject();
if (!jwtTokenUtil.validateToken(json.getString("token"))) { boolean oneLifeToken = tokenSingleton.isTokenAvailable(json.getString("token"));
response.put("message", "Invalid Token").put("status", false);
if(oneLifeToken){
response.put("message", "1-life Token is still up").put("status", true);
return ResponseEntity.ok(response.toMap());
}
boolean validToken = jwtTokenUtil.validateToken(json.getString("token"));
if (!validToken) {
response.put("message", "This token doesn't exist, it might be created on malicious purposes").put("status", false);
return ResponseEntity.status(401).body(response.toMap()); return ResponseEntity.status(401).body(response.toMap());
} }
...@@ -91,17 +99,6 @@ class JWTokenApi { ...@@ -91,17 +99,6 @@ class JWTokenApi {
return ResponseEntity.status(403).body(response.toMap()); return ResponseEntity.status(403).body(response.toMap());
} }
try {
UserDetails userDetails = userRepo.findByUsername(new JSONObject(dataToken).getString("username"));
if (userDetails == null) {
response.put("message", "Invalid Token").put("status", false);
return ResponseEntity.status(401).body(response.toMap());
}
} catch (Exception e) {
response.put("message", "Invalid Token").put("status", false);
return ResponseEntity.status(401).body(response.toMap());
}
response.put("message", "Valid Token").put("status", true); response.put("message", "Valid Token").put("status", true);
return ResponseEntity.ok(response.toMap()); return ResponseEntity.ok(response.toMap());
} }
...@@ -114,7 +111,7 @@ class JWTokenApi { ...@@ -114,7 +111,7 @@ class JWTokenApi {
return ResponseEntity.status(401).body(new JSONObject().put("token", "").put("message", "Invalid Credentials").put("status", false).toMap()); return ResponseEntity.status(401).body(new JSONObject().put("token", "").put("message", "Invalid Credentials").put("status", false).toMap());
} else if (userDetails.getAuthorities().stream().anyMatch(a -> a.getAuthority().equals("SERVICE"))) { } else if (userDetails.getAuthorities().stream().anyMatch(a -> a.getAuthority().equals("SERVICE"))) {
boolean onelife = json.optBoolean("onelife", false); boolean onelife = json.optBoolean("onelife", false);
String generatedToken = jwtTokenUtil.generateToken((User) userDetails, json.optBigInteger("ms", onelife ? BigInteger.valueOf(0) : BigInteger.valueOf(3600000))); String generatedToken = jwtTokenUtil.generateToken((User) userDetails, json.optBigInteger("ms", onelife ? BigInteger.valueOf(0) : BigInteger.valueOf(3600000)),false);
if(onelife){ if(onelife){
tokenSingleton.addToken(generatedToken); tokenSingleton.addToken(generatedToken);
} }
...@@ -135,4 +132,43 @@ class JWTokenApi { ...@@ -135,4 +132,43 @@ class JWTokenApi {
} }
} }
@PostMapping("/tokenize")
public ResponseEntity<?> tokenize(@RequestBody String data) {
JSONObject json = new JSONObject(data);
try {
boolean onelife = json.optBoolean("onelife", false);
String tokenized = jwtTokenUtil.tokenizeData(data, onelife ? BigInteger.valueOf(0) : BigInteger.valueOf(3600000), onelife);
if(onelife){
tokenSingleton.addToken(tokenized);
}
return ResponseEntity.ok(new JSONObject().put("token", tokenized).put("message", "OK").put("status", true).toMap());
} catch (Exception e) {
return ResponseEntity.status(400).body(new JSONObject().put("token", "").put("message", e.getMessage()).put("status", false).toMap());
}
}
@PostMapping("/detokenize")
public ResponseEntity<?> detokenize(@RequestBody String token) {
JSONObject json = new JSONObject(token);
try {
String detokenized = jwtTokenUtil.detokenizeData(json.getString("token"));
return ResponseEntity.ok(new JSONObject().put("data", detokenized).put("message", "OK").put("status", true).toMap());
} catch (Exception e) {
return ResponseEntity.status(400).body(new JSONObject().put("data", "").put("message", e.getMessage()).put("status", false).toMap());
}
}
@PostMapping("/consume")
public ResponseEntity<?> consumeToken(@RequestBody String token) {
JSONObject json = new JSONObject(token);
try {
if(tokenSingleton.consumeToken(json.getString("token"))){
return ResponseEntity.ok(new JSONObject().put("message", "OK").put("status", true).toMap());
}else{
return ResponseEntity.status(400).body(new JSONObject().put("message", "Invalid Token").put("status", false).toMap());
}
} catch (Exception e) {
return ResponseEntity.status(400).body(new JSONObject().put("message", e.getMessage()).put("status", false).toMap());
}
}
} }
\ No newline at end of file
...@@ -10,7 +10,7 @@ public class MVCConfig ...@@ -10,7 +10,7 @@ public class MVCConfig
implements WebMvcConfigurer { implements WebMvcConfigurer {
@Override @Override
public void addCorsMappings(@NonNull CorsRegistry registry) { public void addCorsMappings(@NonNull CorsRegistry registry) {
// registry.addMapping("/**") registry.addMapping("/**")
// .allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH"); .allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
} }
} }
\ No newline at end of file
...@@ -18,7 +18,6 @@ import org.springframework.web.cors.CorsConfiguration; ...@@ -18,7 +18,6 @@ import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter; import org.springframework.web.filter.CorsFilter;
import web.multitask.trismegistoservices.filter.JWTokenFilter; import web.multitask.trismegistoservices.filter.JWTokenFilter;
import web.multitask.trismegistoservices.repository.UserRepository;
import web.multitask.trismegistoservices.singleton.ThreadLocalSingleton; import web.multitask.trismegistoservices.singleton.ThreadLocalSingleton;
import web.multitask.trismegistoservices.singleton.TokenSingleton; import web.multitask.trismegistoservices.singleton.TokenSingleton;
import web.multitask.trismegistoservices.utils.JWTokenUtil; import web.multitask.trismegistoservices.utils.JWTokenUtil;
...@@ -28,7 +27,6 @@ import web.multitask.trismegistoservices.utils.JWTokenUtil; ...@@ -28,7 +27,6 @@ import web.multitask.trismegistoservices.utils.JWTokenUtil;
@AllArgsConstructor @AllArgsConstructor
public class SecurityConfig{ public class SecurityConfig{
// private final UserRepository userRepo;
private final JWTokenUtil jwtTokenUtil; private final JWTokenUtil jwtTokenUtil;
private final TokenSingleton tokenSingleton; private final TokenSingleton tokenSingleton;
private ThreadLocalSingleton threadLocalSingleton; private ThreadLocalSingleton threadLocalSingleton;
...@@ -60,15 +58,15 @@ public class SecurityConfig{ ...@@ -60,15 +58,15 @@ public class SecurityConfig{
return new BCryptPasswordEncoder(); return new BCryptPasswordEncoder();
} }
// @Bean @Bean
// CorsFilter corsFilter() { CorsFilter corsFilter() {
// UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
// CorsConfiguration config = new CorsConfiguration(); CorsConfiguration config = new CorsConfiguration();
// config.addAllowedOrigin("*"); config.addAllowedOrigin("*");
// config.addAllowedHeader("*"); config.addAllowedHeader("*");
// config.addAllowedMethod("*"); config.addAllowedMethod("*");
// source.registerCorsConfiguration("/**", config); source.registerCorsConfiguration("/**", config);
// return new CorsFilter(source); return new CorsFilter(source);
// } }
} }
\ No newline at end of file
...@@ -21,7 +21,6 @@ public class AuthChannelInterceptorAdapter implements ChannelInterceptor { ...@@ -21,7 +21,6 @@ public class AuthChannelInterceptorAdapter implements ChannelInterceptor {
private final JWTokenUtil jwtTokenUtil; private final JWTokenUtil jwtTokenUtil;
private final UserRepository userRepo = new UserRepository(); private final UserRepository userRepo = new UserRepository();
public AuthChannelInterceptorAdapter(JWTokenUtil jwtTokenUtil) { public AuthChannelInterceptorAdapter(JWTokenUtil jwtTokenUtil) {
this.jwtTokenUtil = jwtTokenUtil; this.jwtTokenUtil = jwtTokenUtil;
} }
......
...@@ -30,13 +30,10 @@ import web.multitask.trismegistoservices.utils.JWTokenUtil; ...@@ -30,13 +30,10 @@ import web.multitask.trismegistoservices.utils.JWTokenUtil;
@Component @Component
@Order(1) @Order(1)
//@AllArgsConstructor //@AllArgsConstructor
//@NoArgsConstructor @NoArgsConstructor
public class JWTokenFilter extends OncePerRequestFilter { public class JWTokenFilter extends OncePerRequestFilter {
public JWTokenFilter(){}
private final UserRepository userRepo = new UserRepository(); private final UserRepository userRepo = new UserRepository();
private JWTokenUtil jwtTokenUtil = null; private JWTokenUtil jwtTokenUtil = null;
private TokenSingleton tokenSingleton = null; private TokenSingleton tokenSingleton = null;
private ThreadLocalSingleton threadLocalSingleton = null; private ThreadLocalSingleton threadLocalSingleton = null;
...@@ -47,7 +44,6 @@ public class JWTokenFilter extends OncePerRequestFilter { ...@@ -47,7 +44,6 @@ public class JWTokenFilter extends OncePerRequestFilter {
this.threadLocalSingleton = threadLocalSingleton; this.threadLocalSingleton = threadLocalSingleton;
} }
@Override @Override
protected void doFilterInternal(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain chain) protected void doFilterInternal(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain chain)
throws ServletException, IOException, java.io.IOException { throws ServletException, IOException, java.io.IOException {
......
package web.multitask.trismegistoservices.repository; package web.multitask.trismegistoservices.repository;
//@Repository
//public interface UserRepository extends JpaRepository<User, Long> {
//
// UserDetails findByUsername(String username)
// throws UsernameNotFoundException;
//
//}
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import web.multitask.trismegistoservices.model.Role; import web.multitask.trismegistoservices.model.Role;
import web.multitask.trismegistoservices.model.User; import web.multitask.trismegistoservices.model.User;
...@@ -38,9 +28,4 @@ public class UserRepository{ ...@@ -38,9 +28,4 @@ public class UserRepository{
return users.get(username); return users.get(username);
} }
public static void main(String[] args) {
UserRepository userRepository = new UserRepository();
System.out.println(userRepository.findByUsername("admin").getAuthorities());
}
} }
\ No newline at end of file
package web.multitask.trismegistoservices.singleton; package web.multitask.trismegistoservices.singleton;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
...@@ -10,6 +11,7 @@ import java.util.stream.IntStream; ...@@ -10,6 +11,7 @@ import java.util.stream.IntStream;
@Getter @Getter
@Component @Component
@NoArgsConstructor
public class TokenSingleton { public class TokenSingleton {
private final JSONArray tokens = new JSONArray(); private final JSONArray tokens = new JSONArray();
...@@ -28,19 +30,27 @@ public class TokenSingleton { ...@@ -28,19 +30,27 @@ public class TokenSingleton {
return isAvailable; return isAvailable;
} }
public boolean isTokenAvailable(String token) {
boolean isAvailable = false;
for (int i = 0; i < tokens.length(); i++) {
if (tokens.getJSONObject(i).getString("token").equals(token)) {
isAvailable = tokens.getJSONObject(i).getBoolean("available");
break;
}
}
return isAvailable;
}
public void addToken(String token) { public void addToken(String token) {
tokens.put(new JSONObject().put("token", token).put("available", true)); tokens.put(new JSONObject().put("token", token).put("available", true));
} }
public TokenSingleton() {
}
@Scheduled(fixedRate = 3600000) @Scheduled(fixedRate = 3600000)
public void removeUnavailableTokens() { public void removeUnavailableTokens() {
System.out.println("Removing unavailable tokens"); System.out.println("Removing unavailable tokens");
IntStream.range(0, tokens.length()).forEach(i -> { IntStream.range(0, tokens.length()).forEach(i -> {
if (!tokens.getJSONObject(i).getBoolean("available")) { if (!tokens.getJSONObject(i).getBoolean("available")) {
tokens.remove(i); System.out.println(tokens.remove(i));
} }
}); });
} }
......
...@@ -2,6 +2,7 @@ package web.multitask.trismegistoservices.utils; ...@@ -2,6 +2,7 @@ package web.multitask.trismegistoservices.utils;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.ExpiredJwtException;
...@@ -12,14 +13,18 @@ import io.jsonwebtoken.Jwts; ...@@ -12,14 +13,18 @@ import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys; import io.jsonwebtoken.security.Keys;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import web.multitask.trismegistoservices.model.User; import web.multitask.trismegistoservices.model.User;
import web.multitask.trismegistoservices.singleton.TokenSingleton;
@Component @Component
public class JWTokenUtil implements Serializable{ public class JWTokenUtil implements Serializable{
@Value("${app.jwtSecret}") @Value("${app.jwtSecret}")
private String jwtSecret; private String jwtSecret;
@Value("${app.jwtSecret2}")
private String jwtSecret2;
TokenSingleton tokenSingleton = new TokenSingleton();
public String generateToken(User user, BigInteger ms,boolean onelife) {
public String generateToken(User user, BigInteger ms) {
if(ms == null){ if(ms == null){
ms = BigInteger.valueOf(3600000); ms = BigInteger.valueOf(3600000);
} }
...@@ -31,17 +36,58 @@ public class JWTokenUtil implements Serializable{ ...@@ -31,17 +36,58 @@ public class JWTokenUtil implements Serializable{
.setSubject(json.toString()) .setSubject(json.toString())
.setIssuedAt(new Date()) .setIssuedAt(new Date())
.setExpiration(expiryDate) .setExpiration(expiryDate)
.signWith(Keys.hmacShaKeyFor(jwtSecret.getBytes())) .signWith(Keys.hmacShaKeyFor(onelife ? jwtSecret2.getBytes() : jwtSecret.getBytes()))
.compact(); .compact();
} }
public String generateDataSource(JSONObject json){ public String tokenizeData(String data, BigInteger ms,boolean onelife){
return Jwts.builder() return Jwts.builder()
.setSubject(data)
.setIssuedAt(new Date())
.setExpiration(new Date(new Date().getTime() + 36000000))
.signWith(Keys.hmacShaKeyFor(onelife ? jwtSecret2.getBytes() : jwtSecret.getBytes()))
.compact();
}
public String detokenizeData(String token){
String tokenReturned = "";
try{
tokenReturned = Jwts.parserBuilder()
.setSigningKey(Keys.hmacShaKeyFor(jwtSecret.getBytes()))
.build()
.parseClaimsJws(token)
.getBody()
.getSubject();
}catch (Exception e){
try{
tokenReturned = Jwts.parserBuilder()
.setSigningKey(Keys.hmacShaKeyFor(jwtSecret2.getBytes()))
.build()
.parseClaimsJws(token)
.getBody()
.getSubject();
}catch (Exception e2){
System.out.println(e2.getMessage());
}
}
return tokenReturned;
}
public String generateDataSource(JSONObject json){
String dataReturned = "";
try{
dataReturned = Jwts.builder()
.setSubject(json.toString()) .setSubject(json.toString())
.setIssuedAt(new Date()) .setIssuedAt(new Date())
.setExpiration(new Date(new Date().getTime() + 36000000)) .setExpiration(new Date(new Date().getTime() + 36000000))
.signWith(Keys.hmacShaKeyFor(jwtSecret.getBytes())) .signWith(Keys.hmacShaKeyFor(jwtSecret.getBytes()))
.compact(); .compact();
}catch (Exception e){
System.out.println(e.getMessage());
}
return dataReturned;
} }
public boolean validateToken(String token) { public boolean validateToken(String token) {
...@@ -52,7 +98,8 @@ public class JWTokenUtil implements Serializable{ ...@@ -52,7 +98,8 @@ public class JWTokenUtil implements Serializable{
.parseClaimsJws(token); .parseClaimsJws(token);
return true; return true;
} catch (Exception e) { } catch (Exception e) {
return false; System.out.println(e.getMessage());
return false;
} }
} }
...@@ -66,22 +113,48 @@ public class JWTokenUtil implements Serializable{ ...@@ -66,22 +113,48 @@ public class JWTokenUtil implements Serializable{
} catch (ExpiredJwtException expiredJwtException) { } catch (ExpiredJwtException expiredJwtException) {
return expiredJwtException.getClaims().getSubject(); return expiredJwtException.getClaims().getSubject();
} catch (Exception e) { } catch (Exception e) {
System.out.println(e.getMessage()); try{
return null; return Jwts.parserBuilder()
.setSigningKey(Keys.hmacShaKeyFor(jwtSecret2.getBytes()))
.build()
.parseClaimsJws(token)
.getBody().getSubject();
}catch (Exception e2){
System.out.println(e2.getMessage());
return null;
}
} }
} }
public boolean isTokenExpired(String token) { public boolean isTokenExpired(String token) {
return Jwts.parserBuilder() try {
.setSigningKey(Keys.hmacShaKeyFor(jwtSecret.getBytes())) Jwts.parserBuilder()
.build() .setSigningKey(Keys.hmacShaKeyFor(jwtSecret.getBytes()))
.parseClaimsJws(token) .build()
.getBody() .parseClaimsJws(token)
.getExpiration() .getBody()
.before(new Date()); .getExpiration()
.before(new Date());
return false;
} catch (Exception e) {
try {
Jwts.parserBuilder()
.setSigningKey(Keys.hmacShaKeyFor(jwtSecret2.getBytes()))
.build()
.parseClaimsJws(token)
.getBody()
.getExpiration()
.before(new Date());
return false;
} catch (Exception e2) {
System.out.println(e2.getMessage());
return true;
}
}
} }
public int getExperyTime(String token){ public int getExperyTime(String token){
try{
return (int) ((Jwts.parserBuilder() return (int) ((Jwts.parserBuilder()
.setSigningKey(Keys.hmacShaKeyFor(jwtSecret.getBytes())) .setSigningKey(Keys.hmacShaKeyFor(jwtSecret.getBytes()))
.build() .build()
...@@ -89,5 +162,19 @@ public class JWTokenUtil implements Serializable{ ...@@ -89,5 +162,19 @@ public class JWTokenUtil implements Serializable{
.getBody() .getBody()
.getExpiration() .getExpiration()
.getTime() - new Date().getTime())); .getTime() - new Date().getTime()));
}catch (Exception e){
try{
return (int) ((Jwts.parserBuilder()
.setSigningKey(Keys.hmacShaKeyFor(jwtSecret2.getBytes()))
.build()
.parseClaimsJws(token)
.getBody()
.getExpiration()
.getTime() - new Date().getTime()));
}catch (Exception e2){
System.out.println(e2.getMessage());
return 0;
}
}
} }
} }
\ No newline at end of file
...@@ -3,10 +3,11 @@ ...@@ -3,10 +3,11 @@
#spring.datasource.password=5vC0$2019$ #spring.datasource.password=5vC0$2019$
#spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver #spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
server.port=8080 server.port=8081
server.address=0.0.0.0 server.address=0.0.0.0
# spring.jpa.show-sql=true # spring.jpa.show-sql=true
app.jwtSecret=9a4f2c8d3b7a1e6f45c8a0b3f267d8b1d4e6f3c8a9d2b5f8e3a9c8b5f6v8a3d9 app.jwtSecret=9a4f2c8d3b7a1e6f45c8a0b3f267d8b1d4e6f3c8a9d2b5f8e3a9c8b5f6v8a3d9
app.jwtSecret2=9a4f2c8d3b7a1e6f45c8a0b3f267d8b1d4e6f3c8a9d2b5f8e3a9c8b5f6v8a3d8
spring.jpa.hibernate.ddl-auto=update spring.jpa.hibernate.ddl-auto=update
spring.security.filter.order=1 spring.security.filter.order=1
spring.servlet.multipart.max-file-size=100MB spring.servlet.multipart.max-file-size=100MB
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment