mirror of
https://github.com/fabioformosa/quartz-manager.git
synced 2026-01-04 00:23:19 +09:00
#78 put a secureRandom value as default value for the JWT token
This commit is contained in:
@@ -3,17 +3,28 @@ package it.fabioformosa.quartzmanager.api.security.properties;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Base64;
|
||||
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "quartz-manager.security.jwt")
|
||||
@Getter
|
||||
@Setter
|
||||
public class JwtSecurityProperties {
|
||||
private String secret = RandomStringUtils.randomAlphabetic(10);
|
||||
private String secret;
|
||||
|
||||
{
|
||||
SecureRandom random = new SecureRandom();
|
||||
byte[] bytes = new byte[20];
|
||||
random.nextBytes(bytes);
|
||||
Base64.Encoder encoder = Base64.getUrlEncoder().withoutPadding();
|
||||
secret = encoder.encodeToString(bytes);
|
||||
}
|
||||
|
||||
private long expirationInSec = 28800;
|
||||
|
||||
private CookieStrategy cookieStrategy = new CookieStrategy();
|
||||
|
||||
@@ -2,6 +2,8 @@ package it.fabioformosa.quartzmanager.api.security;
|
||||
|
||||
import it.fabioformosa.quartzmanager.api.common.config.QuartzManagerPaths;
|
||||
import it.fabioformosa.quartzmanager.api.security.controllers.TestController;
|
||||
import it.fabioformosa.quartzmanager.api.security.properties.JwtSecurityProperties;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.hamcrest.core.IsNot;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
@@ -19,9 +21,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
@TestPropertySource(properties = {
|
||||
"quartz-manager.security.jwt.enabled=true",
|
||||
"quartz-manager.security.jwt.secret=bibidibobidiboo",
|
||||
"quartz-manager.security.jwt.expiration-in-sec=28800",
|
||||
"quartz-manager.security.jwt.expiration-in-sec=36000",
|
||||
"quartz-manager.security.jwt.header-strategy.enabled=false",
|
||||
"quartz-manager.security.jwt.header-strategy.header=Authorization",
|
||||
"quartz-manager.security.jwt.cookie-strategy.enabled=true",
|
||||
@@ -36,6 +37,9 @@ class SecurityControllerTest {
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Autowired
|
||||
private JwtSecurityProperties jwtSecurityProperties;
|
||||
|
||||
@Test
|
||||
void givenAnAnonymousUser_whenCalledADMZController_thenShouldRaiseForbidden() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/dmz"))
|
||||
@@ -72,4 +76,10 @@ class SecurityControllerTest {
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenSecurityProps_whenTheBootstrapHasCompleted_thenJWTPropertiesShouldBeSetAccordingly() throws Exception {
|
||||
Assertions.assertThat(jwtSecurityProperties.getExpirationInSec()).isEqualTo(36000);
|
||||
Assertions.assertThat(jwtSecurityProperties.getSecret()).isEqualTo("bibidibobidiboo");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ import org.springframework.test.context.TestPropertySource;
|
||||
@TestPropertySource(properties = {
|
||||
"quartz-manager.security.login-model.form-login-enabled = false",
|
||||
"quartz-manager.security.login-model.userpwd-filter-enabled = true",
|
||||
"quartz-manager.security.jwt.enabled=true",
|
||||
"quartz-manager.security.jwt.secret=bibidibobidiboo",
|
||||
"quartz-manager.security.jwt.expiration-in-sec=28800",
|
||||
"quartz-manager.security.jwt.header-strategy.enabled=true",
|
||||
|
||||
@@ -12,7 +12,6 @@ import org.springframework.test.context.TestPropertySource;
|
||||
@TestPropertySource(properties = {
|
||||
"quartz-manager.security.login-model.form-login-enabled = true",
|
||||
"quartz-manager.security.login-model.userpwd-filter-enabled = false",
|
||||
"quartz-manager.security.jwt.enabled=true",
|
||||
"quartz-manager.security.jwt.secret=bibidibobidiboo",
|
||||
"quartz-manager.security.jwt.expiration-in-sec=28800",
|
||||
"quartz-manager.security.jwt.header-strategy.enabled=true",
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package it.fabioformosa.quartzmanager.api.security.properties;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.springframework.boot.context.properties.bind.BindResult;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
|
||||
import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
|
||||
|
||||
import javax.validation.Validation;
|
||||
import javax.validation.Validator;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Map;
|
||||
|
||||
public class AbstractPropertyValidatorTest {
|
||||
protected static Validator propertyValidator;
|
||||
|
||||
@BeforeAll
|
||||
public static void setup() {
|
||||
propertyValidator = Validation.buildDefaultValidatorFactory().getValidator();
|
||||
}
|
||||
|
||||
protected static <T> T inflateConfigurationPropertyFromAMap(Map<String, String> properties, String configurationPropName, Class<T> propClass) {
|
||||
ConfigurationPropertySource source = new MapConfigurationPropertySource(properties);
|
||||
Binder binder = new Binder(source);
|
||||
BindResult<T> result = binder.bind(configurationPropName, propClass);
|
||||
if (properties != null && !properties.isEmpty()) {
|
||||
Assertions.assertThat(result.isBound()).isTrue();
|
||||
T configPropObject = result.get();
|
||||
return configPropObject;
|
||||
} else {
|
||||
try {
|
||||
return propClass.getConstructor().newInstance();
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,16 @@
|
||||
package it.fabioformosa.quartzmanager.api.security.properties;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.springframework.boot.context.properties.bind.BindResult;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
|
||||
import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
|
||||
|
||||
import javax.validation.Validation;
|
||||
import javax.validation.Validator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class InMemoryUsersValidationControllerTest {
|
||||
|
||||
private static Validator propertyValidator;
|
||||
public class InMemoryUsersValidationControllerTest extends AbstractPropertyValidatorTest {
|
||||
|
||||
static Stream<Arguments> notValidInMemoryProps = Stream.of(
|
||||
Arguments.of(
|
||||
@@ -34,26 +25,15 @@ public class InMemoryUsersValidationControllerTest {
|
||||
);
|
||||
|
||||
|
||||
@BeforeAll
|
||||
public static void setup() {
|
||||
propertyValidator = Validation.buildDefaultValidatorFactory().getValidator();
|
||||
}
|
||||
|
||||
static Stream<Arguments> getNotValidInMemoryProps(){
|
||||
static Stream<Arguments> getNotValidInMemoryProps() {
|
||||
return notValidInMemoryProps;
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("it.fabioformosa.quartzmanager.api.security.properties.InMemoryUsersValidationControllerTest#getNotValidInMemoryProps")
|
||||
void givenAMissingUsername_whenThePropertyValidationIsApplied_thenShouldRaiseValidationError(Map<String, String> properties) {
|
||||
ConfigurationPropertySource source = new MapConfigurationPropertySource(properties);
|
||||
|
||||
Binder binder = new Binder(source);
|
||||
BindResult<InMemoryAccountProperties> result = binder.bind("quartz-manager.security.accounts.in-memory", InMemoryAccountProperties.class);
|
||||
|
||||
Assertions.assertThat(result.isBound()).isTrue();
|
||||
|
||||
InMemoryAccountProperties inMemoryAccountProperties = result.get();
|
||||
InMemoryAccountProperties inMemoryAccountProperties = inflateConfigurationPropertyFromAMap(properties,
|
||||
"quartz-manager.security.accounts.in-memory", InMemoryAccountProperties.class);
|
||||
Assertions.assertThat(propertyValidator.validate(inMemoryAccountProperties)).isNotEmpty();
|
||||
|
||||
}
|
||||
@@ -65,14 +45,9 @@ public class InMemoryUsersValidationControllerTest {
|
||||
properties.put("quartz-manager.security.accounts.in-memory.users[0].password", "bar");
|
||||
properties.put("quartz-manager.security.accounts.in-memory.users[0].roles[0]", "admin");
|
||||
|
||||
ConfigurationPropertySource source = new MapConfigurationPropertySource(properties);
|
||||
InMemoryAccountProperties inMemoryAccountProperties = inflateConfigurationPropertyFromAMap(properties,
|
||||
"quartz-manager.security.accounts.in-memory", InMemoryAccountProperties.class);
|
||||
|
||||
Binder binder = new Binder(source);
|
||||
BindResult<InMemoryAccountProperties> result = binder.bind("quartz-manager.security.accounts.in-memory", InMemoryAccountProperties.class);
|
||||
|
||||
Assertions.assertThat(result.isBound()).isTrue();
|
||||
|
||||
InMemoryAccountProperties inMemoryAccountProperties = result.get();
|
||||
Assertions.assertThat(propertyValidator.validate(inMemoryAccountProperties)).isEmpty();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package it.fabioformosa.quartzmanager.api.security.properties;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
class JwtSecurityPropertiesTest extends AbstractPropertyValidatorTest {
|
||||
|
||||
@Test
|
||||
void givenAllJWTSecurityPropSet_whenThePropertyValidationIsApplied_thenShouldBeValid() {
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
String secret = "helloworld";
|
||||
properties.put("quartz-manager.security.jwt.secret", secret);
|
||||
String expirationInSec = "36000";
|
||||
properties.put("quartz-manager.security.jwt.expirationInSec", expirationInSec);
|
||||
|
||||
JwtSecurityProperties jwtSecurityProperties = inflateConfigurationPropertyFromAMap(properties,
|
||||
"quartz-manager.security.jwt", JwtSecurityProperties.class);
|
||||
|
||||
Assertions.assertThat(propertyValidator.validate(jwtSecurityProperties)).isEmpty();
|
||||
|
||||
Assertions.assertThat(jwtSecurityProperties.getExpirationInSec()).isEqualTo(Long.valueOf(expirationInSec));
|
||||
Assertions.assertThat(jwtSecurityProperties.getSecret()).isEqualTo(secret);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenTheMandatoryJWTSecurityPropUnset_whenThePropertyValidationIsApplied_thenShouldBeSetWithDefault() {
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
|
||||
JwtSecurityProperties jwtSecurityProperties = inflateConfigurationPropertyFromAMap(properties,
|
||||
"quartz-manager.security.jwt", JwtSecurityProperties.class);
|
||||
|
||||
Assertions.assertThat(jwtSecurityProperties.getExpirationInSec()).isEqualTo(28800L);
|
||||
Assertions.assertThat(jwtSecurityProperties.getSecret()).isNotBlank();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user