### Application Configuration Example Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-ui/docs/src/docs/scripts/s2ui-create-challenge-questions.adoc This line is added to application.groovy to ensure proper configuration of challenge questions and answers. ```groovy spring.security.ui.menu..= Questions ``` -------------------------------- ### Example application.yml Configuration Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-oauth2/docs/src/docs/configuration.adoc Configure the OAuth2 plugin by setting parameters in your application.yml file. This example shows how to activate the plugin and configure user registration options. ```yaml grails: plugin: springsecurity: oauth2: active: true registration: askToLinkOrCreateAccountUri: /oauth2/ask roleNames: ['ROLE_USER'] ``` -------------------------------- ### Run-As Authentication Replacement Example Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-acl/docs/src/docs/usage/runAs.adoc This example demonstrates how to use the @Secured annotation with 'RUN_AS_SUPERUSER' to grant temporary roles for a single method invocation. The user must also possess 'ROLE_ADMIN' to access the method. ```groovy class SecureService { @Secured(['ROLE_ADMIN', 'RUN_AS_SUPERUSER']) def someMethod() { ... } } ``` -------------------------------- ### Sample Active Directory Configuration Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-ldap/docs/src/docs/usage.adoc Example configuration settings for connecting to an Active Directory server. Remember to replace placeholder values with your specific AD details. ```yaml grails: plugin: springsecurity: # LDAP config providerNames: ['ldapAuthProvider', 'anonymousAuthenticationProvider'] # specify this when you want to skip attempting to load from db and only use LDAP ldap: context: managerDn: '[distinguishedName]' managerPassword: '[password]' server: 'ldap://[ip]:[port]/' search: base: '[the base directory to start the search. usually something like dc=mycompany,dc=com]' filter: 'sAMAccountName={0}' # for Active Directory you need this searchSubtree: true attributesToReturn: ['mail', 'displayName'] # extra attributes you want returned; see below for custom classes that access this data auth: hideUserNotFoundExceptions: false # role-specific LDAP config useRememberMe: false authorities: ignorePartialResultException: true # typically needed for Active Directory retrieveGroupRoles: true groupSearchBase: '[the base directory to start the search. usually something like dc=mycompany,dc=com]' # If you don't want to support group membership recursion (groups in groups), # then use the following setting # grails.plugin.springsecurity.ldap.authorities.groupSearchFilter = 'member={0}' # If you wish to support groups with group as members (recursive groups), use # the following: ``` -------------------------------- ### CAS Plugin Configuration Example Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-cas/docs/src/docs/configuration.adoc Example of how to configure CAS plugin properties in `application.yml`. All overrides must be specified using the `grails.plugin.springsecurity.cas` suffix. ```yaml grails: plugin: springsecurity: cas: serverUrlPrefix: https://cas-server/cas ``` -------------------------------- ### Create a Security Event Listener Class Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/events/registeringEventListener.adoc Implement the `ApplicationListener` interface to handle specific security events. This example handles `AuthenticationSuccessEvent`. ```groovy package com.foo.bar import org.springframework.context.ApplicationListener import org.springframework.security.authentication.event.AuthenticationSuccessEvent class MySecurityEventListener implements ApplicationListener { void onApplicationEvent(AuthenticationSuccessEvent event) { // handle the event } } ``` -------------------------------- ### Example JSON Authentication Request Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-rest/docs/src/docs/authentication.adoc This is an example of a JSON request payload for authentication using default username and password properties. ```javascript { "username": "john.doe", "password": "dontTellAnybody" } ``` -------------------------------- ### Add Test User in BootStrap.groovy Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/tutorials/usingControllerAnnotations.adoc Initialize the application by adding a test user and an admin role. This setup is crucial for testing secured endpoints. ```groovy package com.mycompany.myapp import grails.gorm.transactions.Transactional class BootStrap { def init = { addTestUser() } @Transactional void addTestUser() { def adminRole = new Role(authority: 'ROLE_ADMIN').save() def testUser = new User(username: 'me', password: 'password').save() UserRole.create testUser, adminRole UserRole.withSession { it.flush() it.clear() } assert User.count() == 1 assert Role.count() == 1 assert UserRole.count() == 1 } } ``` -------------------------------- ### Install Spring Security Plugin Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/tutorials/usingControllerAnnotations.adoc Add the Spring Security plugin dependency to your `build.gradle` file and run the compile command to resolve dependencies. ```groovy dependencies { ... implementation 'org.apache.grails:grails-spring-security:{project-version}' ... } ``` -------------------------------- ### Configure Challenge Questions (YAML) Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-ui/docs/src/docs/forgotPassword.adoc Example of configuring challenge questions using `labelDomain` in `application.yml`. This property is used to ask the question from the domain object. ```yaml grails: plugin: springsecurity: ui: forgotPassword: forgotPasswordExtraValidation: - labelDomain: myQuestion ``` -------------------------------- ### Customized Access Token Response (JSON) Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-rest/docs/src/docs/tokenRendering.adoc Example of a JSON response after customizing the username and roles property names in the configuration. ```javascript { "access_token":"eyJhbGciOiJIUzI1NiJ9...", "token_type":"Bearer", "login": "john.doe", "permissions": [ "ROLE_ADMIN", "ROLE_USER" ] } ``` -------------------------------- ### Custom JSON Authentication Request Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-rest/docs/src/docs/authentication.adoc This example shows a JSON authentication request using custom property names for username and password. ```javascript { "login": "john.doe", "pwd": "dontTellAnybody" } ``` -------------------------------- ### Configure staticRules for rejectIfNoRule or fii.rejectPublicInvocations Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/requestMappings.adoc When using `rejectIfNoRule` or `fii.rejectPublicInvocations`, you must configure `staticRules` to include URLs that cannot be guarded by other means. This example permits access to root, error pages, and static assets. ```groovy grails.plugin.springsecurity.controllerAnnotations.staticRules = [ [pattern: '/', access: ['permitAll']], [pattern: '/error', access: ['permitAll']], [pattern: '/index', access: ['permitAll']], [pattern: '/index.gsp', access: ['permitAll']], [pattern: '/shutdown', access: ['permitAll']], [pattern: '/assets/**', access: ['permitAll']], [pattern: '/**/js/**', access: ['permitAll']], [pattern: '/**/css/**', access: ['permitAll']], [pattern: '/**/images/**', access: ['permitAll']], [pattern: '/**/favicon.ico', access: ['permitAll']] ] ``` -------------------------------- ### Create Request Map Entries in the Database Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/requestMappings/requestmapInstances.adoc Populate the SecurityMapping domain class with URL patterns and their corresponding configuration attributes. This example sets public access for common static assets and login/logout paths, and specific roles for other paths. ```groovy for (String url in [ '/', '/error', '/index', '/index.gsp', '/**/favicon.ico', '/shutdown', '/assets/**', '/**/js/**', '/**/css/**', '/**/images/**', '/login', '/login.*', '/login/*', '/logout', '/logout.*', '/logout/*']) { new SecurityMapping(url: url, configAttribute: 'permitAll').save() } new SecurityMapping(url: '/profile **', configAttribute: 'ROLE_USER').save() new SecurityMapping(url: '/admin **', configAttribute: 'ROLE_ADMIN').save() new SecurityMapping(url: '/admin/role **', configAttribute: 'ROLE_SUPERVISOR').save() new SecurityMapping(url: '/admin/user **', configAttribute: 'ROLE_ADMIN,ROLE_SUPERVISOR').save() new SecurityMapping(url: '/login/impersonate', configAttribute: 'ROLE_SWITCH_USER,IS_AUTHENTICATED_FULLY').save() springSecurityService.clearCachedRequestmaps() ``` -------------------------------- ### Custom UserDetailsService Implementation Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/userDetailsService.adoc Implement GrailsUserDetailsService to provide custom user loading logic. This example demonstrates how to load user details and authorities, including handling potential exceptions. ```groovy package com.mycompany.myapp import grails.plugin.springsecurity.SpringSecurityUtils import grails.plugin.springsecurity.userdetails.GrailsUserDetailsService import grails.plugin.springsecurity.userdetails.NoStackUsernameNotFoundException import grails.gorm.transactions.Transactional import org.springframework.security.core.authority.SimpleGrantedAuthority import org.springframework.security.core.userdetails.UserDetails import org.springframework.security.core.userdetails.UsernameNotFoundException class MyUserDetailsService implements GrailsUserDetailsService { /** ``` -------------------------------- ### Initialize OAuth2 Plugin with Init Script Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-oauth2/README.md Run this command in your Grails application to initialize the OAuth2 plugin, specifying your User domain class package, user class name, and OAuthID class name. For example: `grails init-oauth2 com.yourapp User OAuthID`. ```bash grails init-oauth2 com.yourapp User OAuthID ``` -------------------------------- ### Load Current User (Proxy) - SpringSecurityService Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/helperClasses/springSecurityService.adoc Creates a proxy instance for the current user using GORM's `load` method. This is efficient when only the user's ID is required, for example, in queries. It will not be null but might be an invalid proxy if the ID is not found. ```groovy class SomeController { def springSecurityService def someAction(Long id) { def user = springSecurityService.isLoggedIn() ? springSecurityService.loadCurrentUser() : null if (user) { CreditCard card = CreditCard.findByIdAndUser(id, user) ... } ... } } ``` -------------------------------- ### Run Spring Security Initialization Script Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/introduction/gettingStarted.adoc Execute this command in your terminal to run the `s2-quickstart` script, which sets up essential classes and configurations for the plugin. Replace `com.yourapp` with your application's package and `User` and `Role` with your desired domain class names. ```bash ./gradlew runCommand -Pargs="s2-quickstart com.yourapp User Role" ``` -------------------------------- ### Configure BootStrap.groovy Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-acl/docs/src/docs/tutorial.adoc Configures the application's Bootstrap.groovy file to call the sample data service at startup, ensuring users and permissions are set up. ```groovy class BootStrap { def sampleDataService def init = { sampleDataService.createSampleData() } } ``` -------------------------------- ### Initialize UI Settings Only Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/scripts/s2-quickstart.adoc Use the --uiOnly flag to initialize plugin settings without creating any domain classes. This is useful when integrating with external authentication providers like LDAP, Mock, or Shibboleth. ```bash ./grailsw s2-quickstart --uiOnly ``` -------------------------------- ### Generate User and Role Domain Classes Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/tutorials/usingControllerAnnotations.adoc Use the `s2-quickstart` script to generate the User and Role domain classes for your application. ```bash ./grailsw s2-quickstart com.mycompany.myapp User Role ``` -------------------------------- ### Build Grails Spring Security Project Source: https://github.com/apache/grails-spring-security/blob/7.0.x/README.md Bootstrap the Gradle wrapper and then build the project. Use the -PskipTests flag to skip tests during the build. ```bash cd gradle-bootstrap gradle cd - ./gradlew build ``` ```bash ./gradlew build -PskipTests ``` -------------------------------- ### Define InterceptUrlMap in application.yml Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/requestMappings/configGroovyMap.adoc Example of defining URL mappings using `interceptUrlMap` in `application.yml` to control access to different URL patterns. ```yaml grails: plugin: springsecurity: interceptUrlMap: - { pattern: '/', access: ['permitAll'] } - { pattern: '/error', access: ['permitAll'] } - { pattern: '/index', access: ['permitAll'] } - { pattern: '/index.gsp', access: ['permitAll'] } - { pattern: '/shutdown', access: ['permitAll'] } - { pattern: '/assets/**', access: ['permitAll'] } - { pattern: '/**/js/**', access: ['permitAll'] } - { pattern: '/**/css/**', access: ['permitAll'] } - { pattern: '/**/images/**', access: ['permitAll'] } - { pattern: '/**/favicon.ico', access: ['permitAll'] } - { pattern: '/login', access: ['permitAll'] } - { pattern: '/login/**', access: ['permitAll'] } - { pattern: '/logout', access: ['permitAll'] } - { pattern: '/logout/**', access: ['permitAll'] } ``` -------------------------------- ### Define InterceptUrlMap in application.groovy Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/requestMappings/configGroovyMap.adoc Example of defining URL mappings using `interceptUrlMap` in `application.groovy` to control access to different URL patterns. ```groovy grails.plugin.springsecurity.interceptUrlMap = [ [pattern: '/', access: ['permitAll']], [pattern: '/error', access: ['permitAll']], [pattern: '/index', access: ['permitAll']], [pattern: '/index.gsp', access: ['permitAll']], [pattern: '/shutdown', access: ['permitAll']], [pattern: '/assets/**', access: ['permitAll']], [pattern: '/**/js/**', access: ['permitAll']], [pattern: '/**/css/**', access: ['permitAll']], [pattern: '/**/images/**', access: ['permitAll']], [pattern: '/**/favicon.ico', access: ['permitAll']], [pattern: '/login', access: ['permitAll']], [pattern: '/login/**', access: ['permitAll']], [pattern: '/logout', access: ['permitAll']], [pattern: '/logout/**', access: ['permitAll']] ] ``` -------------------------------- ### Initialize OAuth2 Plugin with Gradle Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-oauth2/docs/src/docs/configuration.adoc Use the Gradle runCommand to initialize the OAuth2 plugin. Provide the domain class package, user class name, and OAuth ID class name as arguments. ```bash ./gradlew runCommand "-Pargs=init-oauth2 [DOMAIN-CLASS-PACKAGE] [USER-CLASS-NAME] [OAUTH-ID-CLASS-NAME]" ``` -------------------------------- ### Create User and Role Domain Classes Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-acl/docs/src/docs/tutorial.adoc Run the s2-quickstart script to generate User and Role domain classes. This is a prerequisite for Spring Security Core plugin functionality. ```bash $ grails s2-quickstart com.testacl User Role ``` -------------------------------- ### JWT Header Example Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-rest/docs/src/docs/tokenStorage.adoc A base64-encoded JSON object representing the header of a JSON Web Token (JWT). It specifies the algorithm and token type. ```javascript { "alg": "HS256", "typ": "JWT" } ``` -------------------------------- ### Create Sample Data Service Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-acl/docs/src/docs/tutorial.adoc Service to create users, roles, and grant permissions on reports. Includes methods for user creation, authentication as admin, and permission management. ```groovy package com.testacl import static org.springframework.security.acls.domain.BasePermission.ADMINISTRATION import static org.springframework.security.acls.domain.BasePermission.READ import static org.springframework.security.acls.domain.BasePermission.WRITE import org.springframework.security.authentication.UsernamePasswordAuthenticationToken import org.springframework.security.core.authority.AuthorityUtils import org.springframework.security.core.context.SecurityContextHolder as SCH import grails.gorm.transactions.Transactional @Transactional class SampleDataService { def aclService def aclUtilService def objectIdentityRetrievalStrategy void createSampleData() { createUsers() loginAsAdmin() grantPermissions() // logout SCH.clearContext() } private void loginAsAdmin() { // have to be authenticated as an admin to create ACLs SCH.context.authentication = new UsernamePasswordAuthenticationToken( 'admin', 'admin123', AuthorityUtils.createAuthorityList('ROLE_ADMIN')) } private void createUsers() { def roleAdmin = new Role(authority: 'ROLE_ADMIN').save() def roleUser = new Role(authority: 'ROLE_USER').save() 3.times { long id = it + 1 def user = new User("user$id", "password$id").save() UserRole.create user, roleUser } def admin = new User('admin', 'admin123').save() UserRole.create admin, roleUser UserRole.create admin, roleAdmin } private void grantPermissions() { def reports = [] 100.times { long id = it + 1 def report = new Report(name: "report$id").save() reports << report aclService.createAcl( objectIdentityRetrievalStrategy.getObjectIdentity(report)) } // grant user 1 admin on 11,12 and read on 1-67 aclUtilService.addPermission reports[10], 'user1', ADMINISTRATION aclUtilService.addPermission reports[11], 'user1', ADMINISTRATION 67.times { aclUtilService.addPermission reports[it], 'user1', READ } // grant user 2 read on 1-5, write on 5 5.times { aclUtilService.addPermission reports[it], 'user2', READ } aclUtilService.addPermission reports[4], 'user2', WRITE // user 3 has no grants // grant admin admin on all for (report in reports) { aclUtilService.addPermission report, 'admin', ADMINISTRATION } // grant user 1 ownership on 1,2 to allow the user to grant aclUtilService.changeOwner reports[0], 'user1' aclUtilService.changeOwner reports[1], 'user1' } } ``` -------------------------------- ### Configure Run-As Authentication Replacement Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-acl/docs/src/docs/usage/configuration.adoc Enable and configure Run-As authentication by setting a shared key. This is used to verify third-party tokens. ```groovy grails.plugin.springsecurity.useRunAs = true grails.plugin.springsecurity.runAs.key = 'your run-as key' ``` -------------------------------- ### Sample secureChannel.definition Configuration Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/channelSecurity.adoc Define URL patterns and their corresponding channel access rules (e.g., REQUIRES_SECURE_CHANNEL, REQUIRES_INSECURE_CHANNEL, ANY_CHANNEL). Ensure more specific rules precede less specific ones. ```groovy grails.plugin.springsecurity.secureChannel.definition = [ [pattern: '/login/**', access: 'REQUIRES_SECURE_CHANNEL'], [pattern: '/maps/**', access: 'REQUIRES_INSECURE_CHANNEL'], [pattern: '/images/login/**', access: 'REQUIRES_SECURE_CHANNEL'], [pattern: '/images/**', access: 'ANY_CHANNEL'] ] ``` -------------------------------- ### Create Grails Application Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/tutorials/usingControllerAnnotations.adoc Use the Grails CLI to create a new application and navigate into its directory. ```bash $ grails create-app bookstore $ cd bookstore ``` -------------------------------- ### Incorrect InterceptUrlMap Order Example Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/requestMappings/configGroovyMap.adoc Demonstrates an incorrect ordering of `interceptUrlMap` rules where a broader pattern precedes a more specific one, leading to unintended access. ```groovy [pattern: '/secure/**', access: ['ROLE_ADMIN', 'ROLE_SUPERUSER']], [pattern: '/secure/reallysecure/**', access: ['ROLE_SUPERUSER']] ``` -------------------------------- ### Registering an Event Listener in Java Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/events.adoc Register a listener to receive notifications for Spring Security events. This example shows how to add a listener using Java. ```java import org.springframework.security.authentication.event.AuthenticationSuccessEvent; import org.springframework.security.authentication.event.AuthenticationSuccessEventListener; beans.with { bean('authenticationSuccessListener', AuthenticationSuccessEventListener) { // Bean configuration } } springSecurityService.onSuccess = { AuthenticationSuccessEvent event, ApplicationContext app -> // Callback logic for successful authentication println "User ${event.authentication.principal} logged in successfully." } as (AuthenticationSuccessEvent, ApplicationContext) -> Void ``` -------------------------------- ### Registering an Event Listener in Groovy Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/events.adoc Register a listener to receive notifications for Spring Security events. This example shows how to add a listener using Groovy. ```groovy import org.springframework.security.authentication.event.AuthenticationSuccessEvent beans.with { bean('authenticationSuccessListener', org.springframework.security.authentication.event.AuthenticationSuccessEventListener) { // Bean configuration }} springSecurityService.onSuccess = { e, app -> // Callback logic for successful authentication println "User ${e.authentication.principal} logged in successfully." } ``` -------------------------------- ### loadCurrentUser() Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/helperClasses/springSecurityService.adoc Loads a proxy instance of the current user using GORM's load method. This is efficient when only the user's ID is needed, for example, in queries. ```APIDOC ## loadCurrentUser() ### Description Often it is not necessary to retrieve the entire domain class instance, for example when using it in a query where only the id is needed as a foreign key. This method uses the GORM `load` method to create a proxy instance. This will never be null, but can be invalid if the id doesn't correspond to a row in the database, although this is very unlikely in this scenario because the instance would have been there during authentication. If you need other data than just the id, use the `getCurrentUser` method instead. ### Method `springSecurityService.loadCurrentUser()` ### Example ```groovy class SomeController { def springSecurityService def someAction(Long id) { def user = springSecurityService.isLoggedIn() ? springSecurityService.loadCurrentUser() : null if (user) { CreditCard card = CreditCard.findByIdAndUser(id, user) // ... } // ... } } ``` ``` -------------------------------- ### Password Expired Controller Action Example Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/passwords/locking.adoc A simple controller action to retrieve the last username from the session, typically used to display a password reset form. ```groovy def passwordExpired() { [username: session['SPRING_SECURITY_LAST_USERNAME']] } ``` -------------------------------- ### Custom UserDetailsContextMapper Implementation Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-ldap/docs/src/docs/usage.adoc Example of a custom UserDetailsContextMapper that extracts additional fields like fullname, email, and title from LDAP. Implement this to customize user attribute mapping. ```groovy import org.springframework.security.core.userdetails.UserDetails import org.springframework.security.ldap.userdetails.UserDetailsContextMapper import org.springframework.ldap.core.DirContextOperations class MyUserDetailsContextMapper implements UserDetailsContextMapper { @Override void mapUserFromContext(DirContextOperations ctx, UserDetails user) { // Extract and map attributes here // Example: user.setFullName(ctx.getStringAttribute('fullname')) // Example: user.setEmail(ctx.getStringAttribute('email')) // Example: user.setTitle(ctx.getStringAttribute('title')) } @Override DirContextOperations mapUserToContext(UserDetails user) { // Not typically used for authentication, but can be implemented if needed return null } } ``` -------------------------------- ### s2ui-create-challenge-questions Script Usage Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-ui/docs/src/docs/scripts/s2ui-create-challenge-questions.adoc Use this script to generate controllers, services, domain objects, views, and configuration for challenge questions. Specify the domain class package, challenge QA class name, user domain class name, and an optional number of questions. ```bash grails s2ui-create-challenge-questions [number-of-questions] ``` ```bash s2ui-create-challenge-questions com.mycompany Profile com.mycompany.User 4 ``` -------------------------------- ### Specifying HTTP Method in @Secured Annotation Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/requestMappings/securedAnnotations.adoc Constrain access rules to specific HTTP methods (e.g., GET, POST) by using the httpMethod attribute in the @Secured annotation. ```groovy package com.mycompany.myapp import grails.plugin.springsecurity.annotation.Secured class SecureAnnotatedController { @Secured(value = ['ROLE_ADMIN'], httpMethod = 'GET') def create() { ... } @Secured(value = ['ROLE_ADMIN'], httpMethod = 'POST') def save() { ... } } ``` -------------------------------- ### Secured Action with Simplified Role Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/hierarchicalRoles.adoc Shows how to secure an action with a single role after establishing a role hierarchy. ```groovy package com.mycompany.myapp import grails.plugin.springsecurity.annotation.Secured class SomeController { @Secured('ROLE_ADMIN') def someAction() { ... } } ``` -------------------------------- ### Get Principal Object - SpringSecurityService Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/helperClasses/springSecurityService.adoc Retrieves the `Principal` object for the currently logged-in user. Typically, this is a `GrailsUser` instance, but it can be a custom `UserDetails` implementation if a custom `UserDetailsService` is configured. ```groovy def principal = springSecurityService.principal ``` -------------------------------- ### Create a Secure Controller Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/tutorials/usingControllerAnnotations.adoc Create a controller to demonstrate restricted access. This controller will be protected by security annotations. ```groovy package com.mycompany.myapp class SecureController { def index() { render 'Secure access only' } } ``` -------------------------------- ### Secure a Controller Action with @Secured Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/tutorials/usingControllerAnnotations.adoc Annotate an individual action within a controller to restrict access to specific roles. This example secures the 'index' action, requiring the 'ROLE_ADMIN' role. ```groovy package com.mycompany.myapp import grails.plugin.springsecurity.annotation.Secured class SecureController { @Secured('ROLE_ADMIN') def index() { render 'Secure access only' } } ``` -------------------------------- ### JWT Claims Example Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-rest/docs/src/docs/tokenStorage.adoc A base64-encoded JSON object containing the claims (payload) of a JSON Web Token (JWT). It includes expiration time, subject, roles, and issued at time. ```javascript { "exp": 1422990129, "sub": "jimi", "roles": [ "ROLE_ADMIN", "ROLE_USER" ], "iat": 1422986529 } ``` -------------------------------- ### CAS Sample Configuration Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-rest/docs/src/docs/oauth.adoc Configure the CAS client and its login URL in your application.groovy. Ensure the CAS configuration points to your CAS server's login endpoint. ```groovy grails { plugin { springsecurity { rest { oauth { frontendCallbackUrl = { String tokenValue -> "http://my.frontend-app.com/welcome#token=${tokenValue}" } cas { client = org.pac4j.cas.client.CasClient configuration = new org.pac4j.cas.config.CasConfiguration("https://my.cas-server.com/cas/login") } } } } } } ``` -------------------------------- ### Twitter OAuth Configuration Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-rest/docs/src/docs/oauth.adoc Configure Twitter OAuth integration by defining the client, key, secret, and default roles. This setup enables users to authenticate via their Twitter accounts. ```groovy grails { plugin { springsecurity { rest { oauth { frontendCallbackUrl = { String tokenValue -> "http://my.frontend-app.com/welcome#token=${tokenValue}" } twitter { client = org.pac4j.oauth.client.TwitterClient key = 'xxx' secret = 'yyy' defaultRoles = ['ROLE_USER', 'ROLE_TWITTER'] } } } } } } ``` -------------------------------- ### Secured Action with Multiple Admin Roles Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/hierarchicalRoles.adoc Demonstrates how to secure an action with multiple specific admin roles when not using hierarchical roles. ```groovy package com.mycompany.myapp import grails.plugin.springsecurity.annotation.Secured class SomeController { @Secured(['ROLE_ADMIN', 'ROLE_FINANCE_ADMIN', 'ROLE_SUPERADMIN']) def someAction() { ... } } ``` -------------------------------- ### Securing Service Methods with @PreAuthorize and @PostFilter Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-acl/docs/src/docs/usage/serviceMethods.adoc Demonstrates securing service methods using @PreAuthorize for pre-invocation checks and @PostFilter for post-invocation filtering based on permissions. Requires importing necessary annotations and domain classes. ```groovy import org.springframework.security.access.prepost.PostFilter import org.springframework.security.access.prepost.PreAuthorize import org.springframework.security.core.parameters.P import grails.gorm.transactions.Transactional import com.yourapp.Report class ReportService { @PreAuthorize("hasPermission(#id, 'com.yourapp.Report', read) or \ "hasPermission(#id, 'com.yourapp.Report', admin)") Report getReport(@P("id") long id) { Report.get(id) } @Transactional @PreAuthorize("hasRole('ROLE_USER')") Report createReport(params) { Report report = new Report(params) report.save() report } @PreAuthorize("hasRole('ROLE_USER')") @PostFilter("hasPermission(filterObject, read) or \ "hasPermission(filterObject, admin)") List getAllReports(params = [:]) { Report.list(params) } @Secured(['ROLE_USER', 'ROLE_ADMIN']) String getReportName(long id) { Report.get(id).name } @Transactional @PreAuthorize("hasPermission(#report, write) or \ "hasPermission(#report, admin)") Report updateReport(@P("report") Report report, params) { report.properties = params report.save() report } @Transactional @PreAuthorize("hasPermission(#report, delete) or \ "hasPermission(#report, admin)") void deleteReport(@P("report") Report report) { report.delete() } } ``` -------------------------------- ### Secure an Entire Controller with @Secured Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/tutorials/usingControllerAnnotations.adoc Annotate the entire controller class to apply access restrictions to all its actions. This example makes all actions within 'SecureController' accessible only to users with the 'ROLE_ADMIN' role. ```groovy package com.mycompany.myapp import grails.plugin.springsecurity.annotation.Secured @Secured('ROLE_ADMIN') class SecureController { def index() { render 'Secure access only' } } ``` -------------------------------- ### Run Grails Application Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/introduction/installation.adoc Use this command to run your Grails application. This is part of the verification process to ensure the Spring Security Core Plugin is correctly installed and enforcing security constraints. ```bash ./gradlew bootRun ``` -------------------------------- ### Granting a Role to a User Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/domainClasses/personAuthorityClass.adoc Demonstrates how to grant a role to a user using the `create` helper method of the UserRole class. Assumes `user` and `role` objects have already been loaded. ```groovy User user = ... Role role = ... UserRole.create user, role ``` -------------------------------- ### Migration: ROLE_USER,ROLE_ADMIN to SpEL Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/requestMappings/expressions.adoc Translates a traditional configuration requiring multiple roles to its SpEL equivalent using hasAnyRole. ```spel hasAnyRole('ROLE_USER','ROLE_ADMIN') ``` -------------------------------- ### Annotated Controller with Secured Annotation Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/requestMappings/expressions.adoc Use the @Secured annotation on controller actions to define access rules using SpEL expressions. This example shows how to require a specific role or a specific username. ```groovy package com.yourcompany.yourapp import grails.plugin.springsecurity.annotation.Secured class SecureController { @Secured("hasRole('ROLE_ADMIN')") def someAction() { ... } @Secured("authentication.name == 'ralph'") def someOtherAction() { ... } } ``` -------------------------------- ### Configure Memcached Token Storage Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-rest/docs/src/docs/tokenStorage.adoc Set Memcached host, username, password, and expiration time for token storage. Default settings should work for local development. ```properties grails.plugin.springsecurity.rest.token.storage.memcached.hosts = 'localhost:11211' grails.plugin.springsecurity.rest.token.storage.memcached.username = '' grails.plugin.springsecurity.rest.token.storage.memcached.password = '' grails.plugin.springsecurity.rest.token.storage.memcached.expiration = 3600 ``` -------------------------------- ### Get Current Authenticated User - SpringSecurityService Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/helperClasses/springSecurityService.adoc Retrieves the domain class instance for the currently authenticated user. Use this when you need full user domain object data. If only the ID is needed, consider `loadCurrentUser()`. ```groovy class SomeController { def springSecurityService def someAction() { def user = springSecurityService.currentUser ... } } ``` -------------------------------- ### Implement Secure Logout in main.gsp Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-acl/docs/src/docs/tutorial.adoc Add a secure logout mechanism to `main.gsp` using `` and `` with a submit button. This ensures logout is performed via POST, which is more secure than a GET request. ```xml Logged in as - Login ``` -------------------------------- ### Implement OAuth2AbstractProviderService Abstract Methods Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-oauth2/docs/src/docs/extensions.adoc Extend `OAuth2AbstractProviderService` and implement abstract methods to define the provider ID, API class, profile scope, scope separator, and token creation logic. ```groovy getProviderID // whatever you want to call your provider. getApiClass // points to your API implementation getProfileScope // comes from config /oauth2/userInfo getScopeSeparator // from the implementation that I've see usually: " " is used. createSpringAuthToken // parses the OAuth2AccessToken to get the email and id that could be used // to look up the user and puts them in a OAuth2SpringToken. // This is also a good place to validate the token either inline or calling a separate method * ``` -------------------------------- ### Customize Password Validation Regex Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-ui/docs/src/docs/customization.adoc Modify the validation regex for passwords to enforce specific complexity rules. This example sets a regex that requires at least one digit, one letter, and one symbol from the specified set. ```groovy grails.plugin.springsecurity.ui.password.validationRegex = "^.*(?=.*\\d)(?=.*[a-zA-Z])(?=.*[!@#$%^&]).*$" ``` -------------------------------- ### Get Authentication Object - SpringSecurityService Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/helperClasses/springSecurityService.adoc Retrieves the current user's Spring Security `Authentication` object. This object contains details like the username, authorities, and authentication status. It can be an anonymous authentication token if no user is logged in. ```groovy class SomeController { def springSecurityService def someAction() { def auth = springSecurityService.authentication String username = auth.username def authorities = auth.authorities // a Collection of GrantedAuthority boolean authenticated = auth.authenticated ... } } ``` -------------------------------- ### Implement DefaultApi20 Abstract Methods Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-oauth2/docs/src/docs/extensions.adoc Extend `DefaultApi20` to define the access token endpoint, authorization base URL, and access token extractor for your provider. ```groovy getAccessTokenEndpoint // I would get this from config which is /oauth2/token getAuthorizationBaseUrl // I would get this from get this from config which is /oauth2/authorize getAccessTokenExtractor // In some implementations the `OpenIdJsonTokenExtractor` is used. ``` -------------------------------- ### Create Persistent Token Domain Class Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/scripts/s2-create-persistent-token.adoc Use this command to create a domain class for persistent tokens. Specify the fully qualified name for your application. ```bash ./grailsw s2-create-persistent-token ``` ```bash ./grailsw s2-create-persistent-token com.yourapp.PersistentLogin ``` -------------------------------- ### Update Project Dependencies Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/introduction/installation.adoc Run this Gradle command in your project's root directory to clean the project and build it, ensuring all dependencies are updated. ```bash ./gradlew clean build ``` -------------------------------- ### Guard Access with createLink Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/helperClasses/securityTagLib.adoc Use the `` tag with `` to dynamically generate and guard access to URLs. Ensure `base: '/'` is included to prevent context path issues. ```html Manage Users ``` -------------------------------- ### GSP Example for Switch User Feature Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/switchUser.adoc This GSP code demonstrates how to conditionally display switch user elements. It shows the current logged-in user, a button to resume the original user session if switched, and a form to switch to another user if the user has the 'ROLE_SWITCH_USER' role. ```html Logged in as
Switch to user:
``` -------------------------------- ### Create Role Hierarchy Entry Domain Class Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/scripts/s2-create-role-hierarchy-entry.adoc Use this command to generate the domain class for storing role hierarchy entries. It requires the fully qualified class name as an argument. ```bash ./grailsw s2-create-role-hierarchy-entry ``` ```bash ./grailsw s2-create-role-hierarchy-entry com.yourapp.RoleHierarchyEntry ``` -------------------------------- ### Grails ActionSubmit Tag Warning Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/requestMappings.adoc This example demonstrates a warning about using Grails `` tags with Spring Security. These tags can lead to unintended access if not handled carefully, as they post to the default controller action. The workaround involves using separate forms with explicitly set actions. ```html ... ``` -------------------------------- ### Securing Switch User URL with Database Requestmap Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/switchUser.adoc When using database-backed Requestmaps, define a rule in BootStrap to protect the '/login/impersonate' URL with required roles. ```groovy new Requestmap(url: '/login/impersonate',\n configAttribute: 'ROLE_SWITCH_USER,IS_AUTHENTICATED_FULLY').save(flush: true) ``` -------------------------------- ### Enable fii.rejectPublicInvocations for 500 Error Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/requestMappings.adoc Configure these settings to reject un-mapped URLs with a 500 error page. `fii.rejectPublicInvocations` defaults to true, so it can be omitted. ```groovy grails.plugin.springsecurity.rejectIfNoRule = false grails.plugin.springsecurity.fii.rejectPublicInvocations = true ``` -------------------------------- ### Configure SystemWideSaltSource Bean Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/passwords/salt.adoc Configure `SystemWideSaltSource` as the `saltSource` bean in `application.groovy` to use a single, system-wide salt for all users. This is less robust than per-user salts but better than none. ```groovy import org.springframework.security.authentication.dao.SystemWideSaltSource beans = { saltSource(SystemWideSaltSource) { systemWideSalt = 'the_salt_value' } } ``` -------------------------------- ### Render Content When Access Denied Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/helperClasses/securityTagLib.adoc Use the `` tag to render content only when the specified expression evaluates to false or the URL is not allowed. This is the inverse of ``. ```html You're not a user ``` -------------------------------- ### Enable rejectIfNoRule for 403 Error Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/requestMappings.adoc Configure these settings to reject un-mapped URLs with a 403 error code. `rejectIfNoRule` defaults to true, so it can be omitted. ```groovy grails.plugin.springsecurity.rejectIfNoRule = true grails.plugin.springsecurity.fii.rejectPublicInvocations = false ``` -------------------------------- ### Configure OAuth2 Callback URL Mapping Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-oauth2/docs/src/docs/extensions.adoc Set up a URL mapping in the application to handle the OAuth2 callback, typically '/oauth2/$provider/success'. ```groovy "/oauth2/$provider/success"(controller: 'login', action: 'oauth2Success') ``` -------------------------------- ### Basic Authentication Configuration Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/authentication/basicAndDigestAuth.adoc Enable Basic Authentication and set a custom realm name. This prompts users with a browser login dialog instead of redirecting to a login page. ```groovy grails.plugin.springsecurity.useBasicAuth = true grails.plugin.springsecurity.basic.realmName = "Ralph's Bait and Tackle" ``` -------------------------------- ### Generate All for Role Domain Class Source: https://github.com/apache/grails-spring-security/blob/7.0.x/plugin-core/docs/src/docs/tutorials/usingControllerAnnotations.adoc Use the grails generate-all command to create controllers and views for the Role domain class. Remember to secure the generated controllers using the @Secured annotation. ```bash $ grails generate-all com.mycompany.myapp.Role ```