Commit 1e69be0b authored by Misagh Moayyed's avatar Misagh Moayyed
Browse files

Merge branch 'master' into response-builders

parents 86bf9866 91edd49d
/*
* Licensed to Apereo under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Apereo 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 the following location:
*
* 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.jasig.cas.support.saml.util;
import org.opensaml.core.xml.XMLObject;
import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
import org.opensaml.saml.saml1.binding.encoding.impl.HTTPSOAP11Encoder;
import org.opensaml.soap.common.SOAPObjectBuilder;
import org.opensaml.soap.soap11.Body;
import org.opensaml.soap.soap11.Envelope;
import org.opensaml.soap.util.SOAPConstants;
import org.opensaml.core.xml.XMLObjectBuilderFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Override OpenSAML {@link HTTPSOAP11Encoder} such that SOAP-ENV XML namespace prefix is used for SOAP envelope
* elements. This is needed for backward compatibility with certain CAS clients (e.g. Java CAS client).
*
* @author Marvin S. Addison
* @since 4.2.0
*/
public final class CasHttpSoap11Encoder extends HTTPSOAP11Encoder {
private static final String OPENSAML_11_SOAP_NS_PREFIX = "SOAP-ENV";
private static final Logger LOGGER = LoggerFactory.getLogger(CasHttpSoap11Encoder.class);
/**
* Instantiates a new encoder.
*/
public CasHttpSoap11Encoder() {
super();
}
@Override
protected void buildAndStoreSOAPMessage(final XMLObject payload) {
final XMLObjectBuilderFactory builderFactory = XMLObjectProviderRegistrySupport.getBuilderFactory();
final SOAPObjectBuilder<Envelope> envBuilder =
(SOAPObjectBuilder<Envelope>) builderFactory.getBuilder(Envelope.DEFAULT_ELEMENT_NAME);
final Envelope envelope = envBuilder.buildObject(
SOAPConstants.SOAP11_NS, Envelope.DEFAULT_ELEMENT_LOCAL_NAME, OPENSAML_11_SOAP_NS_PREFIX);
final SOAPObjectBuilder<Body> bodyBuilder =
(SOAPObjectBuilder<Body>) builderFactory.getBuilder(Body.DEFAULT_ELEMENT_NAME);
final Body body = bodyBuilder.buildObject(
SOAPConstants.SOAP11_NS, Body.DEFAULT_ELEMENT_LOCAL_NAME, OPENSAML_11_SOAP_NS_PREFIX);
if(!body.getUnknownXMLObjects().isEmpty()) {
LOGGER.warn("Existing SOAP Envelope Body already contained children");
}
body.getUnknownXMLObjects().add(payload);
envelope.setBody(body);
this.storeSOAPEnvelope(envelope);
}
}
/*
* Licensed to Apereo under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Apereo 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 the following location:
*
* 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.jasig.cas.support.spnego.authentication.handler.support;
import jcifs.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import java.net.URL;
/**
* Configuration helper for JCIFS and the Spring framework.
*
* @author Marc-Antoine Garrigue
* @author Arnaud Lesueur
* @author Scott Battaglia
* @since 4.2.0
*/
public final class JcifsConfig implements InitializingBean {
private static final String DEFAULT_LOGIN_CONFIG = "/login.conf";
private static final String SYS_PROP_USE_SUBJECT_CRED_ONLY = "javax.security.auth.useSubjectCredsOnly";
private static final String SYS_PROP_LOGIN_CONF = "java.security.auth.login.config";
private static final String SYS_PROP_KERBEROS_DEBUG = "sun.security.krb5.debug";
private static final String SYS_PROP_KERBEROS_CONF = "java.security.krb5.conf";
private static final String SYS_PROP_KERBEROS_REALM = "java.security.krb5.realm";
private static final String SYS_PROP_KERBEROS_KDC = "java.security.krb5.kdc";
private static final String JCIFS_PROP_DOMAIN_CONTROLLER = "jcifs.http.domainController";
private static final String JCIFS_PROP_NETBIOS_WINS = "jcifs.netbios.wins";
private static final String JCIFS_PROP_CLIENT_DOMAIN = "jcifs.smb.client.domain";
private static final String JCIFS_PROP_CLIENT_USERNAME = "jcifs.smb.client.username";
private static final String JCIFS_PROP_CLIENT_PASSWORD = "jcifs.smb.client.password";
/**
* -- the service principal you just created. Using the previous example,
* this would be "HTTP/mybox at DOMAIN.COM".
*/
private static final String JCIFS_PROP_SERVICE_PRINCIPAL = "jcifs.spnego.servicePrincipal";
/**
* The password for the service principal account, required only if you
* decide not to use keytab.
*/
private static final String JCIFS_PROP_SERVICE_PASSWORD = "jcifs.spnego.servicePassword";
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private String loginConf;
/**
* Instantiates a new jCIFS config.
*/
public JcifsConfig() {
Config.setProperty("jcifs.smb.client.soTimeout", "300000");
Config.setProperty("jcifs.netbios.cachePolicy", "600");
}
@Override
public void afterPropertiesSet() throws Exception {
final String propValue = System.getProperty(SYS_PROP_LOGIN_CONF);
if (propValue != null) {
logger.warn("found login config in system property, may overide : {}", propValue);
}
URL url = getClass().getResource(
this.loginConf == null ? DEFAULT_LOGIN_CONFIG : this.loginConf);
if (url != null) {
this.loginConf = url.toExternalForm();
}
if (this.loginConf != null) {
System.setProperty(SYS_PROP_LOGIN_CONF, this.loginConf);
} else {
url = getClass().getResource("/jcifs/http/login.conf");
if (url != null) {
System.setProperty(SYS_PROP_LOGIN_CONF, url.toExternalForm());
}
}
logger.debug("configured login configuration path : {}", propValue);
}
/**
* Sets the jcifs service password.
*
* @param jcifsServicePassword the new jcifs service password
*/
public void setJcifsServicePassword(final String jcifsServicePassword) {
logger.debug("jcifsServicePassword is set to *****");
Config.setProperty(JCIFS_PROP_SERVICE_PASSWORD, jcifsServicePassword);
}
/**
* Sets the jcifs service principal.
*
* @param jcifsServicePrincipal the new jcifs service principal
*/
public void setJcifsServicePrincipal(final String jcifsServicePrincipal) {
logger.debug("jcifsServicePrincipal is set to {}", jcifsServicePrincipal);
Config.setProperty(JCIFS_PROP_SERVICE_PRINCIPAL, jcifsServicePrincipal);
}
/**
* Sets the kerberos conf.
*
* @param kerberosConf the new kerberos conf
*/
public void setKerberosConf(final String kerberosConf) {
logger.debug("kerberosConf is set to :{}", kerberosConf);
System.setProperty(SYS_PROP_KERBEROS_CONF, kerberosConf);
}
/**
* Sets the kerberos kdc.
*
* @param kerberosKdc the new kerberos kdc
*/
public void setKerberosKdc(final String kerberosKdc) {
logger.debug("kerberosKdc is set to : {}", kerberosKdc);
System.setProperty(SYS_PROP_KERBEROS_KDC, kerberosKdc);
}
/**
* Sets the kerberos realm.
*
* @param kerberosRealm the new kerberos realm
*/
public void setKerberosRealm(final String kerberosRealm) {
logger.debug("kerberosRealm is set to :{}", kerberosRealm);
System.setProperty(SYS_PROP_KERBEROS_REALM, kerberosRealm);
}
public void setLoginConf(final String loginConf) {
this.loginConf = loginConf;
}
/**
* Sets the use subject creds only.
*
* @param useSubjectCredsOnly the new use subject creds only
*/
public void setUseSubjectCredsOnly(final boolean useSubjectCredsOnly) {
logger.debug("useSubjectCredsOnly is set to {}", useSubjectCredsOnly);
System.setProperty(SYS_PROP_USE_SUBJECT_CRED_ONLY, Boolean.toString(useSubjectCredsOnly));
}
/**
* Sets the kerberos debug.
*
* @param kerberosDebug the new kerberos debug
*/
public void setKerberosDebug(final String kerberosDebug) {
logger.debug("kerberosDebug is set to : {}", kerberosDebug);
System.setProperty(SYS_PROP_KERBEROS_DEBUG, kerberosDebug);
}
/**
* @param jcifsDomain the jcifsDomain to set
*/
public void setJcifsDomain(final String jcifsDomain) {
logger.debug("jcifsDomain is set to {}", jcifsDomain);
Config.setProperty(JCIFS_PROP_CLIENT_DOMAIN, jcifsDomain);
}
/**
* @param jcifsDomainController the jcifsDomainController to set
*/
public void setJcifsDomainController(final String jcifsDomainController) {
logger.debug("jcifsDomainController is set to {}", jcifsDomainController);
Config.setProperty(JCIFS_PROP_DOMAIN_CONTROLLER, jcifsDomainController);
}
/**
* @param jcifsPassword the jcifsPassword to set
*/
public void setJcifsPassword(final String jcifsPassword) {
Config.setProperty(JCIFS_PROP_CLIENT_PASSWORD, jcifsPassword);
logger.debug("jcifsPassword is set to *****");
}
/**
* @param jcifsUsername the jcifsUsername to set
*/
public void setJcifsUsername(final String jcifsUsername) {
logger.debug("jcifsUsername is set to {}", jcifsUsername);
Config.setProperty(JCIFS_PROP_CLIENT_USERNAME, jcifsUsername);
}
/**
* @param jcifsNetbiosWins the jcifsNetbiosWins to set
*/
public void setJcifsNetbiosWins(final String jcifsNetbiosWins) {
logger.debug("jcifsNetbiosWins is set to {}", jcifsNetbiosWins);
Config.setProperty(JCIFS_PROP_NETBIOS_WINS, jcifsNetbiosWins);
}
}
/*
* Licensed to Apereo under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Apereo 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 the following location:
*
* 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.jasig.cas.support.spnego.authentication.handler.support;
import jcifs.spnego.Authentication;
import org.jasig.cas.authentication.BasicCredentialMetaData;
import org.jasig.cas.authentication.Credential;
import org.jasig.cas.authentication.DefaultHandlerResult;
import org.jasig.cas.authentication.HandlerResult;
import org.jasig.cas.authentication.PreventedException;
import org.jasig.cas.authentication.handler.support.AbstractPreAndPostProcessingAuthenticationHandler;
import org.jasig.cas.authentication.principal.Principal;
import org.jasig.cas.support.spnego.authentication.principal.SpnegoCredential;
import javax.security.auth.login.FailedLoginException;
import java.security.GeneralSecurityException;
import java.util.regex.Pattern;
/**
* Implementation of an AuthenticationHandler for SPNEGO supports. This Handler
* support both NTLM and Kerberos. NTLM is disabled by default.
*
* @author Arnaud Lesueur
* @author Marc-Antoine Garrigue
* @author Scott Battaglia
* @author Marvin S. Addison
* @since 3.1
*/
public final class JcifsSpnegoAuthenticationHandler extends AbstractPreAndPostProcessingAuthenticationHandler {
private Authentication authentication;
/**
* Principal contains the DomainName ? (true by default).
*/
private boolean principalWithDomainName = true;
/**
* Allow SPNEGO/NTLM Token as valid credentials. (false by default)
*/
private boolean isNTLMallowed;
@Override
protected HandlerResult doAuthentication(final Credential credential) throws GeneralSecurityException, PreventedException {
final SpnegoCredential spnegoCredential = (SpnegoCredential) credential;
java.security.Principal principal;
byte[] nextToken;
if (!this.isNTLMallowed && spnegoCredential.isNtlm()) {
throw new FailedLoginException("NTLM not allowed");
}
try {
// proceed authentication using jcifs
synchronized (this) {
this.authentication.reset();
this.authentication.process(spnegoCredential.getInitToken());
principal = this.authentication.getPrincipal();
nextToken = this.authentication.getNextToken();
}
} catch (final jcifs.spnego.AuthenticationException e) {
throw new FailedLoginException(e.getMessage());
}
// evaluate jcifs response
if (nextToken != null) {
logger.debug("Setting nextToken in credential");
spnegoCredential.setNextToken(nextToken);
} else {
logger.debug("nextToken is null");
}
boolean success = false;
if (principal != null) {
if (spnegoCredential.isNtlm()) {
logger.debug("NTLM Credential is valid for user [{}]", principal.getName());
} else {
logger.debug("Kerberos Credential is valid for user [{}]", principal.getName());
}
spnegoCredential.setPrincipal(getPrincipal(principal.getName(), spnegoCredential.isNtlm()));
success = true;
}
if (!success) {
throw new FailedLoginException("Principal is null, the processing of the SPNEGO Token failed");
}
return new DefaultHandlerResult(this, new BasicCredentialMetaData(credential), spnegoCredential.getPrincipal());
}
@Override
public boolean supports(final Credential credential) {
return credential instanceof SpnegoCredential;
}
public void setAuthentication(final Authentication authentication) {
this.authentication = authentication;
}
public void setPrincipalWithDomainName(final boolean principalWithDomainName) {
this.principalWithDomainName = principalWithDomainName;
}
public void setNTLMallowed(final boolean isNTLMallowed) {
this.isNTLMallowed = isNTLMallowed;
}
/**
* Gets the principal from the given name. The principal
* is created by the factory instance.
*
* @param name the name
* @param isNtlm the is ntlm
* @return the simple principal
*/
protected Principal getPrincipal(final String name, final boolean isNtlm) {
if (this.principalWithDomainName) {
return this.principalFactory.createPrincipal(name);
}
if (isNtlm) {
return Pattern.matches("\\S+\\\\\\S+", name)
? this.principalFactory.createPrincipal(name.split("\\\\")[1])
: this.principalFactory.createPrincipal(name);
}
return this.principalFactory.createPrincipal(name.split("@")[0]);
}
}
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