Closure doWithSpring()

in plugin-rest/spring-security-rest/src/main/groovy/grails/plugin/springsecurity/rest/SpringSecurityRestGrailsPlugin.groovy [92:302]


    Closure doWithSpring() { {->
        if (!springSecurityPluginsAreActive()){
            return
        }

        def conf = SpringSecurityUtils.securityConfig
        SpringSecurityUtils.loadSecondaryConfig 'DefaultRestSecurityConfig'
        conf = SpringSecurityUtils.securityConfig

        boolean printStatusMessages = (conf.printStatusMessages instanceof Boolean) ? conf.printStatusMessages : true

        if (printStatusMessages) {
            println "\nConfiguring Spring Security REST ${plugin.version}..."
        }

        ///*
        SpringSecurityUtils.registerProvider 'restAuthenticationProvider'

        /* restAuthenticationFilter */
        if(conf.rest.login.active) {
            SpringSecurityUtils.registerFilter 'restAuthenticationFilter', SecurityFilterPosition.FORM_LOGIN_FILTER.order + 1

            restAuthenticationFilterRequestMatcher(SpringSecurityRestFilterRequestMatcher, conf.rest.login.endpointUrl)

            restAuthenticationFilter(RestAuthenticationFilter) {
                authenticationManager = ref('authenticationManager')
                authenticationSuccessHandler = ref('restAuthenticationSuccessHandler')
                authenticationFailureHandler = ref('restAuthenticationFailureHandler')
                authenticationDetailsSource = ref('authenticationDetailsSource')
                credentialsExtractor = ref('credentialsExtractor')
                endpointUrl = conf.rest.login.endpointUrl
                tokenGenerator = ref('tokenGenerator')
                tokenStorageService = ref('tokenStorageService')
                authenticationEventPublisher = ref('authenticationEventPublisher')
                requestMatcher = ref('restAuthenticationFilterRequestMatcher')
            }

            def paramsClosure = {
                usernamePropertyName = conf.rest.login.usernamePropertyName // username
                passwordPropertyName = conf.rest.login.passwordPropertyName // password
            }

            if (conf.rest.login.useRequestParamsCredentials) {
                credentialsExtractor(RequestParamsCredentialsExtractor, paramsClosure)
            } else if (conf.rest.login.useJsonCredentials) {
                credentialsExtractor(DefaultJsonPayloadCredentialsExtractor, paramsClosure)
            }

            /* restLogoutFilter */
            restLogoutFilterRequestMatcher(SpringSecurityRestFilterRequestMatcher, conf.rest.logout.endpointUrl)

            restLogoutFilter(RestLogoutFilter) {
                endpointUrl = conf.rest.logout.endpointUrl
                headerName = conf.rest.token.validation.headerName
                tokenStorageService = ref('tokenStorageService')
                tokenReader = ref('tokenReader')
                requestMatcher = ref('restLogoutFilterRequestMatcher')
            }
        }

        restAuthenticationSuccessHandler(RestAuthenticationSuccessHandler) {
            renderer = ref('accessTokenJsonRenderer')
        }

        accessTokenJsonRenderer(DefaultAccessTokenJsonRenderer) {
            usernamePropertyName = conf.rest.token.rendering.usernamePropertyName
            tokenPropertyName = conf.rest.token.rendering.tokenPropertyName
            authoritiesPropertyName = conf.rest.token.rendering.authoritiesPropertyName
            useBearerToken = conf.rest.token.validation.useBearerToken
        }

        if(conf.rest.token.validation.useBearerToken ) {
            tokenReader(BearerTokenReader)
            restAuthenticationFailureHandler(BearerTokenAuthenticationFailureHandler){
                tokenReader = ref('tokenReader')
            }
            restAuthenticationEntryPoint(BearerTokenAuthenticationEntryPoint) {
                tokenReader = ref('tokenReader')
            }
            restAccessDeniedHandler(BearerTokenAccessDeniedHandler) {
                errorPage = null //403
            }

        } else {
            restAuthenticationEntryPoint(Http403ForbiddenEntryPoint)
            tokenReader(HttpHeaderTokenReader) {
                headerName = conf.rest.token.validation.headerName
            }
            restAuthenticationFailureHandler(RestAuthenticationFailureHandler) {
                statusCode = conf.rest.login.failureStatusCode?:HttpServletResponse.SC_UNAUTHORIZED
            }
            restAccessDeniedHandler(AccessDeniedHandlerImpl) {
                errorPage = null //403
            }
        }

        /* restTokenValidationFilter */
        SpringSecurityUtils.registerFilter 'restTokenValidationFilter', SecurityFilterPosition.ANONYMOUS_FILTER.order + 1
        SpringSecurityUtils.registerFilter 'restExceptionTranslationFilter', SecurityFilterPosition.EXCEPTION_TRANSLATION_FILTER.order - 5

        restTokenValidationFilterRequestMatcher(SpringSecurityRestFilterRequestMatcher, conf.rest.token.validation.endpointUrl)

        restTokenValidationFilter(RestTokenValidationFilter) {
            headerName = conf.rest.token.validation.headerName
            validationEndpointUrl = conf.rest.token.validation.endpointUrl
            active = conf.rest.token.validation.active
            tokenReader = ref('tokenReader')
            enableAnonymousAccess = conf.rest.token.validation.enableAnonymousAccess
            authenticationSuccessHandler = ref('restAuthenticationSuccessHandler')
            authenticationFailureHandler = ref('restAuthenticationFailureHandler')
            restAuthenticationProvider = ref('restAuthenticationProvider')
            authenticationEventPublisher = ref('authenticationEventPublisher')
            requestMatcher = ref('restTokenValidationFilterRequestMatcher')
        }

        restExceptionTranslationFilter(ExceptionTranslationFilter, ref('restAuthenticationEntryPoint'), ref('restRequestCache')) {
            accessDeniedHandler = ref('restAccessDeniedHandler')
            authenticationTrustResolver = ref('authenticationTrustResolver')
            throwableAnalyzer = ref('throwableAnalyzer')
        }

        restRequestCache(NullRequestCache)

        /* tokenGenerator */
        tokenGenerator(SecureRandomTokenGenerator)

        callbackErrorHandler(DefaultCallbackErrorHandler)
        
        String jwtSecretValue = conf.rest.token.storage.jwt.secret

        /* tokenStorageService - defaults to JWT */
        jwtService(JwtService) {
            jwtSecret = jwtSecretValue
        }
        tokenStorageService(JwtTokenStorageService) {
            jwtService = ref('jwtService')
            userDetailsService = ref('userDetailsService')
        }

        issuerClaimProvider(IssuerClaimProvider) {
            issuerName = conf.rest.token.generation.jwt.issuer
        }

        if (conf.rest.token.storage.jwt.useEncryptedJwt) {
            jwtService(JwtService) {
                keyProvider = ref('keyProvider')
            }
            tokenGenerator(EncryptedJwtTokenGenerator) {
                jwtTokenStorageService = ref('tokenStorageService')
                keyProvider = ref('keyProvider')
                defaultExpiration = conf.rest.token.storage.jwt.expiration
                defaultRefreshExpiration = conf.rest.token.storage.jwt.refreshExpiration
                jweAlgorithm = JWEAlgorithm.parse(conf.rest.token.generation.jwt.jweAlgorithm)
                encryptionMethod = EncryptionMethod.parse(conf.rest.token.generation.jwt.encryptionMethod)
            }

            if (conf.rest.token.storage.jwt.privateKeyPath instanceof CharSequence &&
                    conf.rest.token.storage.jwt.publicKeyPath instanceof CharSequence) {
                keyProvider(FileRSAKeyProvider) {
                    privateKeyPath = conf.rest.token.storage.jwt.privateKeyPath
                    publicKeyPath = conf.rest.token.storage.jwt.publicKeyPath
                }
            } else {
                keyProvider(DefaultRSAKeyProvider)
            }

        } else if (conf.rest.token.storage.jwt.useSignedJwt) {
            checkJwtSecret(jwtSecretValue)

            tokenGenerator(SignedJwtTokenGenerator) {
                jwtTokenStorageService = ref('tokenStorageService')
                jwtSecret = jwtSecretValue
                defaultExpiration = conf.rest.token.storage.jwt.expiration
                defaultRefreshExpiration = conf.rest.token.storage.jwt.refreshExpiration
                jwsAlgorithm = JWSAlgorithm.parse(conf.rest.token.generation.jwt.algorithm)
            }
        }

        /* restAuthenticationProvider */
        restAuthenticationProvider(RestAuthenticationProvider) {
            tokenStorageService = ref('tokenStorageService')
            useJwt = true
            jwtService = ref('jwtService')
        }

        /* oauthUserDetailsService */
        oauthUserDetailsService(DefaultOauthUserDetailsService) {
            userDetailsService = ref('userDetailsService')
            preAuthenticationChecks = ref('preAuthenticationChecks')
        }

        // SecurityEventListener
        if (conf.useSecurityEventListener) {
            restSecurityEventListener(RestSecurityEventListener)

            authenticationEventPublisher(DefaultRestAuthenticationEventPublisher)
        } else {
            authenticationEventPublisher(NullRestAuthenticationEventPublisher)
        }

        String algorithm = conf.password.algorithm
        Class beanTypeResolverClass = conf.beanTypeResolverClass ?: BeanTypeResolver
        def beanTypeResolver = beanTypeResolverClass.newInstance(conf, grailsApplication)

        passwordEncoder(beanTypeResolver.resolveType('passwordEncoder', DelegatingPasswordEncoder), algorithm, idToPasswordEncoder(conf))

        if (printStatusMessages) {
            println '... finished configuring Spring Security REST\n'
        }

    }}