Support for password file.
This commit is contained in:
		
							parent
							
								
									f3c28258d1
								
							
						
					
					
						commit
						fa7e832996
					
				| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										15
									
								
								gourmetpw.sample
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								gourmetpw.sample
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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…
	
		Reference in New Issue
	
	Block a user