Support for password file.

main
Tim Holloway 10 months ago
parent f3c28258d1
commit fa7e832996
  1. 7
      README.md
  2. 3
      application.properties
  3. 15
      gourmetpw.sample
  4. 67
      src/main/java/com/mousetech/gourmetj/SpringSecurityConfig.java

@ -49,6 +49,13 @@ You must have a recipe database file (see below) to store the
recipes in. By default, it will be looked for in your
home directory.
As of the 0.1.4 release, the parts of the application that can
alter the database are now password-protected. You will need
a ``.gourmetpw`` file to contain your userid/password
definitions. By default it should be in the same directory
that you are running the application from. A sample password file
is included in this project.
To actually access the application, open your web browser
to ``http://localhost:8080``

@ -17,3 +17,6 @@ spring.datasource.driverClassName=org.sqlite.JDBC
#spring.jpa.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
spring.jpa.database-platform=org.sqlite.hibernate.dialect.SQLiteDialect
#spring.jpa.show-sql: true
# My special properties
gourmet.password.file=.gourmetpw

@ -0,0 +1,15 @@
# This is a sample password file for the Gourmetj webapp.
# The actual file should be named ".gourmetpw" and located
# in the same directory that you run the application from.
#
# Blank lines and lines beginning with "#" are ignored.
# Password lines look like this (remove leading "#")
#
# userid,password,role[,role,...]
#
# like so:
#
# john.smith,secretpassword,USER
#
# Where "role" is a security role. ADMIN is also allowed.
#

@ -1,8 +1,19 @@
package com.mousetech.gourmetj;
import java.io.File;
import java.io.FileReader;
import java.io.LineNumberInputStream;
import java.io.LineNumberReader;
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer;
import org.springframework.security.config.annotation.authentication.configurers.provisioning.UserDetailsManagerConfigurer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@ -12,6 +23,11 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
public class SpringSecurityConfig
extends WebSecurityConfigurerAdapter {
/* Logger */
private static final Logger log =
LoggerFactory.getLogger(SpringSecurityConfig.class);
@Override
protected void configure(HttpSecurity http)
throws Exception {
@ -32,12 +48,55 @@ public class SpringSecurityConfig
http.csrf().disable();
}
@Value("${gourmet.password.file}")
private String passwordFile;
@Autowired
public void configureGlobal(
AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("tim.holloway")
.password("{noop}secret").roles("ADMIN").and()
.withUser("jane.doe").password("{noop}5678")
.roles("USER");
File pwFile = new File(passwordFile);
if (!pwFile.canRead()) {
String msg =
"Password file '" + pwFile.getAbsolutePath()
+ "' could not be found or read.";
log.error(msg);
throw new RuntimeException(msg);
}
LineNumberReader rdr =
new LineNumberReader(new FileReader(pwFile));
String pwLine;
InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> authenticator =
auth.inMemoryAuthentication();
while ((pwLine = rdr.readLine()) != null) {
pwLine = pwLine.trim();
if (( pwLine.length() == 0) || (pwLine.charAt(0) == '#')) {
continue;
}
String[] creds = parseCreds(pwLine);
UserDetailsManagerConfigurer<AuthenticationManagerBuilder, InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder>>.UserDetailsBuilder bar =
authenticator.withUser(creds[0])
.password("{noop}"+creds[1]);
int credlen = creds.length;
for (int i = 2; i < credlen; i++) {
bar.roles(creds[i]);
}
}
rdr.close();
}
/**
* Parse CSV credential/roles line. Element 1 is userid,
* element 2 is password, following element(s) are role(s)
*
* @param pwLine
* @return Credentials array following CSV values, trimmed
*/
private String[] parseCreds(String pwLine) {
String[] creds = pwLine.split(",");
String[] ocreds = Arrays.stream(creds).map(e -> e.trim())
.toArray(String[]::new);
return ocreds;
}
}

Loading…
Cancel
Save