Skip to content

Commit

Permalink
add configuration for security and jwt validation
Browse files Browse the repository at this point in the history
  • Loading branch information
radoslawdabrowski committed Dec 7, 2020
1 parent 4671bbe commit c094429
Show file tree
Hide file tree
Showing 14 changed files with 277 additions and 9 deletions.
23 changes: 21 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
</parent>

<groupId>online.buildit.commons</groupId>
<artifactId>http-api-common</artifactId>
<artifactId>api-common</artifactId>
<version>0.0.1</version>

<name>http-api-common</name>
<name>api-common</name>
<description>Commons with http resolvers and filters</description>

<properties>
Expand All @@ -31,6 +31,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
Expand Down Expand Up @@ -68,6 +72,21 @@
<artifactId>springdoc-openapi-hateoas</artifactId>
<version>${springdoc-openapi.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.8.0</version>
</dependency>
</dependencies>

<distributionManagement>
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/online/buildit/commons/annotation/Factory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package online.buildit.commons.annotation;

import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.Documented;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Factory {

/**
* Alias for component annotation.
* @return default value
*/
@AliasFor(annotation = Component.class)
String value() default "";

}
24 changes: 24 additions & 0 deletions src/main/java/online/buildit/commons/annotation/Handler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package online.buildit.commons.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Handler {

/**
* Alias for component annotation.
* @return default value
*/
@AliasFor(annotation = Component.class)
String value() default "";

}
24 changes: 24 additions & 0 deletions src/main/java/online/buildit/commons/annotation/Provider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package online.buildit.commons.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Provider {

/**
* Alias for component annotation.
* @return default value
*/
@AliasFor(annotation = Component.class)
String value() default "";

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package online.buildit.commons.enums;
package online.buildit.commons.locale.enums;

public final class Characters {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package online.buildit.commons.exceptions;
package online.buildit.commons.locale.exceptions;

public class AcceptLanguageHeaderIsBlankException extends Exception{

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package online.buildit.commons.filters;
package online.buildit.commons.locale.filters;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import online.buildit.commons.resolvers.CommonLocaleResolver;
import online.buildit.commons.locale.resolvers.CommonLocaleResolver;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package online.buildit.commons.resolvers;
package online.buildit.commons.locale.resolvers;

import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import online.buildit.commons.enums.Characters;
import online.buildit.commons.exceptions.AcceptLanguageHeaderIsBlankException;
import online.buildit.commons.locale.enums.Characters;
import online.buildit.commons.locale.exceptions.AcceptLanguageHeaderIsBlankException;
import org.apache.commons.lang3.LocaleUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/online/buildit/commons/security/UserDetails.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package online.buildit.commons.security;

import java.util.UUID;

public interface UserDetails extends org.springframework.security.core.userdetails.UserDetails {

UUID getUUID();
String getEmail();

@Override
default String getUsername() {
return getEmail();
}

}
47 changes: 47 additions & 0 deletions src/main/java/online/buildit/commons/security/UserPrincipal.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package online.buildit.commons.security;


import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;

@Data
@Builder
@AllArgsConstructor
public class UserPrincipal {

private UUID uuid;
private String email;
private String password;

private Collection<? extends GrantedAuthority> authorities;
private Map<String, Object> attributes;

public static <USER extends UserDetails> UserPrincipal create(final USER user) {
return create(user, Collections.emptyList());
}

/**
* Creating user principal object.
* @param user model user
* @param authorities user's roles
* @return {@link UserPrincipal}
*/
public static <USER extends UserDetails> UserPrincipal create(final USER user,
final List<? extends GrantedAuthority> authorities) {
return UserPrincipal.builder()
.uuid(user.getUUID())
.email(user.getEmail())
.password(user.getPassword())
.authorities(authorities)
.build();
}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package online.buildit.commons.security.configuration;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableConfigurationProperties
@SpringBootApplication
public class SecurityConfiguration {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package online.buildit.commons.security.factory;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "app.security")
public class AuthPropertiesFactory {

private String tokenSecret;
private long tokenExpirationMSec;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package online.buildit.commons.security.providers;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import online.buildit.commons.annotation.Provider;
import online.buildit.commons.security.UserPrincipal;
import online.buildit.commons.security.factory.AuthPropertiesFactory;
import org.springframework.security.core.Authentication;

import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.time.Clock;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.UUID;

/**
* JWT Token Generate.
*/
@Slf4j
@Provider
@RequiredArgsConstructor
public class TokenProvider {

private final AuthPropertiesFactory authPropertiesFactory;

/**
* Generating JWT token.
* @param authentication authentication's data
* @return JWT
*/
public String generate(final Authentication authentication) {
final UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();

return Jwts.builder()
.setSubject(String.valueOf(userPrincipal.getUuid()))
.setIssuedAt(Date.from(ZonedDateTime.now(Clock.systemUTC()).toInstant()))
.setExpiration(
new Date(Date.from(ZonedDateTime.now(Clock.systemUTC()).toInstant()).getTime()
+ authPropertiesFactory.getTokenExpirationMSec())
)
.signWith(getKey())
.compact();
}

/**
* Getting user uuid by token.
* @param token token
* @return user UUID
*/
public UUID getUserIdFromToken(final String token) {
Claims claims = Jwts.parser()
.setSigningKey(getKey())
.parseClaimsJws(token)
.getBody();

return UUID.fromString(claims.getSubject());
}

/**
* JWT Token Validation.
* @param authToken token
* @return true/false
*/
public boolean validateToken(final String authToken) {
Jwts.parser().setSigningKey(getKey()).parseClaimsJws(authToken);
return true;
}

private Key getKey() {
return Keys.hmacShaKeyFor(authPropertiesFactory.getTokenSecret().getBytes(StandardCharsets.UTF_8));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package online.buildit.commons.security.validators;

import java.time.Clock;
import java.time.ZonedDateTime;

public class TokenValidator {

public static boolean validate(final VerificationToken token, final VerificationType verificationType) {
return verificationType.getName().equals(token.getName())
&& ZonedDateTime.now(Clock.systemUTC()).isBefore(token.getExpiresIn());
}
}

0 comments on commit c094429

Please sign in to comment.