blob: b279e18e0aca6a2aa8d90fe0bd8decde9c532cfa [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.rampart.policy.model;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.apache.neethi.Assertion;
import org.apache.neethi.Constants;
import org.apache.neethi.PolicyComponent;
import org.apache.rampart.RampartException;
import org.ietf.jgss.GSSCredential;
/**
* Container for Kerberos configuration options.
*/
public class KerberosConfig implements Assertion {
public final static String KERBEROS_LN = RampartConfig.KERBEROS_CONFIG;
public final static String JAAS_CONTEXT_LN = "jaasContext";
public final static String PRINCIPAL_NAME_LN = "principalName";
public final static String PRINCIPAL_PASSWORD_LN = "principalPassword";
public final static String SERVICE_PRINCIPAL_NAME_LN = "servicePrincipalName";
public final static String SERVICE_PRINCIPAL_NAME_FORM_LN = "servicePrincipalNameForm";
public final static String KERBEROS_TOKEN_DECODER_CLASS_LN = "kerberosTokenDecoderClass";
public final static String REQUEST_CREDENTIAL_DELEGATION_LN = "requestCredentialDelegation";
public final static String DELEGATION_CREDENTIAL_LN = "delegationCredential";
/**
* Specifies that the service principal name should be interpreted as a
* "host-based" name as specified in GSS API RFC,
* section "4.1: Host-Based Service Name Form".
* See <a href="http://www.ietf.org/rfc/rfc2743.txt">rfc2743 - GSS
* API, Version 2</a>.
*/
public final static String HOST_BASED_NAME_FORM = "hostbased";
/**
* Specifies that the service principal name should be interpreted as a
* "username" name as specified in GSS API RFC,
* section "4.2: User Name Form".
* See <a href="http://www.ietf.org/rfc/rfc2743.txt">rfc2743 - GSS API, Version
* 2</a>.
*/
public final static String USERNAME_NAME_FORM = "username";
private String jaasContext;
private String principalName;
private String principalPassword;
private String servicePrincipalName;
private String servicePrincipalNameForm;
private String kerberosTokenDecoderClass;
private boolean requstCredentialDelegation;
private GSSCredential delegationCredential;
/**
* @return The JAAS context name to use to obtain a TGT (Ticket granting ticket).
*/
public String getJaasContext() {
return jaasContext;
}
/**
* Sets the JAAS context name to use to obtain a TGT (Ticket granting ticket).
* @param jaasContext the jaasContext to set
*/
public void setJaasContext(String jaasContext) {
this.jaasContext = jaasContext;
}
/**
* @return The principal name to use to obtain a TGT (Ticket granting ticket).
* This is usually the domain username.
* If not specified, Rampart will fall back to the Rampart configuration's
* {@link RampartConfig#getUser() user}.
* Note that the principal name specified in JAAS configuration takes precedence
* over any principal name configured here.
*/
public String getPrincipalName() {
return principalName;
}
/**
* Sets the principal name to use to obtain a TGT (Ticket granting ticket).
* This is usually the domain username. If* not specified, Rampart will fall back
* to the Rampart configuration's {@link RampartConfig#getUser() user}.
* Note that the principal name specified in JAAS configuration takes precedence
* over any principal name configured via this method.
* @param principalName the principalName to set
*/
public void setPrincipalName(String principalName) {
this.principalName = principalName;
}
/**
* @return Returns the principal's clear-text password. If the password is not
* configured (null), Rampart will try to obtain it from any configured
* {@link RampartConfig#getPwCbClass() password callback}. Note that any
* principal password configured here will be ignored if the JAAS configuration
* configures usage of a keytab file.
*/
public String getPrincipalPassword() {
return principalPassword;
}
/**
* Sets the principal's clear-text password. If the password is not configured
* (null), Rampart will try to obtain it from any configured
* {@link RampartConfig#getPwCbClass() password callback}. Note that any
* principal password configured here will be ignored if the JAAS configuration
* configures usage of a keytab file.
*/
public void setPrincipalPassword(String principalPassword) {
this.principalPassword = principalPassword;
}
/**
* @return The service principal name to use to obtain a service ticket on the
* client-side. Note that by default,
* this name is assumed to be in a {@link #HOST_BASED_NAME_FORM} unless the
* {@link #setServicePrincipalNameForm(String) service principal name form} is
* explicitly configured.
*/
public String getServicePrincipalName() {
return servicePrincipalName;
}
/**
* Sets service principal name to use to obtain a service ticket on the
* client-side. Note that by default, this name is assumed to be in a
* {@link #HOST_BASED_NAME_FORM} unless the
* {@link #setServicePrincipalNameForm(String)
* service principal name form} is explicitly configured.
*/
public void setServicePrincipalName(String servicePrincipalName) {
this.servicePrincipalName = servicePrincipalName;
}
/**
* Returns the service principal name form.
* @return Either {@value #HOST_BASED_NAME_FORM} or {@value #USERNAME_NAME_FORM}.
* Default is: {@value #HOST_BASED_NAME_FORM}.
*/
public String getServicePrincipalNameForm() {
if (servicePrincipalNameForm == null) {
return HOST_BASED_NAME_FORM;
}
return servicePrincipalNameForm;
}
/**
* Configures a Kerberos token decoder implementation for decoding Kerberos v5 tokens on server side.
* The decoder will be used only if the Kerberos client/server session key cannot be obtained using Java's {@link com.sun.security.jgss.ExtendedGSSContext} API,
* which is normally the case when using Java version older than 1.7.0_b07,
* see <a href="http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6710360"> JDK-6710360 : export Kerberos session key to applications</a>.
* <p>
* The class will be loaded using current service's {@link org.apache.axis2.description.AxisService#getClassLoader() classloader}.
* </p>
*
* @param kerberosTokenDecoderClass A fully qualifier class name that implements {@link org.apache.ws.security.validate.KerberosTokenValidator}.
*/
public void setKerberosTokenDecoderClass(String kerberosTokenDecoderClass) {
this.kerberosTokenDecoderClass = kerberosTokenDecoderClass;
}
/**
* Returns the Kerberos token decoder implementation for decoding Kerberos v5 tokens on server side.
* The decoder will be used only if the Kerberos client/server session key cannot be obtained using Java's {@link com.sun.security.jgss.ExtendedGSSContext} API,
* which is normally the case when using Java version older than 1.7.0_b07,
* see <a href="http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6710360"> JDK-6710360 : export Kerberos session key to applications</a>
*
* @return A fully qualifier class name that implements {@link org.apache.ws.security.validate.KerberosTokenValidator} or <code>null</code> if no Kerberos token decoder is configured.
*/
public String getKerberosTokenDecoderClass() {
return this.kerberosTokenDecoderClass;
}
/**
* Sets the service principal name form.
* @param servicePrincipalNameForm The service principal name form to set.
* The given literal must be either {@value #HOST_BASED_NAME_FORM} or
* {@value #USERNAME_NAME_FORM}.
* @throws IllegalArgumentException If the given
* <code>servicePrincipalNameForm</code> is not one of:
* {@value #HOST_BASED_NAME_FORM} or {@value #USERNAME_NAME_FORM}.
*/
public void setServicePrincipalNameForm(String servicePrincipalNameForm)
throws IllegalArgumentException {
if (!HOST_BASED_NAME_FORM.equals(servicePrincipalNameForm) &&
!USERNAME_NAME_FORM.equals(servicePrincipalNameForm)) {
throw new IllegalArgumentException(
new RampartException("invalidServicePrincipalNameForm",
new String[] {
servicePrincipalNameForm,
HOST_BASED_NAME_FORM,
USERNAME_NAME_FORM }));
}
this.servicePrincipalNameForm = servicePrincipalNameForm;
}
/**
* If Kerberos credential delegation is requested, the initiator's TGT (Ticket granting ticket) is propagated to the receiver
* along with the TGS(Ticket granting service).
*
* @return true if credential delegation is requested.
*/
public boolean isRequstCredentialDelegation() {
return requstCredentialDelegation;
}
/**
* Enables Kerberos credential delegation. If credential delegation is requested, the initiator's TGT (Ticket
* granting ticket) is propagated to the receiver along with the TGS(Ticket granting service).
* <p>
* Enabling delegation requires <b>forwardable=true</b> property to be added to the <b>[libdefaults]</b> section in
* the Kerberos setup configuration.KDC should also be explicitly configured to allow delegation as it is considered
* a security issue and is disabled by default.
*
* @param requstCredentialDelegation if true, credential delegation is requested.
*/
public void setRequstCredentialDelegation(boolean requstCredentialDelegation) {
this.requstCredentialDelegation = requstCredentialDelegation;
}
/**
* The delegation credential is available when the initiator has explicitly requested delegation through
* {@link KerberosConfig#setRequstCredentialDelegation(boolean)} and the receiver has retrieved it and set it
* through {@link KerberosConfig#setDelegationCredential(GSSCredential)}.
*
* If available, the delegation credential is used by the receiver to obtain a service ticket for another
* Kerberos protected WS on behalf of the initiator. The receiver's principal must have explicit privileges to use
* the delegated credential(TGT) for retrieval of the service ticket.
*
* @return the client's TGT wrapped in {@link GSSCredential}
*/
public GSSCredential getDelegationCredential() {
return delegationCredential;
}
/**
* Sets the delegation credential to be used by the receiver to obtain a service ticket for another
* Kerberos protected WS on behalf of the initiator. The receiver's principal must have explicit privileges to use
* the delegated credential(TGT) for retrieval of the service ticket.
*
* @param delegationCredential the {@link GSSCredential} to use for obtaining a TGS
*/
public void setDelegationCredential(GSSCredential delegationCredential) {
this.delegationCredential = delegationCredential;
}
public PolicyComponent normalize() {
throw new UnsupportedOperationException();
}
public QName getName() {
return new QName(RampartConfig.NS, KERBEROS_LN);
}
public boolean isOptional() {
return true;
}
public boolean isIgnorable() {
throw new UnsupportedOperationException();
}
public short getType() {
return Constants.TYPE_ASSERTION;
}
public boolean equal(PolicyComponent policyComponent) {
throw new UnsupportedOperationException();
}
public void serialize(XMLStreamWriter writer) throws XMLStreamException {
String prefix = writer.getPrefix(RampartConfig.NS);
if (prefix == null) {
prefix = RampartConfig.NS;
writer.setPrefix(prefix, RampartConfig.NS);
}
if (getJaasContext() != null) {
writer.writeStartElement(RampartConfig.NS, JAAS_CONTEXT_LN);
writer.writeCharacters(getJaasContext());
writer.writeEndElement();
}
if (getPrincipalName() != null) {
writer.writeStartElement(RampartConfig.NS, PRINCIPAL_NAME_LN);
writer.writeCharacters(getPrincipalName());
writer.writeEndElement();
}
if (getPrincipalPassword() != null) {
writer.writeStartElement(RampartConfig.NS, PRINCIPAL_PASSWORD_LN);
writer.writeCharacters(getPrincipalPassword());
writer.writeEndElement();
}
if (getServicePrincipalName() != null) {
writer.writeStartElement(RampartConfig.NS, SERVICE_PRINCIPAL_NAME_LN);
writer.writeCharacters(getServicePrincipalName());
writer.writeEndElement();
}
if (this.servicePrincipalNameForm != null) {
writer.writeStartElement(RampartConfig.NS,
SERVICE_PRINCIPAL_NAME_FORM_LN);
writer.writeCharacters(this.servicePrincipalNameForm);
writer.writeEndElement();
}
if (this.kerberosTokenDecoderClass != null) {
writer.writeStartElement(RampartConfig.NS,
KERBEROS_TOKEN_DECODER_CLASS_LN);
writer.writeCharacters(this.kerberosTokenDecoderClass);
writer.writeEndElement();
}
if (this.requstCredentialDelegation) {
writer.writeStartElement(RampartConfig.NS, REQUEST_CREDENTIAL_DELEGATION_LN);
writer.writeCharacters(Boolean.toString(this.requstCredentialDelegation));
writer.writeEndElement();
}
}
}