Navigation Menu

Skip to content

Commit

Permalink
GRAILSPLUGINS-2248 and GRAILSPLUGINS-2241
Browse files Browse the repository at this point in the history
  • Loading branch information
burtbeckwith committed Jun 29, 2010
1 parent d5dbe2f commit 60882b8
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 6 deletions.
19 changes: 13 additions & 6 deletions SpringSecurityCoreGrailsPlugin.groovy
Expand Up @@ -13,7 +13,6 @@
* limitations under the License.
*/
import grails.plugins.springsecurity.DigestAuthPasswordEncoder
import grails.plugins.springsecurity.SecurityConfigType

import javax.servlet.Filter

Expand All @@ -26,6 +25,7 @@ import org.springframework.security.access.vote.RoleHierarchyVoter
import org.springframework.security.authentication.AccountStatusUserDetailsChecker
import org.springframework.security.authentication.AnonymousAuthenticationProvider
import org.springframework.security.authentication.AuthenticationTrustResolverImpl
import org.springframework.security.authentication.DefaultAuthenticationEventPublisher
import org.springframework.security.authentication.ProviderManager
import org.springframework.security.authentication.RememberMeAuthenticationProvider
import org.springframework.security.authentication.dao.DaoAuthenticationProvider
Expand Down Expand Up @@ -90,6 +90,7 @@ import org.codehaus.groovy.grails.plugins.springsecurity.GormUserDetailsService
import org.codehaus.groovy.grails.plugins.springsecurity.InterceptUrlMapFilterInvocationDefinition
import org.codehaus.groovy.grails.plugins.springsecurity.IpAddressFilter
import org.codehaus.groovy.grails.plugins.springsecurity.MutableLogoutFilter
import org.codehaus.groovy.grails.plugins.springsecurity.NullAuthenticationEventPublisher
import org.codehaus.groovy.grails.plugins.springsecurity.NullSaltSource
import org.codehaus.groovy.grails.plugins.springsecurity.RequestmapFilterInvocationDefinition
import org.codehaus.groovy.grails.plugins.springsecurity.RequestHolderAuthenticationFilter
Expand All @@ -104,15 +105,15 @@ import org.codehaus.groovy.grails.plugins.springsecurity.WebExpressionVoter
*/
class SpringSecurityCoreGrailsPlugin {

String version = '0.4'
String version = '0.4.1'
String grailsVersion = '1.2.2 > *'
List observe = ['controllers']
List loadAfter = ['controllers', 'services', 'hibernate']

List pluginExcludes = [
'grails-app/domain/**',
'scripts/_Events.groovy',
'scripts/CreateTestApp.groovy',
'scripts/CreateS2TestApps.groovy',
'docs/**',
'src/docs/**'
]
Expand Down Expand Up @@ -374,6 +375,11 @@ class SpringSecurityCoreGrailsPlugin {
// SecurityEventListener
if (conf.useSecurityEventListener) {
securityEventListener(SecurityEventListener)

authenticationEventPublisher(DefaultAuthenticationEventPublisher)
}
else {
authenticationEventPublisher(NullAuthenticationEventPublisher)
}

// Basic Auth
Expand Down Expand Up @@ -462,7 +468,7 @@ class SpringSecurityCoreGrailsPlugin {
addControllerMethods controllerClass.metaClass, ctx
}

if (conf.securityConfigType == SecurityConfigType.Annotation) {
if (conf.securityConfigType.name() == 'Annotation') {
ctx.objectDefinitionSource.initialize conf.controllerAnnotations.staticRules,
ctx.grailsUrlMappingsHolder, application.controllerClasses
}
Expand Down Expand Up @@ -539,7 +545,7 @@ class SpringSecurityCoreGrailsPlugin {

if (event.source && application.isControllerClass(event.source)) {

if (conf.securityConfigType == SecurityConfigType.Annotation) {
if (conf.securityConfigType.name() == 'Annotation') {
event.ctx.objectDefinitionSource.initialize conf.controllerAnnotations.staticRules,
event.ctx.grailsUrlMappingsHolder, application.controllerClasses
}
Expand All @@ -555,7 +561,7 @@ class SpringSecurityCoreGrailsPlugin {
return
}

if (conf.securityConfigType == SecurityConfigType.Annotation) {
if (conf.securityConfigType.name() == 'Annotation') {
// might have changed controllerAnnotations.staticRules
event.ctx.objectDefinitionSource.initialize conf.controllerAnnotations.staticRules,
event.ctx.grailsUrlMappingsHolder, application.controllerClasses
Expand Down Expand Up @@ -669,6 +675,7 @@ class SpringSecurityCoreGrailsPlugin {
/** authenticationManager */
authenticationManager(ProviderManager) {
providers = providerRefs
authenticationEventPublisher = ref('authenticationEventPublisher')
}
}

Expand Down
@@ -0,0 +1,30 @@
package org.codehaus.groovy.grails.plugins.springsecurity;

import org.springframework.security.authentication.AuthenticationEventPublisher;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

/**
* @author <a href='mailto:burt@burtbeckwith.com'>Burt Beckwith</a>
*/
public class NullAuthenticationEventPublisher implements AuthenticationEventPublisher {

/**
* {@inheritDoc}
* @see org.springframework.security.authentication.AuthenticationEventPublisher#publishAuthenticationFailure(
* org.springframework.security.core.AuthenticationException,
* org.springframework.security.core.Authentication)
*/
public void publishAuthenticationFailure(AuthenticationException e, Authentication a) {
// do nothing
}

/**
* {@inheritDoc}
* @see org.springframework.security.authentication.AuthenticationEventPublisher#publishAuthenticationSuccess(
* org.springframework.security.core.Authentication)
*/
public void publishAuthenticationSuccess(Authentication a) {
// do nothing
}
}

6 comments on commit 60882b8

@kalarani
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple of things

  1. The NullAuthenticationEventPublisher in the plugin is not required since its defaulted by spring itself for the ProviderManager.
  2. The DefaultAuthenticationEventPublisher is now added only if user has configured to use Security Listener. One might choose to listen to events without setting the configuration, as they can implement the ApplicationListener directly and expect events to be thrown. Either useSecurityListener should be true by default or the DefaultAuthenticationEventPublisher should always be injected

@burtbeckwith
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The NullAuthenticationEventPublisher is required because the ProviderManager bean is configured separately from the event publisher. Doing it the way I did creates an 'authenticationEventPublisher' bean either way. So you have three options: don't use any events (useSecurityListener=false), use events the way I've configured them (useSecurityListener=true), or override the 'authenticationEventPublisher' bean in resources.groovy with a custom implementation.

This pattern is used throughout the plugin, where I create the same bean that Spring Security would have created by default, but by explicitly creating it as an injected named bean it can be overridden easily.

@kalarani
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. So, now i need to explicitly specify in the configuration (i.e, useSecurityListener=true) to receive events. I would expect events to be thrown by default and switched off if needed. Shouldn't this be the default behavior?

@kalarani
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, we came across one more issue.We were unable to receive UsernameNotFoundException exception as the field hideUserNotFoundExceptions is set to true by default in AbstractUserDetailsAuthenticationProvider.It would be great if you can make it configurable in the plugin :)

@burtbeckwith
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please create an issue at http://jira.codehaus.org/browse/GRAILSPLUGINS and I'll get it into the next release. Until then you can override the bean in resources.groovy:

daoAuthenticationProvider(DaoAuthenticationProvider) {
    userDetailsService = ref('userDetailsService')
    passwordEncoder = ref('passwordEncoder')
    userCache = ref('userCache')
    saltSource = ref('saltSource')
    hideUserNotFoundExceptions = false
}

@kalarani
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup. We are currently overriding the resources.groovy. I've logged an issue as well. Thanks.

Please sign in to comment.