plugin-core/plugin/grails-app/conf/DefaultSecurityConfig.groovy (234 lines of code) (raw):

/* Copyright 2006-2016 the original author or authors. * * Licensed 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 * * https://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. */ import grails.plugin.springsecurity.BeanTypeResolver import grails.plugin.springsecurity.SecurityConfigType import grails.plugin.springsecurity.SpringSecurityUtils import grails.plugin.springsecurity.authentication.GrailsAnonymousAuthenticationToken import grails.util.Environment import org.springframework.security.authentication.RememberMeAuthenticationToken import org.springframework.security.core.context.SecurityContextHolder import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices import org.springframework.security.web.authentication.switchuser.SwitchUserFilter import org.springframework.security.web.context.HttpSessionSecurityContextRepository security { /** misc properties */ active = true beanTypeResolverClass = BeanTypeResolver printStatusMessages = true ajaxHeader = 'X-Requested-With' ajaxCheckClosure = null registerLoggerListener = false // 'strict' mode where an explicit grant is required to access any resource; // if true make sure to allow IS_AUTHENTICATED_ANONYMOUSLY or permitAll // for /, /error, /index, /index.gsp, /shutdown, /assets/**, /**/js/**, /**/css/**, /**/images/**, etc. // (and /login, /login/**, /logout, /logout/** if you're not using annotations) // Also consider using fii.rejectPublicInvocations = true rejectIfNoRule = true // hierarchical roles roleHierarchy = '' // ip restriction filter ipRestrictions = [] // voters voterNames = [] // 'authenticatedVoter', 'roleVoter', 'closureVoter' // providers providerNames = [] // 'daoAuthenticationProvider', 'anonymousAuthenticationProvider', 'rememberMeAuthenticationProvider' // AfterInvocationManager afterInvocationManagerProviderNames = [] // HttpSessionEventPublisher useHttpSessionEventPublisher = false // SecurityEventListener useSecurityEventListener = false // user caching cacheUsers = false useExternalClasses = false // user and role class properties userLookup { userDomainClassName = null // must be set if using UserDetailsService usernamePropertyName = 'username' usernameIgnoreCase = false enabledPropertyName = 'enabled' passwordPropertyName = 'password' authoritiesPropertyName = 'authorities' accountExpiredPropertyName = 'accountExpired' accountLockedPropertyName = 'accountLocked' passwordExpiredPropertyName = 'passwordExpired' authorityJoinClassName = null // must be set if using UserDetailsService } authority { className = null // must be set if using UserDetailsService nameField = 'authority' groupAuthorityNameField = null //must be set if using authority groups } useRoleGroups = false /** authenticationProcessingFilter */ apf { filterProcessesUrl = '/login/authenticate' usernameParameter = UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_USERNAME_KEY // 'username' passwordParameter = UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_PASSWORD_KEY // 'password' continueChainBeforeSuccessfulAuthentication = false allowSessionCreation = true postOnly = true storeLastUsername = false } // authenticationFailureHandler failureHandler { defaultFailureUrl = '/login/authfail?login_error=1' ajaxAuthFailUrl = '/login/authfail?ajax=true' exceptionMappings = [] useForward = false allowSessionCreation = true } // successHandler successHandler { defaultTargetUrl = '/' alwaysUseDefault = false targetUrlParameter = SpringSecurityUtils.DEFAULT_TARGET_PARAMETER // 'spring-security-redirect' ajaxSuccessUrl = '/login/ajaxSuccess' useReferer = false } // requestCache requestCache { createSession = true } // redirectStrategy redirectStrategy { contextRelative = false } // session fixation prevention useSessionFixationPrevention = true sessionFixationPrevention { migrate = true alwaysCreateSession = false } /** daoAuthenticationProvider **/ dao { reflectionSaltSourceProperty = null // if null, don't use salt source hideUserNotFoundExceptions = true } /** anonymousProcessingFilter */ anon { key = 'foo' } /** authenticationEntryPoint */ auth { loginFormUrl = '/login/auth' forceHttps = false ajaxLoginFormUrl = '/login/authAjax' useForward = false // redirect to login page } /** logoutFilter */ logout { afterLogoutUrl = '/' filterProcessesUrl = '/logoff' handlerNames = [] // 'rememberMeServices', 'securityContextLogoutHandler' clearAuthentication = true invalidateHttpSession = true targetUrlParameter = null alwaysUseDefaultTargetUrl = false redirectToReferer = false postOnly = true } /** * accessDeniedHandler * set errorPage to null to send Error 403 instead of showing error page */ adh { errorPage = '/login/denied' ajaxErrorPage = '/login/ajaxDenied' useForward = true } /** passwordEncoder */ // see https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html password { algorithm = 'bcrypt' encodeHashAsBase64 = false if (Environment.current == Environment.TEST) { bcrypt { logrounds = 4 } hash { iterations = 1 } } else { bcrypt { logrounds = 10 } hash { iterations = 10000 } } } /** rememberMeServices */ rememberMe { cookieName = 'grails_remember_me' cookieDomain = null alwaysRemember = false tokenValiditySeconds = AbstractRememberMeServices.TWO_WEEKS_S // 1209600 -> 14 days parameter = AbstractRememberMeServices.DEFAULT_PARAMETER // 'remember-me' key = 'grailsRocks' persistent = false persistentToken { domainClassName = null seriesLength = PersistentTokenBasedRememberMeServices.DEFAULT_SERIES_LENGTH // 16 tokenLength = PersistentTokenBasedRememberMeServices.DEFAULT_TOKEN_LENGTH // 16 } useSecureCookie = null createSessionOnSuccess = true } /** URL <-> Role mapping */ // default to annotation mode securityConfigType = SecurityConfigType.Annotation // use Requestmap domain class to store rules in the database // change securityConfigType to 'Requestmap' requestMap { className = null // must be set if using urlField = 'url' configAttributeField = 'configAttribute' httpMethodField = 'httpMethod' } // use annotations from Controllers to define security rules // change securityConfigType to 'Annotation' controllerAnnotations { staticRules = [] } // List of Maps where the keys are pattern (URL pattern), // access (single token or List, e.g. role name(s)), httpMethod (optional restriction to particular method) // to use, change securityConfigType to 'InterceptUrlMap' interceptUrlMap = [] /** basic auth */ useBasicAuth = false basic { realmName = 'Grails Realm' credentialsCharset = 'UTF-8' } /** digest auth */ useDigestAuth = false digest { realmName = 'Grails Realm' key = 'changeme' nonceValiditySeconds = 300 passwordAlreadyEncoded = false createAuthenticatedToken = false useCleartextPasswords = false } /** use switchUserProcessingFilter */ useSwitchUserFilter = false switchUser { switchUserUrl = '/login/impersonate' exitUserUrl = '/logout/impersonate' targetUrl = null // use the authenticationSuccessHandler switchFailureUrl = null // use the authenticationFailureHandler usernameParameter = SwitchUserFilter.SPRING_SECURITY_SWITCH_USERNAME_KEY // username } // port mappings portMapper { httpPort = 8080 httpsPort = 8443 } // secure channel filter (http/https) secureChannel { definition = [] useHeaderCheckChannelSecurity = false secureHeaderName = 'X-Forwarded-Proto' secureHeaderValue = 'http' secureConfigAttributeKeyword = 'REQUIRES_SECURE_CHANNEL' insecureHeaderName = 'X-Forwarded-Proto' insecureHeaderValue = 'https' insecureConfigAttributeKeyword = 'REQUIRES_INSECURE_CHANNEL' } // X509 useX509 = false x509 { continueFilterChainOnUnsuccessfulAuthentication = true subjectDnRegex = 'CN=(.*?)(?:,|$)' subjectDnClosure = null checkForPrincipalChanges = false invalidateSessionOnPrincipalChange = true throwExceptionWhenTokenRejected = false } // authenticationTrustResolver atr { anonymousClass = GrailsAnonymousAuthenticationToken rememberMeClass = RememberMeAuthenticationToken } // providerManager providerManager { eraseCredentialsAfterAuthentication = true } // securityContextRepository scr { allowSessionCreation = true disableUrlRewriting = true springSecurityContextKey = HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY // 'SPRING_SECURITY_CONTEXT' } // securityContextPersistenceFilter scpf { forceEagerSessionCreation = false } // filterInvocationInterceptor fii { alwaysReauthenticate = false rejectPublicInvocations = true validateConfigAttributes = true publishAuthorizationSuccess = false observeOncePerRequest = true } debug { useFilter = false } // SecurityContextHolder sch { // one of MODE_THREADLOCAL, MODE_INHERITABLETHREADLOCAL, MODE_GLOBAL, // or the name of a class implementing org.springframework.security.core.context.SecurityContextHolderStrategy strategyName = SecurityContextHolder.MODE_THREADLOCAL } gsp { layoutAuth = 'main' layoutDenied = 'main' } }