Merge remote-tracking branch 'airsonic/pr/1037'
This commit is contained in:
@@ -33,6 +33,8 @@ public class GlobalSecurityConfig extends GlobalAuthenticationConfigurerAdapter
|
|||||||
|
|
||||||
static final String FAILURE_URL = "/login?error=1";
|
static final String FAILURE_URL = "/login?error=1";
|
||||||
|
|
||||||
|
static final String DEVELOPMENT_REMEMBER_ME_KEY = "airsonic";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SecurityService securityService;
|
private SecurityService securityService;
|
||||||
|
|
||||||
@@ -125,6 +127,32 @@ public class GlobalSecurityConfig extends GlobalAuthenticationConfigurerAdapter
|
|||||||
restAuthenticationFilter.setEventPublisher(eventPublisher);
|
restAuthenticationFilter.setEventPublisher(eventPublisher);
|
||||||
http = http.addFilterBefore(restAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
|
http = http.addFilterBefore(restAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
|
||||||
|
|
||||||
|
// Try to load the 'remember me' key.
|
||||||
|
//
|
||||||
|
// Note that using a fixed key compromises security as perfect
|
||||||
|
// forward secrecy is not guaranteed anymore.
|
||||||
|
//
|
||||||
|
// An external entity can then re-use our authentication cookies before
|
||||||
|
// the expiration time, or even, given enough time, recover the password
|
||||||
|
// from the MD5 hash.
|
||||||
|
//
|
||||||
|
// See: https://docs.spring.io/spring-security/site/docs/3.0.x/reference/remember-me.html
|
||||||
|
|
||||||
|
String rememberMeKey = settingsService.getRememberMeKey();
|
||||||
|
boolean development = settingsService.isDevelopmentMode();
|
||||||
|
if (StringUtils.isBlank(rememberMeKey) && !development) {
|
||||||
|
// ...if it is empty, generate a random key on startup (default).
|
||||||
|
logger.debug("Generating a new ephemeral 'remember me' key in a secure way.");
|
||||||
|
rememberMeKey = generateRememberMeKey();
|
||||||
|
} else if (StringUtils.isBlank(rememberMeKey) && development) {
|
||||||
|
// ...if we are in development mode, we can use a fixed key.
|
||||||
|
logger.warn("Using a fixed 'remember me' key because we're in development mode, this is INSECURE.");
|
||||||
|
rememberMeKey = DEVELOPMENT_REMEMBER_ME_KEY;
|
||||||
|
} else {
|
||||||
|
// ...otherwise, use the custom key directly.
|
||||||
|
logger.info("Using a fixed 'remember me' key from system properties, this is insecure.");
|
||||||
|
}
|
||||||
|
|
||||||
http
|
http
|
||||||
.csrf()
|
.csrf()
|
||||||
.requireCsrfProtectionMatcher(csrfSecurityRequestMatcher)
|
.requireCsrfProtectionMatcher(csrfSecurityRequestMatcher)
|
||||||
@@ -169,7 +197,7 @@ public class GlobalSecurityConfig extends GlobalAuthenticationConfigurerAdapter
|
|||||||
// see http://docs.spring.io/spring-security/site/docs/3.2.4.RELEASE/reference/htmlsingle/#csrf-logout
|
// see http://docs.spring.io/spring-security/site/docs/3.2.4.RELEASE/reference/htmlsingle/#csrf-logout
|
||||||
.and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET")).logoutSuccessUrl(
|
.and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET")).logoutSuccessUrl(
|
||||||
"/login?logout")
|
"/login?logout")
|
||||||
.and().rememberMe().key(generateRememberMeKey());
|
.and().rememberMe().key(rememberMeKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ public class SettingsService {
|
|||||||
private static final String KEY_SONOS_SERVICE_NAME = "SonosServiceName";
|
private static final String KEY_SONOS_SERVICE_NAME = "SonosServiceName";
|
||||||
private static final String KEY_SONOS_SERVICE_ID = "SonosServiceId";
|
private static final String KEY_SONOS_SERVICE_ID = "SonosServiceId";
|
||||||
private static final String KEY_JWT_KEY = "JWTKey";
|
private static final String KEY_JWT_KEY = "JWTKey";
|
||||||
|
private static final String KEY_REMEMBER_ME_KEY = "RememberMeKey";
|
||||||
|
|
||||||
private static final String KEY_SMTP_SERVER = "SmtpServer";
|
private static final String KEY_SMTP_SERVER = "SmtpServer";
|
||||||
private static final String KEY_SMTP_ENCRYPTION = "SmtpEncryption";
|
private static final String KEY_SMTP_ENCRYPTION = "SmtpEncryption";
|
||||||
@@ -794,6 +795,27 @@ public class SettingsService {
|
|||||||
setString(KEY_MEDIA_LIBRARY_STATISTICS, statistics.format());
|
setString(KEY_MEDIA_LIBRARY_STATISTICS, statistics.format());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether we are running in Development mode.
|
||||||
|
*
|
||||||
|
* @return true if we are in Development mode.
|
||||||
|
*/
|
||||||
|
public boolean isDevelopmentMode() {
|
||||||
|
return System.getProperty("airsonic.development") != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the custom 'remember me' key used for generating authentication tokens.
|
||||||
|
*
|
||||||
|
* @return The 'remember me' key.
|
||||||
|
*/
|
||||||
|
public String getRememberMeKey() {
|
||||||
|
String key = null;
|
||||||
|
if (StringUtils.isBlank(key)) key = getString(KEY_REMEMBER_ME_KEY, null);
|
||||||
|
if (StringUtils.isBlank(key)) key = System.getProperty("airsonic.rememberMeKey");
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the locale (for language, date format etc).
|
* Returns the locale (for language, date format etc).
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user