package de.is24.infrastructure.gridfs.http.security;
import org.jvnet.libpam.PAM;
import org.jvnet.libpam.PAMException;
import org.jvnet.libpam.UnixUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;
import static de.is24.infrastructure.gridfs.http.Profiles.PROD;
import static de.is24.infrastructure.gridfs.http.security.UserAuthorities.USER_AUTHORITIES;
@Component
@Profile(PROD)
public class PamAuthenticationProvider implements AuthenticationProvider {
private final String pamServiceName;
@Autowired
public PamAuthenticationProvider(@Value("${pam.service.name:password-auth}") String pamServiceName) {
this.pamServiceName = pamServiceName;
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = String.valueOf(authentication.getPrincipal());
String password = String.valueOf(authentication.getCredentials());
PAM pam;
try {
pam = new PAM(pamServiceName);
} catch (PAMException e) {
throw new AuthenticationServiceException("Could not initialize PAM.", e);
}
try {
UnixUser user = pam.authenticate(username, password);
return new UsernamePasswordAuthenticationToken(user.getUserName(), authentication.getCredentials(), USER_AUTHORITIES);
} catch (PAMException e) {
throw new BadCredentialsException("PAM authentication failed.", e);
} finally {
pam.dispose();
}
}
@Override
public boolean supports(Class<?> authentication) {
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}
}