Commit 345ac3ed authored by Gradl, Tobias's avatar Gradl, Tobias
Browse files

717: Implement bcrypt security for local authentication

Task-Url: https://minfba.de.dariah.eu/mantisbt/view.php?id=717
parent c1c28080
......@@ -12,9 +12,9 @@ The implementation needs to be provided to the *LocalAuthenticationProvider*.
In cases that do not require user detail persistence, no implementation of the *UserDetails* should be provided to the *LocalAuthenticationProvider*.
To create sha256 hashes on linux shells, you can use the following command (replace foo with the desired password):
To create bcrypt passwords from a shell:
```
$ echo -n foo | openssl dgst -binary -sha1 | openssl base64
java -cp dariahsp-core-0.0.4-SNAPSHOT-jar-with-dependencies.jar eu.dariah.de.dariahsp.local.BCryptPasswordCreator
```
### SAML
......
......@@ -11,21 +11,34 @@
<description>DARIAH wrapper to the Spring Security Saml Project</description>
<dependencies>
<!-- Dependencies without provided scope are included in the jar
-> only dependencies needed for CLI methods should NOT have <scope>provided</scope>
-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${org.springsecurity-version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>eu.dariah.de.minfba.core</groupId>
<artifactId>core-metamodel</artifactId>
<version>${eu.dariah.de.minfba.core-metamodel.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>eu.dariah.eu</groupId>
<artifactId>spring-security-saml2-core</artifactId>
<version>${spring-security-saml2-core.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
<scope>provided</scope>
</dependency>
<dependency>
......@@ -39,6 +52,7 @@
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${joda-time-version}</version>
<scope>provided</scope>
</dependency>
<!-- Logging -->
......@@ -46,16 +60,25 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${ch.qos.logback.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${ch.qos.logback.version}</version>
<scope>compile</scope>
</dependency>
<!-- Commons -->
......@@ -63,6 +86,7 @@
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
<scope>provided</scope>
</dependency>
</dependencies>
......@@ -77,5 +101,29 @@
<url>https://minfba.de.dariah.eu/artifactory/dariah-snapshot-proxy</url>
</snapshotRepository>
</distributionManagement>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
package eu.dariah.de.dariahsp.local;
import java.util.Scanner;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
public class BCryptPasswordCreator {
private static BCryptPasswordEncoder encoder;
public static void main(String[] args) {
Scanner scanner = new Scanner (System.in);
System.out.println("CLI Tool to create BCrypt passwords to be used with a dariahsp derived application");
System.out.println("------------------------------------------------------");
System.out.println("Please make sure to provide BCrypt initialization arguments exactly \n as they are configured in the security-context-common.xml");
System.out.println("If you have not changed the default initialization of the BCryptPasswordEncoder \n (and you dont have to), choose the default values for rounds:");
System.out.println("------------------------------------------------------");
System.out.println("Please choose rounds [4-31; default: 10]");
String input = scanner.nextLine();
int rounds = 10;
if (!input.isEmpty()) {
rounds = Integer.parseInt(input);
}
boolean computed = false;
while(!computed){
System.out.println("Provide the password that you want encoded (minimum 6 characters, no leading/trailing whitespace):");
/** NOTE: For debugging in some IDE use the first line as
* System.console().readPassword() needs a real console to work */
//input = scanner.nextLine().trim();
input = new String(System.console().readPassword()).trim();
if (input.length()<6) {
System.out.println("Password too short");
} else {
encoder = new BCryptPasswordEncoder(rounds, null);
System.out.println("BCrypt computation successful:");
System.out.println(encoder.encode(input));
computed = true;
}
}
scanner.close();
scanner = null;
}
}
package eu.dariah.de.dariahsp.local;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collection;
import org.joda.time.DateTime;
......@@ -16,6 +12,7 @@ import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import eu.dariah.de.dariahsp.model.Role;
import eu.dariah.de.dariahsp.model.RoleImpl;
......@@ -27,7 +24,7 @@ import eu.dariah.de.dariahsp.service.UserService;
public class LocalAuthenticationProvider implements AuthenticationProvider {
private UserService userService;
private UserDetailsService localUserDb;
private PasswordEncoder encoder;
public UserService getUserService() { return userService; }
public void setUserService(UserService userService) { this.userService = userService; }
......@@ -35,18 +32,17 @@ public class LocalAuthenticationProvider implements AuthenticationProvider {
public UserDetailsService getLocalUserDb() { return localUserDb; }
public void setLocalUserDb(UserDetailsService localUserDb) { this.localUserDb = localUserDb; }
public PasswordEncoder getEncoder() { return encoder; }
public void setEncoder(PasswordEncoder encoder) { this.encoder = encoder; }
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
try {
UserDetails user = getLocalUserDb().loadUserByUsername(authentication.getName());
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(authentication.getCredentials().toString().getBytes("UTF-8"));
byte[] aMessageDigest = md.digest();
String enteredHash = Base64.getEncoder().encodeToString(aMessageDigest);
if (user.getPassword().equals(enteredHash)) {
if (encoder.matches(authentication.getCredentials().toString(), user.getPassword())) {
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword().hashCode(), user.getAuthorities());
auth.setDetails(this.getUserDetails(user));
return auth;
......@@ -55,10 +51,6 @@ public class LocalAuthenticationProvider implements AuthenticationProvider {
}
} catch (AuthenticationException e) {
throw new BadCredentialsException("Provided username and/or password wrong.");
} catch (NoSuchAlgorithmException e) {
throw new BadCredentialsException("Unsupported algorithm", e);
} catch (UnsupportedEncodingException e) {
throw new BadCredentialsException("Unsupported encoding", e);
}
}
......
......@@ -11,6 +11,7 @@ import org.springframework.context.ApplicationContextAware;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.fasterxml.jackson.databind.ObjectMapper;
......@@ -20,16 +21,18 @@ import eu.dariah.de.dariahsp.model.RoleImpl;
public class LocalUserConfService implements UserDetailsService, ApplicationContextAware {
protected static final Logger logger = LoggerFactory.getLogger(LocalUserConfService.class);
private String userfile;
private LocalUserConf[] localUserConfigurations;
@Autowired private ObjectMapper objMapper;
public String getUserfile() { return userfile; }
public void setUserfile(String userfile) { this.userfile = userfile; }
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
File userconf;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment