Much of the Spring Security configuration is user-configurable. The configuration has sensible default values, but each application has special needs. Default values are in the plugin's grails-app/conf/DefaultSecurityConfig.groovy file and application-specific values are in grails-app/conf/SecurityConfig.groovy.
Only one property must be specified in SecurityConfig.groovy - 'active' defaults to false, so you have to change it to true to enable the plugin.
Other properties that are most likely to be overridden are the User, Role, and Requestmap class and field names:
| Property | Default Value | Meaning |
|---|
| loginUserDomainClass | 'Person' | User class name |
| userName | 'username' | User class username field |
| password | 'passwd' | User class password field |
| enabled | 'enabled' | User class enabled field |
| relationalAuthorities | 'authorities' | User class role collection field |
| authorityDomainClass | 'Authority' | Role class name |
| authorityField | 'authority' | Role class role name field |
| requestMapClass | 'Requestmap' | request map class name |
| requestMapPathField | 'url' | request map class url pattern field |
| requestMapConfigAttributeField | 'configAttribute' | request map class role name list field (comma-delimited) |
| useRequestMapDomainClass | true | if true, searches the database, otherwise uses static configuration |
If you want to send emails to newly-registered users, configure these properties:
| Property | Default Value | Meaning |
|---|
| useMail | false | if true, enables user registration emails |
| mailHost | 'localhost' | mail server url |
| mailUsername | 'user@localhost' | mail server username (set to null if auth isn't required) |
| mailPassword | 'sungod' | mail server password (set to null if auth isn't required) |
| mailProtocol | 'smtp' | JavaMail protocol name |
| mailFrom | 'user@localhost' | email 'from' address |
| mailPort | 25 | mail server port |
| javaMailProperties | null | optional map of custom JavaMail properties |
URL attributes:
| Property | Default Value | Meaning |
|---|
| authenticationFailureUrl | '/login/authfail?login_error=1' | redirect url for failed logins |
| ajaxAuthenticationFailureUrl | /login/authfail?ajax=true' | url for failed Ajax logins |
| defaultTargetUrl | '/' | |
| alwaysUseDefaultTargetUrl | false | if true, will always redirect to the value of defaultTargetUrl after successful authentication, otherwise redirects to originally-requested page |
| filterProcessesUrl | '/j_spring_security_check' | Login form post url, intercepted by Spring Security filter |
| loginFormUrl | '/login/auth' | url of login page |
| ajaxLoginFormUrl | '/login/authAjax' | url of Ajax login page |
| forceHttps | 'false' | if true, Spring Security will redirect login page requests to https |
| afterLogoutUrl | '/' | redirect url after logout |
| errorPage | '/login/denied' | location of the 403 error page |
| ajaxErrorPage | '/login/deniedAjax' | location of the 403 error page for Ajax requests |
| ajaxHeader | 'X-Requested-With' | header name sent by Ajax library, used to detect Ajax |
Attributes for rememberMeServices bean (cookie management):
| Property | Default Value | Meaning |
|---|
| cookieName | 'grails_remember_me' | remember-me cookie name |
| alwaysRemember | false | |
| tokenValiditySeconds | 1209600 (14 days) | max age of the cookie in seconds |
| parameter | '_spring_security_remember_me' | Login form remember-me checkbox name |
| rememberMeKey | 'grailsRocks' | a value used to encode cookies - should be unique per application |
To use LDAP, configure these properties:
| Property | Default Value | Meaning |
|---|
| useLdap | false | if true, enables LDAP authentication |
| ldapServer | 'ldap://localhost:389' | server url |
| ldapManagerDn | 'cn=admin,dc=example,dc=com' | manager DN |
| ldapManagerPassword | 'secret' | manager password |
| ldapSearchBase | 'dc=example,dc=com' | user search name base |
| ldapPasswordAttributeName | 'userPassword' | where to look for the user's password in the entry |
| ldapSearchFilter | '(uid={0})' | user search pattern |
| ldapSearchSubtree | true | |
| ldapGroupRoleAttribute | 'cn' | |
| ldapGroupSearchBase | 'ou=groups,dc=example,dc=com' | group search string |
| ldapGroupSearchFilter | 'uniquemember={0}' | search pattern to determine user groups (converted to Roles) |
| ldapRetrieveGroupRoles | true | whether or not to convert LDAP group membership to Roles |
| ldapRetrieveDatabaseRoles | false | whether or not to look for assigned roles in the database |
| ldapUsePassword | true | if true, extracts password from LDAP, otherwise uses a dummy password |
To use OpenID, configure these properties:
| Property | Default Value | Meaning |
|---|
| useOpenId | false | if true, enables OpenID authentication |
| openIdNonceMaxSeconds | 300 | max time between auth start and end in seconds |
To use Kerberos, configure these properties:
| Property | Default Value | Meaning |
|---|
| useKerberos | false | if true, enables Kerberos authentication |
| kerberosLoginConfigFile | 'WEB-INF/jaas.conf' | config location |
| kerberosRealm | 'KERBEROS.REALM' | realm name |
| kerberosKdc | 'krbserver.domain.lan' | Key Distribution Center url |
| kerberosRetrieveDatabaseRoles | true | if true, look for roles in database |
To use CAS, configure these properties:
| Property | Default Value | Meaning |
|---|
| useCAS | false | if true, enables CAS authentication |
| cas.casServer | 'localhost' | server name of CAS server |
| cas.casServerPort | 443 | CAS server port |
| cas.casServerSecure | true | whether the CAS server uses HTTPS |
| cas.localhostSecure | true | whether the application server uses HTTPS |
| cas.failureURL | '/denied.jsp' | url to use when authentication fails |
| cas.defaultTargetURL | '/' | |
| cas.fullLoginURL | 'https://localhost:443/cas/login' | the CAS server login URL |
| cas.fullServiceURL | 'https://localhost:443/cas' | the Service URL of the CAS server |
| cas.authenticationProviderKey | 'cas_key_changeme' | unique key for the CAS authentication provider |
| cas.userDetailsService | 'userDetailsService' | Spring bean name for user lookup service (in case you wish to use a second service for CAS) |
| cas.sendRenew | false | |
| cas.proxyReceptorUrl | '/secure/receptor' | |
| cas.filterProcessesUrl | '/j_spring_cas_security_check' | |
To use NTLM, configure these properties:
| Property | Default Value | Meaning |
|---|
| useNtlm | false | if true, enables NTLM authentication |
| ntlm.stripDomain | true | |
| ntlm.retryOnAuthFailure | true | |
| ntlm.forceIdentification | false | |
| ntlm.defaultDomain | null - must be specified in SecurityConfig.groovy | |
| ntlm.netbiosWINS | null - must be specified in SecurityConfig.groovy | |
To use Facebook Connect, configure these properties:
| Property | Default Value | Meaning |
|---|
| useFacebook | false | if true, enables Facebook Connect authentication |
| facebook.filterProcessesUrl | '/j_spring_facebook_security_check' | the facebookAuth.gsp form POST url that's intercepted by the Facebook filter |
| facebook.authenticationUrlRoot | 'http://www.facebook.com/login.php?v=1.0&api_key=' | the root of the Facebook login server url (minus your API key) |
| facebook.apiKey | none - must be specified in SecurityConfig.groovy | your Facebook Connect API key |
| facebook.secretKey | none - must be specified in SecurityConfig.groovy | your Facebook Connect secret key |
To use Channel security (declaring which URLs must use HTTPS or HTTP), configure these properties:
| Property | Default Value | Meaning |
|---|
| httpPort | 8080 | the HTTP port your app uses |
| httpsPort | 8443 | the HTTPS port your app uses |
| secureChannelDefinitionSource | none | the full channel filter configuration string, if not defined using the channelConfig map |
| channelConfig | none | secure (HTTPS) URLs and insecure (HTTP) URLs, if not defined using the secureChannelDefinitionSource string |
There are two ways to configure channel security, either using 'channelConfig' or 'secureChannelDefinitionSource'. If your configuration is simply a list of URL patterns that require HTTPS and a list that require HTTP (either can be omitted), e.g.
channelConfig = [secure: ['/admin/**', '/admin2/**'],
insecure: ['/foo/**']]then specifying channelConfig is the better option. If you need full control over the configuration string then you can specify the entire thing as secureChannelDefinitionSource, e.g.
secureChannelDefinitionSource = '''
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/admin/**=REQUIRES_SECURE_CHANNEL
/admin2/**=REQUIRES_SECURE_CHANNEL
/foo/**=REQUIRES_INSECURE_CHANNEL
'''
then specifying the full secureChannelDefinitionSource is the better option.
To use IP address restrictions, configure these properties:
| Property | Default Value | Meaning |
|---|
| ipRestrictions | none | a Map of URL patterns to IP address patterns |
For example, given this configuration:
ipRestrictions = ['/pattern1/**': '127.0.0.1',
'/pattern2/**': '10.**',
'/pattern3/**': '10.10.200.63']then 'pattern1' URLs can only be access from localhost, 'pattern2' URLs can only be accessed from an intranet address, and 'pattern3' URLs can only be accessed from the one specified address. All other URL patterns are accessible from any IP address.
You can use either Ant-style patterns (e.g. 10.**) or masked patterns (e.g. 192.168.1.0/24 or 202.24.0.0/14), and can specify either IPV4 or IPV6 patterns.
Note that all addresses can always be accessed from localhost regardless of IP pattern.
Password encryption attributes:
| Name | Default | Description |
|---|
| algorithm | 'SHA' | passwordEncoder Message Digest algorithm |
| encodeHashAsBase64 | false | if true, Base64-encode the hashed password |
Logout Handlers:
Spring Security allows you to register a list of logout handlers (implementing the org.springframework.security.ui.logout.LogoutHandler interface) that will be called when a user explicitly logs out.
By default, a 'securityContextLogoutHandler' is registered to clear the SecurityContextHolder. Also, if you're not using Facebook or OpenID, 'rememberMeServices' is registered to reset your cookie (Facebook and OpenID authenticate externally so we don't have access to the password to create a remember-me cookie). If you're using Facebook, a 'facebookLogoutHandler' is registered to reset its session cookies.
To customize this list, you define a 'logoutHandlerNames' attribute with a list of bean names. The beans must be declared either by the plugin or by you in resources.groovy or resources.xml. So if you have a custom MyLogoutHandler in resources.groovy, e.g.
beans = { myLogoutHandler(com.foo.MyLogoutHandler) {
// attributes
}
}then you'd register it in SecurityConfig.groovy as:
security {
... logoutHandlerNames = ['securityContextLogoutHandler',
'rememberMeServices',
'myLogoutHandler']
}Voters:
Spring Security allows you to register a list of voters (implementing the org.springframework.security.vote.AccessDecisionVoter interface) that check that a successful authentication is applicable for the current request. By default a 'roleVoter' is registered to ensure users have the required roles for the request, and an 'authenticatedVoter' is registered to support IS_AUTHENTICATED_FULLY, IS_AUTHENTICATED_REMEMBERED, and IS_AUTHENTICATED_ANONYMOUSLY.
To customize this list, you define a 'decisionVoterNames' attribute with a list of bean names. The beans must be declared either by the plugin, or yourself in resources.groovy or resources.xml. So if you have a custom MyAccessDecisionVoter in resources.groovy, e.g.
beans = { myAccessDecisionVoter(com.foo.MyAccessDecisionVoter) {
// attributes
}
}then you'd register it in SecurityConfig.groovy as:
security {
... decisionVoterNames = ['authenticatedVoter',
'roleVoter',
'myAccessDecisionVoter']
}Authentication managers:
The plugin registers autentication managers (implementing the org.springframework.security.providers.AuthenticationProvider interface) that perform authentication. By default, three are registered: 'daoAuthenticationProvider' to authenticate using the User and Role database tables, 'rememberMeAuthenticationProvider' to login with a remember-me cookie, and 'anonymousAuthenticationProvider' to create an 'anonymous' authentication if no other provider authenticates.
Also, if configured, one of 'kerberosAuthProvider', 'casAuthenticationProvider', 'ldapAuthProvider', 'facebookAuthProvider', or 'openIDAuthProvider' are registered.
To customize this list, you define a 'providerNames' attribute with a list of bean names. The beans must be declared either by the plugin, or yourself in resources.groovy or resources.xml. So if you have a custom MyAuthenticationProvider in resources.groovy, e.g.
beans = { myAuthenticationProvider(com.foo.MyAuthenticationProvider) {
// attributes
}
}then you'd register it in SecurityConfig.groovy as:
security {
... providerNames = ['myAuthenticationProvider',
'anonymousAuthenticationProvider',
'rememberMeAuthenticationProvider']
}Filters
There are four ways to configure filter chain(s). The default way is to use configuration attributes to determine which extra filters to use (e.g. Basic Auth, OpenID, etc.) and add these to the 'core' filters. For example, setting "useOpenId=true" adds an 'openIDAuthenticationProcessingFilter' filter to the filter chain (and in the correct order). The filter chain built here is applied to all URLs, so if you need more flexibility then you can use one of the other approaches.
If you'd like to define custom filters, remove a core filter from the chain (not recommended), or otherwise have control over the filter chain, then you can specify the 'filterNames' property to a list of strings, e.g.
security {
... filterNames = ['httpSessionContextIntegrationFilter',
'logoutFilter',
'authenticationProcessingFilter',
'myCustomProcessingFilter',
'rememberMeProcessingFilter',
'anonymousProcessingFilter',
'exceptionTranslationFilter',
'filterInvocationInterceptor']
}As with the default approach, the filter chain built here is applied to all URLs, so if you need more flexibility then you can use one of the other approaches.
The most flexible approach uses the 'filterInvocationDefinitionSource' config attribute. This allows you to define the entire mapping of URL pattern(s) to filter chain(s). This is a string in the format that you'd use in a traditional Spring application, e.g.
filterInvocationDefinitionSource = '''
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,…
'''
</value>
The fourth approach specifies one or more lists of filter bean names, each with a corresponding URL pattern, in a SecurityConfig map using the 'filterInvocationDefinitionSourceMap' property, e.g.:
filterInvocationDefinitionSourceMap = [
'/urlpattern1/**': 'httpSessionContextIntegrationFilter,authenticationProcessingFilter,..',
'/urlpattern2/**': 'httpSessionContextIntegrationFilter,authenticationProcessingFilter,..',
'/**': 'httpSessionContextIntegrationFilter,authenticationProcessingFilter,..',
]
Additionally, you can specify 'JOINED_FILTERS' as the filter list for a pattern, and it will use the standard filter list that's configured in the default approach above.
Other miscellaneous attributes:
| Property | Default Value | Meaning |
|---|
| key | 'foo' | anonymousProcessingFilter key |
| userAttribute | 'anonymousUser,ROLE_ANONYMOUS' | anonymousProcessingFilter |
| useLogger | false | enables logging, also need to add 'org.springframework.security' to Config.groovy log4j |
| basicProcessingFilter | false | if true, enable the Basic Auth processing filter |
| realmName | 'Grails Realm' | Basic Auth realm name |
| switchUserProcessingFilter | false | if true, enable the switchUserProcessingFilter bean |
| swswitchUserUrl | '/j_spring_security_switch_user' | switch user filter url |
| swexitUserUrl | '/j_spring_security_exit_user' | |
| swtargetUrl | '/' | |
| defaultRole | 'ROLE_USER' | default user's role for user registration |
| useHttpSessionEventPublisher | false | if true, a HttpSessionEventPublisher will be configured |
| cacheUsers | true | if true, logins are cached using an EhCache |
URL <-> Role configuration
The configuration options for configuring URL <-> role mappings are described
here