SES-1: Added KerberosServiceAuthenticationProvider
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
package org.springframework.security.extensions.kerberos;
|
||||
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
|
||||
public class KerberosServiceAuthenticationProvider implements
|
||||
AuthenticationProvider {
|
||||
|
||||
private KerberosTicketValidator ticketValidator;
|
||||
private UserDetailsService userDetailsService;
|
||||
|
||||
public void setUserDetailsService(UserDetailsService userDetailsService) {
|
||||
this.userDetailsService = userDetailsService;
|
||||
}
|
||||
|
||||
public void setTicketValidator(KerberosTicketValidator ticketValidator) {
|
||||
this.ticketValidator = ticketValidator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authentication authenticate(Authentication authentication)
|
||||
throws AuthenticationException {
|
||||
KerberosServiceRequestToken auth = (KerberosServiceRequestToken) authentication;
|
||||
byte[] token = auth.getToken();
|
||||
String username = this.ticketValidator.validateTicket(token);
|
||||
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
|
||||
return new KerberosServiceRequestToken(userDetails, userDetails.getAuthorities(), token);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<? extends Object> auth) {
|
||||
return KerberosServiceRequestToken.class.isAssignableFrom(auth);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,7 +16,10 @@
|
||||
|
||||
package org.springframework.security.extensions.kerberos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
|
||||
/**
|
||||
* Holds the Kerberos/SPNEGO token for requesting a kerberized service Will
|
||||
@@ -30,9 +33,15 @@ import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||
|
||||
public class KerberosServiceRequestToken extends AbstractAuthenticationToken {
|
||||
|
||||
public KerberosServiceRequestToken(Object principal, List<GrantedAuthority> authorities, byte[] token) {
|
||||
super(authorities);
|
||||
this.token = token;
|
||||
this.principal = principal;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 395488921064775014L;
|
||||
private final byte[] token;
|
||||
private final Object principal = null;
|
||||
private final Object principal;
|
||||
|
||||
/**
|
||||
* Creates an unauthenticated instance which should then be authenticated by
|
||||
@@ -44,6 +53,7 @@ public class KerberosServiceRequestToken extends AbstractAuthenticationToken {
|
||||
public KerberosServiceRequestToken(byte[] token) {
|
||||
super(null);
|
||||
this.token = token;
|
||||
this.principal = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.springframework.security.extensions.kerberos;
|
||||
|
||||
public interface KerberosTicketValidator {
|
||||
|
||||
public abstract String validateTicket(byte[] token);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package org.springframework.security.extensions.kerberos;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.kerberos.KerberosPrincipal;
|
||||
import javax.security.auth.login.AppConfigurationEntry;
|
||||
import javax.security.auth.login.Configuration;
|
||||
import javax.security.auth.login.LoginContext;
|
||||
|
||||
import org.ietf.jgss.GSSContext;
|
||||
import org.ietf.jgss.GSSCredential;
|
||||
import org.ietf.jgss.GSSManager;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
public class SunJaasKerberosTicketValidator implements KerberosTicketValidator, InitializingBean {
|
||||
|
||||
private String servicePrincipal;
|
||||
private Resource keyTabLocation;
|
||||
private Subject serviceSubject;
|
||||
|
||||
public String validateTicket(byte[] token) {
|
||||
String username = null;
|
||||
try {
|
||||
username = Subject.doAs(this.serviceSubject, new KerberosValidateAction(token));
|
||||
} catch (PrivilegedActionException e) {
|
||||
throw new BadCredentialsException("Kerberos validation not succesfull", e);
|
||||
}
|
||||
return username;
|
||||
}
|
||||
|
||||
|
||||
public void setServicePrincipal(String servicePrincipal) {
|
||||
this.servicePrincipal = servicePrincipal;
|
||||
}
|
||||
|
||||
public void setKeyTabLocation(Resource keyTabLocation) {
|
||||
this.keyTabLocation = keyTabLocation;
|
||||
}
|
||||
|
||||
public void setServiceSubject(Subject serviceSubject) {
|
||||
this.serviceSubject = serviceSubject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(this.servicePrincipal, "ServicePrincipal muss gesetzt werden");
|
||||
Assert.notNull(this.keyTabLocation, "KeyTab muss gesetzt werden");
|
||||
LoginConfig loginConfig = new LoginConfig(this.keyTabLocation.getURL().toExternalForm(), servicePrincipal);
|
||||
Set<Principal> princ = new HashSet<Principal>(1);
|
||||
princ.add(new KerberosPrincipal(this.servicePrincipal));
|
||||
Subject sub = new Subject(false, princ, new HashSet<Object>(), new HashSet<Object>());
|
||||
LoginContext lc = new LoginContext("", sub, null, loginConfig);
|
||||
lc.login();
|
||||
this.serviceSubject = lc.getSubject();
|
||||
}
|
||||
|
||||
private static class KerberosValidateAction implements PrivilegedExceptionAction<String> {
|
||||
byte[] kerberosTicket;
|
||||
|
||||
public KerberosValidateAction(byte[] kerberosTicket) {
|
||||
this.kerberosTicket = kerberosTicket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String run() throws Exception {
|
||||
GSSContext context = GSSManager.getInstance().createContext((GSSCredential) null);
|
||||
context.acceptSecContext(kerberosTicket, 0, kerberosTicket.length);
|
||||
String user = context.getSrcName().toString();
|
||||
context.dispose();
|
||||
return user;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class LoginConfig extends Configuration {
|
||||
private String keyTabLocation;
|
||||
private String servicePrincipalName;
|
||||
|
||||
public LoginConfig(String keyTabLocation, String servicePrincipalName) {
|
||||
this.keyTabLocation = keyTabLocation;
|
||||
this.servicePrincipalName = servicePrincipalName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
|
||||
HashMap<String, String> options = new HashMap<String, String>();
|
||||
options.put("useKeyTab", "true");
|
||||
options.put("keyTab", this.keyTabLocation);
|
||||
options.put("principal", this.servicePrincipalName);
|
||||
options.put("storeKey", "true");
|
||||
options.put("doNotPrompt", "true");
|
||||
options.put("debug", "true");
|
||||
options.put("isInitiator", "false");
|
||||
|
||||
return new AppConfigurationEntry[] { new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule",
|
||||
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options), };
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user