Commit 4e0cae0f authored by Gradl, Tobias's avatar Gradl, Tobias
Browse files

716: Rework local user configuration

Task-Url: https://minfba.de.dariah.eu/mantisbt/view.php?id=716
parent 5565d1b2
......@@ -12,6 +12,11 @@ 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):
```
$ echo -n foo | openssl dgst -binary -sha1 | openssl base64
```
### SAML
## Further info
......
package eu.dariah.de.dariahsp.web;
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;
......@@ -20,8 +24,7 @@ import eu.dariah.de.dariahsp.model.UserImpl;
import eu.dariah.de.dariahsp.service.BaseUserService;
import eu.dariah.de.dariahsp.service.UserService;
public class LocalAuthenticationProvider implements AuthenticationProvider {
public class LocalAuthenticationProvider implements AuthenticationProvider {
private UserService userService;
private UserDetailsService localUserDb;
......@@ -32,12 +35,18 @@ public class LocalAuthenticationProvider implements AuthenticationProvider {
public UserDetailsService getLocalUserDb() { return localUserDb; }
public void setLocalUserDb(UserDetailsService localUserDb) { this.localUserDb = localUserDb; }
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
try {
UserDetails user = getLocalUserDb().loadUserByUsername(authentication.getName());
if (user.getPassword().equals(authentication.getCredentials())) {
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)) {
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword().hashCode(), user.getAuthorities());
auth.setDetails(this.getUserDetails(user));
return auth;
......@@ -46,6 +55,10 @@ 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);
}
}
......@@ -79,4 +92,6 @@ public class LocalAuthenticationProvider implements AuthenticationProvider {
}
return authorizedUser;
}
}
package eu.dariah.de.dariahsp.local;
public class LocalUserConf {
private String username;
private String passhash;
private String[] roles;
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPasshash() { return passhash; }
public void setPasshash(String passhash) { this.passhash = passhash; }
public String[] getRoles() { return roles; }
public void setRoles(String[] roles) { this.roles = roles; }
}
package eu.dariah.de.dariahsp.local;
import java.io.File;
import java.util.ArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
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 com.fasterxml.jackson.databind.ObjectMapper;
import eu.dariah.de.dariahsp.model.LocalUserImpl;
import eu.dariah.de.dariahsp.model.Role;
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;
userfile = userfile.trim();
try {
if (userfile.startsWith("file:") || userfile.startsWith("classpath:")) {
userconf = applicationContext.getResource(userfile).getFile();
} else {
userconf = new File(userfile);
}
localUserConfigurations = objMapper.readValue(userconf, LocalUserConf[].class);
} catch (Exception e) {
logger.error("Failed to initialize local user configuration: no local logins will be possible.", e);
}
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (localUserConfigurations!=null) {
for (LocalUserConf uc : localUserConfigurations) {
if (uc.getUsername().equals(username)) {
LocalUserImpl u = new LocalUserImpl();
u.setUsername(uc.getUsername());
u.setPassword(uc.getPasshash());
if (uc.getRoles()!=null && uc.getRoles().length>0) {
u.setAuthorities(new ArrayList<Role>(uc.getRoles().length));
for (String r : uc.getRoles()) {
u.getAuthorities().add(new RoleImpl(r));
}
}
return u;
}
}
}
return null;
}
}
package eu.dariah.de.dariahsp.model;
public class LocalUserImpl extends UserImpl {
private static final long serialVersionUID = -5818509791157521462L;
private String password;
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
}
saml.local.userfile = classpath:dariahsp_localusers.json
saml.keystore.path = /data/_srv/schereg/key/dfa-de-dariah-eu.jks
......
[
{
"username" : "tgradl",
"passhash" : "g6arV8TSr/xibM/A93AOwRuoGRSZ2RCVwId7xICLDek=",
"roles" : ["ROLE_ADMINISTRATOR"]
}
]
\ No newline at end of file
......@@ -20,5 +20,7 @@
</property>
</bean>
<bean class="com.fasterxml.jackson.databind.ObjectMapper" />
<context:component-scan base-package="eu.dariah.de.dariahsp.configuration" />
</beans>
\ No newline at end of file
......@@ -36,20 +36,12 @@
<sec:authentication-provider ref="localAuthenticationProvider" />
</sec:authentication-manager>
<bean id="localAuthenticationProvider" class="eu.dariah.de.dariahsp.web.LocalAuthenticationProvider">
<property name="localUserDb" ref="localUserDb" />
<property name="userDetails" ref="userDetailsService" />
<bean id="localAuthenticationProvider" class="eu.dariah.de.dariahsp.local.LocalAuthenticationProvider">
<property name="localUserDb">
<bean class="eu.dariah.de.dariahsp.local.LocalUserConfService">
<property name="userfile" value="${saml.local.userfile}" />
</bean>
</property>
<property name="userService" ref="userDetailsService" />
</bean>
<sec:user-service id="localUserDb">
<sec:user name="tgradl" password="hairad" authorities="ROLE_ADMINISTRATOR" />
<sec:user name="tgradl_user" password="hairad" authorities="" />
<sec:user name="ahenrich" password="hairad" authorities="ROLE_CONTRIBUTOR" />
<sec:user name="teckart" password="niralc" authorities="ROLE_CONTRIBUTOR" />
<sec:user name="nutzer_hab" password="augusT66" authorities="ROLE_CONTRIBUTOR" />
<sec:user name="nutzer_ksw" password="goEthe49" authorities="ROLE_CONTRIBUTOR" />
</sec:user-service>
</beans>
\ No newline at end of file
......@@ -36,5 +36,5 @@
</bean>
<context:component-scan base-package="eu.dariah.de.dariahsp.sample.controller" />
<context:component-scan base-package="eu.dariah.de.dariahsp.saml.web.controller" />
<!-- <context:component-scan base-package="eu.dariah.de.dariahsp.saml.web.controller" /> -->
</beans>
\ No newline at end of file
Supports Markdown
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