From 96af6ca8da1bfa0f6702f0244e874eac0b18ad70 Mon Sep 17 00:00:00 2001 From: "Aaron J. Zirbes" Date: Fri, 6 Jan 2012 17:57:48 -0600 Subject: [PATCH] logging is working --- .classpath | 73 +++++++++++++++---- .gitignore | 5 ++ .project | 9 ++- ...urityShibbolethNativeSpGrailsPlugin.groovy | 65 ++++++++--------- application.properties | 3 +- grails-app/conf/Config.groovy | 4 - .../DefaultShibbolethSecurityConfig.groovy | 3 + .../ShibbolethAuthenticationEntryPoint.groovy | 21 ++++-- .../sp/ShibbolethAuthenticationFilter.groovy | 20 +++-- .../ShibbolethAuthenticationProvider.groovy | 9 ++- .../sp/ShibbolethUserDetailsService.groovy | 5 ++ 11 files changed, 149 insertions(+), 68 deletions(-) diff --git a/.classpath b/.classpath index ebd5145..aa032fd 100644 --- a/.classpath +++ b/.classpath @@ -1,14 +1,61 @@ + - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.gitignore b/.gitignore index a256167..4a81997 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,8 @@ stacktrace.log .*.swp web-app/WEB-INF/tld/c.tld web-app/WEB-INF/tld/fmt.tld +.settings/com.springsource.sts.grails.core.prefs +.settings/org.eclipse.core.resources.prefs +grails-spring-security-shibboleth-native-sp-*.zip +plugin.xml +target-eclipse/ diff --git a/.project b/.project index 0ce1be7..5963bbe 100644 --- a/.project +++ b/.project @@ -12,8 +12,15 @@ - com.springsource.sts.grails.core.nature + com.springsource.sts.grails.core.nature org.eclipse.jdt.groovy.core.groovyNature org.eclipse.jdt.core.javanature + + + .link_to_grails_plugins + 2 + GRAILS_ROOT/1.3.7/projects/spring-security-shibboleth-native-sp/plugins + + diff --git a/SpringSecurityShibbolethNativeSpGrailsPlugin.groovy b/SpringSecurityShibbolethNativeSpGrailsPlugin.groovy index 9642aca..96fd172 100644 --- a/SpringSecurityShibbolethNativeSpGrailsPlugin.groovy +++ b/SpringSecurityShibbolethNativeSpGrailsPlugin.groovy @@ -1,3 +1,4 @@ +import edu.umn.shibboleth.sp.* import org.codehaus.groovy.grails.plugins.springsecurity.SecurityFilterPosition import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils @@ -16,7 +17,7 @@ class SpringSecurityShibbolethNativeSpGrailsPlugin { 'test/**' ] - // TODO Fill in these fields + // Fill in these fields def author = "Aaron J. Zirbes" def authorEmail = "ajz@umn.edu" def title = "Shibboleth Naitive SP support for the Spring Security grails plugin." @@ -30,28 +31,40 @@ class SpringSecurityShibbolethNativeSpGrailsPlugin { def conf = SpringSecurityUtils.securityConfig if (!conf || !conf.active) { return } - if (application.warDeployed) { - // need to load secondary here since web.xml was already built, so - // doWithWebDescriptor isn't called when deployed as war + SpringSecurityUtils.loadSecondaryConfig 'DefaultShibbolethSecurityConfig' + conf = SpringSecurityUtils.securityConfig + if (!conf.shibboleth.active) { return } - SpringSecurityUtils.loadSecondaryConfig 'DefaultShibbolethSecurityConfig' - conf = SpringSecurityUtils.securityConfig - if (!conf.shibboleth.active) { return } + // shibboleth authentication entry point + authenticationEntryPoint(ShibbolethAuthenticationEntryPoint) { + loginUrl = conf.shibboleth.loginUrl } - println 'Configuring Spring Security CAS ...' + // shibboleth user details service + shibbolethUserDetailsService(ShibbolethUserDetailsService) { + rolesAttribute = conf.shibboleth.roles.attribute + rolesSeparator = conf.shibboleth.roles.separator + rolesPrefix = conf.shibboleth.roles.prefix + authenticationMethodRoles = conf.shibboleth.authenticationMethod.roles + ipAddressRoles = conf.remoteaddress.roles + developmentRoles = conf.shibboleth.development.roles + } - SpringSecurityUtils.registerProvider 'shibbolethAuthenticationProvider' - SpringSecurityUtils.registerFilter 'shibbolethAuthenticationFilter', SecurityFilterPosition.CAS_FILTER + 20 + // shibboleth authentication provider + shibbolethAuthenticationProvider(ShibbolethAuthenticationProvider) { + userDetailsService = ref('shibbolethUserDetailsService') + identityProviderAllowed = conf.shibboleth.identityProvider.attribute + authenticationMethodAllowed = conf.shibboleth.authenticationMethod.allowed + } - // custom authentication filter + // shibboleth authentication filter shibbolethAuthenticationFilter(ShibbolethAuthenticationFilter) { + authenticationDetailsSource = ref('authenticationDetailsSource') + authenticationFailureHandler = ref('authenticationFailureHandler') authenticationManager = ref('authenticationManager') - sessionAuthenticationStrategy = ref('sessionAuthenticationStrategy') authenticationSuccessHandler = ref('authenticationSuccessHandler') - authenticationFailureHandler = ref('authenticationFailureHandler') rememberMeServices = ref('rememberMeServices') - authenticationDetailsSource = ref('authenticationDetailsSource') + sessionAuthenticationStrategy = ref('sessionAuthenticationStrategy') principalUsernameAttribute = conf.shibboleth.principalUsername.attribute authenticationMethodAttribute = conf.shibboleth.authenticationMethod.attribute @@ -61,27 +74,9 @@ class SpringSecurityShibbolethNativeSpGrailsPlugin { extraAttributes = conf.shibboleth.extraAttributes } - // custom authentication provider - shibbolethAuthenticationProvider(ShibbolethAuthenticationProvider) { - userDetailsService = ref('shibbolethUserDetailsService') - identityProviderAllowed = conf.shibboleth.identityProvider.attribute - authenticationMethodAllowed = conf.shibboleth.authenticationMethod.allowed - } - - // custom user details service - shibbolethUserDetailsService(ShibbolethUserDetailsService) { - rolesAttribute = conf.shibboleth.roles.attribute - rolesSeparator = conf.shibboleth.roles.separator - rolesPrefix = conf.shibboleth.roles.prefix - authenticationMethodRoles = conf.shibboleth.authenticationMethod.roles - ipAddressRoles = conf.remoteaddress.roles - developmentRoles = conf.shibboleth.development.roles - } + println 'Configuring Spring Security CAS ...' + SpringSecurityUtils.registerProvider 'shibbolethAuthenticationProvider' + SpringSecurityUtils.registerFilter 'shibbolethAuthenticationFilter', SecurityFilterPosition.CAS_FILTER - // custom authentication entry point - authenticationEntryPoint(ShibbolethAuthenticationEntryPoint) { - loginUrl = conf.shibboleth.loginUrl - targetVariable = conf.shibboleth.loginTargetVariable - } } } diff --git a/application.properties b/application.properties index 2bdb82f..81307e4 100644 --- a/application.properties +++ b/application.properties @@ -1,6 +1,7 @@ #Grails Metadata file -#Tue Dec 06 15:54:01 CST 2011 +#Tue Jan 03 21:27:30 CST 2012 app.grails.version=1.3.7 app.name=spring-security-shibboleth-native-sp plugins.hibernate=1.3.7 +plugins.spring-security-core=1.2.7 plugins.tomcat=1.3.7 diff --git a/grails-app/conf/Config.groovy b/grails-app/conf/Config.groovy index a95f9e0..cf8c4b1 100644 --- a/grails-app/conf/Config.groovy +++ b/grails-app/conf/Config.groovy @@ -153,10 +153,6 @@ grails.plugins.springsecurity.shibboleth.development.environment = [ 'Shib-AuthnContext-Class': 'urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified', 'Shib-Session-ID': '_58872da8c49da55e94bf1c68c7c12745' ] -grails.plugins.springsecurity.shibboleth.loginUrl = '/Shibboleth.sso/Login' -grails.plugins.springsecurity.shibboleth.loginTargetVariable = 'target' - - // Added by the Spring Security Core plugin: //grails.plugins.springsecurity.userLookup.userDomainClassName = 'edu.umn.idm.User' //grails.plugins.springsecurity.userLookup.authorityJoinClassName = 'edu.umn.idm.UserRole' diff --git a/grails-app/conf/DefaultShibbolethSecurityConfig.groovy b/grails-app/conf/DefaultShibbolethSecurityConfig.groovy index b7e09a3..b3a32c2 100644 --- a/grails-app/conf/DefaultShibbolethSecurityConfig.groovy +++ b/grails-app/conf/DefaultShibbolethSecurityConfig.groovy @@ -1,5 +1,8 @@ security { shibboleth { + // Disabled by default + active = false + // Used by Controllers loginUrl = '/Shibboleth.sso/Login?target={0}' logoutUrl = '/Shibboleth.sso/Logout' diff --git a/src/groovy/edu/umn/shibboleth/sp/ShibbolethAuthenticationEntryPoint.groovy b/src/groovy/edu/umn/shibboleth/sp/ShibbolethAuthenticationEntryPoint.groovy index fd5dca5..e6f9a52 100644 --- a/src/groovy/edu/umn/shibboleth/sp/ShibbolethAuthenticationEntryPoint.groovy +++ b/src/groovy/edu/umn/shibboleth/sp/ShibbolethAuthenticationEntryPoint.groovy @@ -1,30 +1,37 @@ package edu.umn.shibboleth.sp -import java.net.URLEncoder import java.io.IOException - +import java.net.URLEncoder import javax.servlet.ServletException import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse +import org.apache.log4j.Logger import org.springframework.beans.factory.InitializingBean import org.springframework.security.core.AuthenticationException import org.springframework.security.web.AuthenticationEntryPoint import org.springframework.util.Assert +/** + Processes a login request and redirects to shibboleth login + + @author Aaron J. Zirbes +*/ class ShibbolethAuthenticationEntryPoint implements AuthenticationEntryPoint, InitializingBean { + private static final log = Logger.getLogger(this) + /** This is the SP login URL, typically this is '/Shibboleth.sso/Login', but you can change it if your implementation is different */ - String loginUrl = '/Shibboleth.sso/Login' - String targetVariable = 'target' + String loginUrl = '/Shibboleth.sso/Login?target={0}' public void afterPropertiesSet() throws Exception { Assert.hasLength(loginUrl, "loginUrl must be specified") - Assert.hasLength(targetVariable, "targetVariable must be specified") } public final void commence(final HttpServletRequest servletRequest, final HttpServletResponse response, - final AuthenticationException authenticationException) throws IOException, ServletException { + final AuthenticationException authenticationException) throws IOException, ServletException { + + log.debug("commence():: invocation") final String redirectUrl = createRedirectUrl(servletRequest, response) @@ -36,7 +43,7 @@ class ShibbolethAuthenticationEntryPoint implements AuthenticationEntryPoint, In private String createRedirectUrl(final HttpServletRequest request, final HttpServletResponse response) { String uri = request.getRequestURI() String returnUrl = URLEncoder.encode(uri.toString(), "ISO-8859-1") - return loginUrl + '?' + targetVariable + '=' + returnUrl + return loginUrl.replace("{0}", returnUrl) } /** diff --git a/src/groovy/edu/umn/shibboleth/sp/ShibbolethAuthenticationFilter.groovy b/src/groovy/edu/umn/shibboleth/sp/ShibbolethAuthenticationFilter.groovy index 21d5d7d..5b7100b 100644 --- a/src/groovy/edu/umn/shibboleth/sp/ShibbolethAuthenticationFilter.groovy +++ b/src/groovy/edu/umn/shibboleth/sp/ShibbolethAuthenticationFilter.groovy @@ -1,14 +1,18 @@ package edu.umn.shibboleth.sp +import java.io.IOException +import javax.servlet.FilterChain +import javax.servlet.ServletException import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse -import javax.servlet.FilterChain -import org.springframework.security.core.Authentication +import org.apache.log4j.Logger +import org.codehaus.groovy.grails.plugins.springsecurity.SecurityFilterPosition import org.springframework.security.authentication.AuthenticationManager import org.springframework.security.authentication.AuthenticationProvider -import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter -import org.codehaus.groovy.grails.plugins.springsecurity.SecurityFilterPosition +import org.springframework.security.core.Authentication +import org.springframework.security.core.AuthenticationException import org.springframework.security.core.context.SecurityContextHolder +import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter // https://github.com/grails-plugins/grails-spring-security-core/blob/master/src/java/org/codehaus/groovy/grails/plugins/springsecurity/SecurityFilterPosition.java @@ -19,6 +23,8 @@ import org.springframework.security.core.context.SecurityContextHolder */ class ShibbolethAuthenticationFilter extends AbstractAuthenticationProcessingFilter { + private static final log = Logger.getLogger(this) + // configuration settings + default values // def principalUsernameAttribute = 'EPPN' String principalUsernameAttribute = null @@ -31,17 +37,21 @@ class ShibbolethAuthenticationFilter extends AbstractAuthenticationProcessingFil /** The default constructor */ public ShibbolethAuthenticationFilter() { super("/j_spring_shibboleth_native_sp_security_check") + log.debug "instantiation" } /** Try logging in the user via Shibboleth Native SP */ - @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) { Authentication token = null ShibbolethAuthenticationToken shibbolethAuthenticationToken = null + log.debug "attemptAuthentication():: invocation" + if (SecurityContextHolder.getContext().getAuthentication() == null) { + log.debug "attemptAuthentication():: authenticating" + // These are set by mod_shib22 in Apache and passed through mod_jk // to the servlet (Tomcat, Glassfish, etc..) // This means you MUST trust the assertions chain made by mod_jk, and in diff --git a/src/groovy/edu/umn/shibboleth/sp/ShibbolethAuthenticationProvider.groovy b/src/groovy/edu/umn/shibboleth/sp/ShibbolethAuthenticationProvider.groovy index 65a997e..511d77e 100644 --- a/src/groovy/edu/umn/shibboleth/sp/ShibbolethAuthenticationProvider.groovy +++ b/src/groovy/edu/umn/shibboleth/sp/ShibbolethAuthenticationProvider.groovy @@ -1,5 +1,6 @@ package edu.umn.shibboleth.sp +import org.apache.log4j.Logger import org.springframework.beans.factory.InitializingBean import org.springframework.security.authentication.AuthenticationProvider import org.springframework.security.authentication.BadCredentialsException @@ -22,13 +23,15 @@ import org.springframework.util.Assert */ class ShibbolethAuthenticationProvider implements AuthenticationProvider, InitializingBean { + private static final log = Logger.getLogger(this) + // injected service(s) def userDetailsService // configuration settings + default values // def principalUsernameAttribute = 'EPPN' - String identityProviderAllowed = null - String authenticationMethodAllowed = null + Collection identityProviderAllowed = null + Collection authenticationMethodAllowed = null // injected configuration parameters @@ -37,6 +40,8 @@ class ShibbolethAuthenticationProvider implements AuthenticationProvider, Initia */ Authentication authenticate(Authentication authentication) throws AuthenticationException { + log.debug("ShibbolethAuthenticationProvider.authenticate():: invocation") + // exit if unsupported token is passed if (!supports(authentication.getClass())) { return null diff --git a/src/groovy/edu/umn/shibboleth/sp/ShibbolethUserDetailsService.groovy b/src/groovy/edu/umn/shibboleth/sp/ShibbolethUserDetailsService.groovy index d6d70c3..4d30dcf 100644 --- a/src/groovy/edu/umn/shibboleth/sp/ShibbolethUserDetailsService.groovy +++ b/src/groovy/edu/umn/shibboleth/sp/ShibbolethUserDetailsService.groovy @@ -1,5 +1,6 @@ package edu.umn.shibboleth.sp +import org.apache.commons.logging.LogFactory import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils import org.springframework.security.core.GrantedAuthority import org.springframework.security.core.Authentication @@ -26,6 +27,9 @@ import org.springframework.security.web.util.IpAddressMatcher @author Aaron J. Zirbes */ class ShibbolethUserDetailsService implements UserDetailsService, AuthenticationUserDetailsService { + + private static final log = LogFactory.getLog(this) + /** * This is to support the {@code RememberMeService} */ @@ -70,6 +74,7 @@ class ShibbolethUserDetailsService implements UserDetailsService, Authentication */ UserDetails loadUserDetails(Authentication authentication) throws UsernameNotFoundException { + log.debug("ShibbolethUserDetailsService.loadUserDetails():: invocation") // set default values def username = authentication.name