First parts of SAML login module
git-svn-id: https://svn.libreccm.org/ccm/trunk@6167 8810af33-2d31-482b-a856-94f89814c4dfmaster^2^2^2^2^2^2
parent
559bf5f10a
commit
288dd00ca1
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.arsdigita.kernel.security;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||
import javax.security.auth.login.LoginException;
|
||||
import javax.security.auth.spi.LoginModule;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class SamlLoginModule implements LoginModule {
|
||||
|
||||
private CallbackHandler callbackHandler;
|
||||
private HttpServletRequest request;
|
||||
private HttpServletResponse response;
|
||||
private Subject subject;
|
||||
|
||||
@Override
|
||||
public void initialize(final Subject subject,
|
||||
final CallbackHandler callbackHandler,
|
||||
final Map<String, ?> sharedState,
|
||||
final Map<String, ?> options) {
|
||||
|
||||
this.callbackHandler = callbackHandler;
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean login() throws LoginException {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean commit() throws LoginException {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean abort() throws LoginException {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean logout() throws LoginException {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
protected HttpServletRequest getRequest() throws LoginException {
|
||||
|
||||
try {
|
||||
if (request == null) {
|
||||
final HTTPRequestCallback callback = new HTTPRequestCallback();
|
||||
callbackHandler.handle(new Callback[]{callback});
|
||||
request = callback.getRequest();
|
||||
}
|
||||
return request;
|
||||
} catch (IOException | UnsupportedCallbackException ex) {
|
||||
throw new LoginException("Could not get HTTP request" + ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected HttpServletResponse getResponse() throws LoginException {
|
||||
|
||||
try {
|
||||
if (response == null) {
|
||||
final HTTPResponseCallback callback = new HTTPResponseCallback();
|
||||
callbackHandler.handle(new Callback[]{callback});
|
||||
response = callback.getResponse();
|
||||
}
|
||||
return response;
|
||||
} catch (IOException | UnsupportedCallbackException ex) {
|
||||
throw new LoginException("Could not get HTTP response" + ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -36,8 +36,8 @@ import org.apache.log4j.Logger;
|
|||
/**
|
||||
* A record containing server-session scoped security configuration properties.
|
||||
*
|
||||
* Accessors of this class may return null. Developers should take care
|
||||
* to trap null return values in their code.
|
||||
* Accessors of this class may return null. Developers should take care to trap
|
||||
* null return values in their code.
|
||||
*
|
||||
*
|
||||
* @author Rafael H. Schloming <rhs@mit.edu>
|
||||
|
|
@ -49,10 +49,14 @@ public class SecurityConfig extends AbstractConfig {
|
|||
private static final Logger s_log = Logger.getLogger(SecurityConfig.class);
|
||||
private static SecurityConfig s_config = null;
|
||||
private static String s_systemAdministratorEmailAddress = null;
|
||||
/** Size of secret key in bytes. **/
|
||||
/**
|
||||
* Size of secret key in bytes. *
|
||||
*/
|
||||
public static int SECRET_KEY_BYTES = 16;
|
||||
/** The class name of the SecurityHelper implementation. Must implement
|
||||
SecurityHelper interface */
|
||||
/**
|
||||
* The class name of the SecurityHelper implementation. Must implement
|
||||
* SecurityHelper interface
|
||||
*/
|
||||
private final Parameter m_securityHelperClass = new SpecificClassParameter(
|
||||
"waf.security_helper_class", Parameter.REQUIRED,
|
||||
com.arsdigita.kernel.security.DefaultSecurityHelper.class,
|
||||
|
|
@ -60,10 +64,12 @@ public class SecurityConfig extends AbstractConfig {
|
|||
// /** This parameter is obsolete. */
|
||||
// private final Parameter m_sessionTrackingMethod = new StringParameter
|
||||
// ("waf.session_tracking_method", Parameter.REQUIRED, "cookie");
|
||||
/** List of extensions excluded from authentication cookies.
|
||||
* Authentication is checked for all requests, but requests with one of
|
||||
* these extensions will never cause a new cookie to be set.
|
||||
* Include a leading dot for each extension. */
|
||||
/**
|
||||
* List of extensions excluded from authentication cookies. Authentication
|
||||
* is checked for all requests, but requests with one of these extensions
|
||||
* will never cause a new cookie to be set. Include a leading dot for each
|
||||
* extension.
|
||||
*/
|
||||
private final Parameter m_excludedExtensions = new StringArrayParameter(
|
||||
"waf.excluded_extensions", Parameter.REQUIRED,
|
||||
new String[]{".jpg", ".gif", ".png", ".pdf"});
|
||||
|
|
@ -126,12 +132,77 @@ public class SecurityConfig extends AbstractConfig {
|
|||
"waf.admin.contact_email", Parameter.OPTIONAL, null);
|
||||
private final Parameter m_autoRegistrationOn = new BooleanParameter(
|
||||
"waf.auto_registration_on", Parameter.REQUIRED, Boolean.TRUE);
|
||||
private final Parameter m_userBanOn = new BooleanParameter("waf.user_ban_on",
|
||||
private final Parameter m_userBanOn
|
||||
= new BooleanParameter("waf.user_ban_on",
|
||||
Parameter.REQUIRED,
|
||||
Boolean.FALSE);
|
||||
private final Parameter m_enableQuestion = new BooleanParameter(
|
||||
"waf.user_question.enable", Parameter.REQUIRED, Boolean.FALSE);
|
||||
|
||||
private final Parameter m_enableSaml = new BooleanParameter(
|
||||
"waf.enable_saml", Parameter.REQUIRED, Boolean.FALSE);
|
||||
private final Parameter m_oneLoginSaml2Strict = new BooleanParameter(
|
||||
"waf.onelogin.saml2.strict", Parameter.REQUIRED, Boolean.TRUE);
|
||||
private final Parameter m_oneLoginSaml2Debug = new BooleanParameter(
|
||||
"waf.onelogin.saml2.debug", Parameter.REQUIRED, Boolean.FALSE);
|
||||
private final Parameter m_oneLoginSaml2SpEntityId = new StringParameter(
|
||||
"waf.onelogin.saml2.sp.entityid",
|
||||
Parameter.REQUIRED,
|
||||
"http://localhost:8080/ccm-saml/metadata");
|
||||
private final Parameter m_oneLoginSaml2SpAssertationConsumerServiceUrl
|
||||
= new StringParameter(
|
||||
"waf.onelogin.saml2.sp.assertion_consumer_service.url",
|
||||
Parameter.REQUIRED,
|
||||
"http://localhost:8080/ccm-saml/acs");
|
||||
private final Parameter m_oneLoginSaml2SpAssertationConsumerServiceBinding
|
||||
= new StringParameter(
|
||||
"waf.onelogin.saml2.sp.assertion_consumer_service.binding",
|
||||
Parameter.REQUIRED,
|
||||
"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST");
|
||||
private final Parameter m_oneLoginSaml2SpSingleLogoutServiceUrl
|
||||
= new StringParameter(
|
||||
"waf.onelogin.saml2.sp.single_logout_service.url",
|
||||
Parameter.REQUIRED,
|
||||
"http://localhost:8080/ccm-saml/sls");
|
||||
private final Parameter m_oneLoginSaml2SpSingleLogoutServiceBinding
|
||||
= new StringParameter(
|
||||
"waf.onelogin.saml2.sp.single_logout_service.binding",
|
||||
Parameter.REQUIRED,
|
||||
"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect");
|
||||
private final Parameter m_oneLoginSaml2SpNameIdFormat = new StringParameter(
|
||||
"waf.onelogin.saml2.sp.nameidformat",
|
||||
Parameter.REQUIRED,
|
||||
"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified");
|
||||
private final Parameter m_oneLoginSaml2IdpEntityId = new StringParameter(
|
||||
"waf.onelogin.saml2.idp.entityid",
|
||||
Parameter.REQUIRED,
|
||||
"");
|
||||
private final Parameter m_oneLoginSaml2IdpSingleSignOnServiceUrl
|
||||
= new StringParameter(
|
||||
"waf.onelogin.saml2.idp.single_sign_on_service.url",
|
||||
Parameter.REQUIRED,
|
||||
"");
|
||||
private final Parameter m_oneLoginSaml2IdpSingleSignOnServiceBinding
|
||||
= new StringParameter(
|
||||
"waf.onelogin.saml2.idp.single_sign_on_service.binding",
|
||||
Parameter.REQUIRED,
|
||||
"");
|
||||
private final Parameter m_oneLoginSaml2IdpSingleLogoutServiceUrl
|
||||
= new StringParameter(
|
||||
"waf.onelogin.saml2.idp.single_logout_service.url",
|
||||
Parameter.REQUIRED,
|
||||
"");
|
||||
private final Parameter m_oneLoginSaml2IdpSingleLogoutServiceResponseUrl
|
||||
= new StringParameter(
|
||||
"waf.onelogin.saml2.idp.single_logout_service.response.url",
|
||||
Parameter.REQUIRED,
|
||||
"");
|
||||
private final Parameter m_oneLoginSaml2IdpSingleLogoutServiceBinding
|
||||
= new StringParameter(
|
||||
"waf.onelogin.saml2.idp.single_logout_service.binding",
|
||||
Parameter.REQUIRED,
|
||||
"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect");
|
||||
|
||||
/**
|
||||
* Constructs an empty SecurityConfig object
|
||||
*/
|
||||
|
|
@ -149,12 +220,28 @@ public class SecurityConfig extends AbstractConfig {
|
|||
register(m_userBanOn);
|
||||
register(m_enableQuestion);
|
||||
|
||||
register(m_enableSaml);
|
||||
|
||||
register(m_oneLoginSaml2Debug);
|
||||
register(m_oneLoginSaml2IdpEntityId);
|
||||
register(m_oneLoginSaml2IdpSingleLogoutServiceBinding);
|
||||
register(m_oneLoginSaml2IdpSingleLogoutServiceResponseUrl);
|
||||
register(m_oneLoginSaml2IdpSingleLogoutServiceUrl);
|
||||
register(m_oneLoginSaml2IdpSingleSignOnServiceBinding);
|
||||
register(m_oneLoginSaml2IdpSingleSignOnServiceUrl);
|
||||
register(m_oneLoginSaml2SpAssertationConsumerServiceBinding);
|
||||
register(m_oneLoginSaml2SpAssertationConsumerServiceUrl);
|
||||
register(m_oneLoginSaml2SpEntityId);
|
||||
register(m_oneLoginSaml2SpNameIdFormat);
|
||||
register(m_oneLoginSaml2SpSingleLogoutServiceBinding);
|
||||
register(m_oneLoginSaml2SpSingleLogoutServiceUrl);
|
||||
register(m_oneLoginSaml2Strict);
|
||||
|
||||
loadInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the singleton configuration record for the runtime
|
||||
* environment.
|
||||
* Returns the singleton configuration record for the runtime environment.
|
||||
*
|
||||
* @return The <code>RuntimeConfig</code> record; it cannot be null
|
||||
*/
|
||||
|
|
@ -220,8 +307,7 @@ public class SecurityConfig extends AbstractConfig {
|
|||
|
||||
private static synchronized String getSystemAdministratorEmailAddress() {
|
||||
if (s_systemAdministratorEmailAddress == null) {
|
||||
ObjectPermissionCollection perms =
|
||||
PermissionService.
|
||||
ObjectPermissionCollection perms = PermissionService.
|
||||
getGrantedUniversalPermissions();
|
||||
perms.addEqualsFilter("granteeIsUser", Boolean.TRUE);
|
||||
perms.clearOrder();
|
||||
|
|
@ -242,4 +328,67 @@ public class SecurityConfig extends AbstractConfig {
|
|||
public final boolean isAutoRegistrationOn() {
|
||||
return ((Boolean) get(m_autoRegistrationOn)).booleanValue();
|
||||
}
|
||||
|
||||
public final boolean getEnableSaml() {
|
||||
return (Boolean) get(m_enableSaml);
|
||||
}
|
||||
|
||||
public final Boolean getOneLoginSaml2Strict() {
|
||||
return (Boolean) get(m_oneLoginSaml2Strict);
|
||||
}
|
||||
|
||||
public final Boolean getM_oneLoginSaml2Debug() {
|
||||
return (boolean) get(m_oneLoginSaml2Debug);
|
||||
}
|
||||
|
||||
public final String getM_oneLoginSaml2SpEntityId() {
|
||||
return (String) get(m_oneLoginSaml2SpEntityId);
|
||||
}
|
||||
|
||||
public final String getOneLoginSaml2SpAssertationConsumerServiceUrl() {
|
||||
return (String) get(m_oneLoginSaml2SpAssertationConsumerServiceUrl);
|
||||
}
|
||||
|
||||
public final String getOneLoginSaml2SpAssertationConsumerServiceBinding() {
|
||||
return (String) get(m_oneLoginSaml2SpAssertationConsumerServiceBinding);
|
||||
}
|
||||
|
||||
public final String getOneLoginSaml2SpSingleLogoutServiceUrl() {
|
||||
return (String) get(m_oneLoginSaml2SpSingleLogoutServiceUrl);
|
||||
}
|
||||
|
||||
public final String getOneLoginSaml2SpSingleLogoutServiceBinding() {
|
||||
return (String) get(m_oneLoginSaml2SpSingleLogoutServiceBinding);
|
||||
}
|
||||
|
||||
public final String getOneLoginSaml2SpNameIdFormat() {
|
||||
return (String) get(m_oneLoginSaml2SpNameIdFormat);
|
||||
}
|
||||
|
||||
public final String getOneLoginSaml2IdpEntityId() {
|
||||
return (String) get(m_oneLoginSaml2IdpEntityId);
|
||||
}
|
||||
|
||||
public final String getOneLoginSaml2IdpSingleSignOnServiceUrl() {
|
||||
return (String) get(m_oneLoginSaml2IdpSingleSignOnServiceUrl);
|
||||
}
|
||||
|
||||
public final String getOneLoginSaml2IdpSingleSignOnServiceBinding() {
|
||||
return (String) get(m_oneLoginSaml2IdpSingleSignOnServiceBinding);
|
||||
}
|
||||
|
||||
public final String getOneLoginSaml2IdpSingleLogoutServiceUrl() {
|
||||
return (String) get(m_oneLoginSaml2IdpSingleLogoutServiceUrl);
|
||||
}
|
||||
|
||||
public final String getOneLoginSaml2IdpSingleLogoutServiceResponseUrl() {
|
||||
return (String) get(m_oneLoginSaml2IdpSingleLogoutServiceResponseUrl);
|
||||
}
|
||||
|
||||
public final String getOneLoginSaml2IdpSingleLogoutServiceBinding() {
|
||||
return (String) get(m_oneLoginSaml2IdpSingleLogoutServiceBinding);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,81 @@ waf.user_question_enable.purpose=Enable question if a user has forgotten its pas
|
|||
waf.user_question_enable.example=false
|
||||
waf.user_question_enable.format=true|false
|
||||
|
||||
waf.enable_saml.title=Enable SAML
|
||||
waf.enable_saml.purpose=Enable authentication via SAML
|
||||
waf.enable_saml.example=false
|
||||
waf.enable_saml.format=true|false
|
||||
|
||||
waf.onelogin.saml2.strict.title=Strict mode for OneLogin
|
||||
waf.onelogin.saml2.strict.purpose=
|
||||
waf.onelogin.saml2.strict.example=true
|
||||
waf.onelogin.saml2.strict.format=true|false
|
||||
|
||||
waf.onelogin.saml2.debug.title=Enable OneLogin debug messages
|
||||
waf.onelogin.saml2.debug.purpose=Show debug messages for SAML
|
||||
waf.onelogin.saml2.debug.example=false
|
||||
waf.onelogin.saml2.debug.format=true|false
|
||||
|
||||
waf.onelogin.saml2.sp.entityid.title=URL to informations about this application.
|
||||
waf.onelogin.saml2.sp.entityid.purpose
|
||||
waf.onelogin.saml2.sp.entityid.example=http://localhost:8080/ccm-saml/
|
||||
waf.onelogin.saml2.sp.entityid.format=[string]
|
||||
|
||||
waf.onelogin.saml2.sp.assertion_consumer_service.url.title=Consumer service URL
|
||||
waf.onelogin.saml2.sp.assertion_consumer_service.url.purpose
|
||||
waf.onelogin.saml2.sp.assertion_consumer_service.url.example=
|
||||
waf.onelogin.saml2.sp.assertion_consumer_service.url.format=[string]
|
||||
|
||||
waf.onelogin.saml2.sp.assertion_consumer_service.binding.title=Service binding
|
||||
waf.onelogin.saml2.sp.assertion_consumer_service.binding.purpose=
|
||||
waf.onelogin.saml2.sp.assertion_consumer_service.binding.example=
|
||||
waf.onelogin.saml2.sp.assertion_consumer_service.binding.format=[string]
|
||||
|
||||
waf.onelogin.saml2.sp.single_logout_service.url.title=Logout URL
|
||||
waf.onelogin.saml2.sp.single_logout_service.url.purpose=
|
||||
waf.onelogin.saml2.sp.single_logout_service.url.example=
|
||||
waf.onelogin.saml2.sp.single_logout_service.url.format=[string]
|
||||
|
||||
waf.onelogin.saml2.sp.single_logout_service.binding.title=Logout binding
|
||||
waf.onelogin.saml2.sp.single_logout_service.binding.purpose=
|
||||
waf.onelogin.saml2.sp.single_logout_service.binding.example=
|
||||
waf.onelogin.saml2.sp.single_logout_service.binding.format=[string]
|
||||
|
||||
waf.onelogin.saml2.sp.nameidformat.title=Name ID format
|
||||
waf.onelogin.saml2.sp.nameidformat.purpose=
|
||||
waf.onelogin.saml2.sp.nameidformat.example=
|
||||
waf.onelogin.saml2.sp.nameidformat.format=[string]
|
||||
|
||||
waf.onelogin.saml2.idp.entityid.title=IDP Entity ID
|
||||
waf.onelogin.saml2.idp.entityid.purpose=
|
||||
waf.onelogin.saml2.idp.entityid.example=
|
||||
waf.onelogin.saml2.idp.entityid.format=[string]
|
||||
|
||||
waf.onelogin.saml2.idp.single_sign_on_service.url.title=Single Sign On Service URL
|
||||
waf.onelogin.saml2.idp.single_sign_on_service.url.purpose=
|
||||
waf.onelogin.saml2.idp.single_sign_on_service.url.example=
|
||||
waf.onelogin.saml2.idp.single_sign_on_service.url.format=[string]
|
||||
|
||||
waf.onelogin.saml2.idp.single_sign_on_service.binding.title=Single Sign On Service URL
|
||||
waf.onelogin.saml2.idp.single_sign_on_service.binding.purpose=
|
||||
waf.onelogin.saml2.idp.single_sign_on_service.binding.example=
|
||||
waf.onelogin.saml2.idp.single_sign_on_service.binding.format=[string]
|
||||
|
||||
waf.onelogin.saml2.idp.single_logout_service.url.title=Single Logout Service URL
|
||||
waf.onelogin.saml2.idp.single_logout_service.url.purpose=
|
||||
waf.onelogin.saml2.idp.single_logout_service.url.example=
|
||||
waf.onelogin.saml2.idp.single_logout_service.url.format=[string]
|
||||
|
||||
waf.onelogin.saml2.idp.single_logout_service.response.url.title=Single Logout Service Response URL
|
||||
waf.onelogin.saml2.idp.single_logout_service.response.url.purpose=
|
||||
waf.onelogin.saml2.idp.single_logout_service.response.url.example=
|
||||
waf.onelogin.saml2.idp.single_logout_service.response.url.format=[string]
|
||||
|
||||
waf.onelogin.saml2.idp.single_logout_service.binding.title=Logout Service Binding
|
||||
waf.onelogin.saml2.idp.single_logout_service.binding.purpose=
|
||||
waf.onelogin.saml2.idp.single_logout_service.binding.example=
|
||||
waf.onelogin.saml2.idp.single_logout_service.binding.format=[string]
|
||||
|
||||
# Moved to com.arsdigita.ui.UIConfig (2011-02).
|
||||
# Retained here for easy reference during transition phase
|
||||
# waf.pagemap.root.title=Root Page
|
||||
|
|
|
|||
Loading…
Reference in New Issue