| [[switchUser]] |
| == Switch User |
| |
| To enable a user to switch from the current `Authentication` to another user's, set the `useSwitchUserFilter` attribute to `true`. This feature is similar to the "`su`" command in Unix. It enables, for example, an admin to act as a regular user to perform some actions, and then switch back. |
| |
| [WARNING] |
| ==== |
| This feature is very powerful; it allows full access to everything the switched-to user can access without requiring the user's password. Limit who can use this feature by guarding the user switch URL with a role, for example, `ROLE_SWITCH_USER`, `ROLE_ADMIN`, and so on. |
| ==== |
| |
| === Switching to Another User |
| |
| To switch to another user, typically you create a form that submits to `/login/impersonate`: |
| |
| [source,html] |
| .Listing {counter:listing}. An HTML form for switching to another user |
| ---- |
| <sec:ifAllGranted roles='ROLE_SWITCH_USER'> |
| |
| <form action='/login/impersonate' method='POST'> |
| Switch to user: <input type='text' name='username'/> <br/> |
| <input type='submit' value='Switch'/> |
| </form> |
| |
| </sec:ifAllGranted> |
| ---- |
| |
| Here the form is guarded by a check that the logged-in user has `ROLE_SWITCH_USER` and is not shown otherwise. You also need to guard the user switch URL, and the approach depends on your mapping scheme. If you use annotations, add a rule to the `controllerAnnotations.staticRules` attribute: |
| |
| [source,groovy] |
| .Listing {counter:listing}. Guarding the switch user url with `controllerAnnotations.staticRules` |
| ---- |
| grails.plugin.springsecurity.controllerAnnotations.staticRules = [ |
| ... |
| [pattern: '/login/impersonate', access: ['ROLE_SWITCH_USER', 'IS_AUTHENTICATED_FULLY']] |
| ] |
| ---- |
| |
| If you use ``Requestmap``s, create a rule like this (for example, in `BootStrap`): |
| |
| [source,groovy] |
| .Listing {counter:listing}. Guarding the switch user url with a database requestmap |
| ---- |
| new Requestmap(url: '/login/impersonate', |
| configAttribute: 'ROLE_SWITCH_USER,IS_AUTHENTICATED_FULLY').save(flush: true) |
| ---- |
| |
| If you use the static `application.groovy` map, add the rule there: |
| |
| [source,groovy] |
| .Listing {counter:listing}. Guarding the switch user url with `interceptUrlMap` |
| ---- |
| grails.plugin.springsecurity.interceptUrlMap = [ |
| ... |
| [pattern: '/login/impersonate', access: ['ROLE_SWITCH_USER', 'IS_AUTHENTICATED_FULLY']] |
| ] |
| ---- |
| |
| === Switching Back to Original User |
| To resume as the original user, POST to `/logout/impersonate`. |
| |
| [source,html] |
| .Listing {counter:listing}. A link to switch back to the real user |
| ---- |
| <sec:ifSwitched> |
| <form action='${request.contextPath}/logout/impersonate' method='POST'> |
| <input type='submit' value="Resume as ${grails.plugin.springsecurity.SpringSecurityUtils.switchedUserOriginalUsername}"/> |
| </form> |
| </sec:ifSwitched> |
| ---- |
| |
| === Customizing URLs |
| You can customize the URLs that are used for this feature, although it is rarely necessary: |
| |
| [source,groovy] |
| ---- |
| grails.plugin.springsecurity.switchUser.switchUserUrl = ... |
| grails.plugin.springsecurity.switchUser.exitUserUrl = ... |
| grails.plugin.springsecurity.switchUser.targetUrl = ... |
| grails.plugin.springsecurity.switchUser.switchFailureUrl = ... |
| ---- |
| |
| .Switch user configuration options |
| [cols="30,30,40"] |
| |==================== |
| | *Property* | *Default* | *Meaning* |
| |
| |useSwitchUserFilter |
| |`false` |
| |Whether to use the switch user filter |
| |
| |switchUser.switchUserUrl |
| |"`/login/impersonate`" |
| |URL to access (via POST) to switch to another user |
| |
| |switchUser.exitUserUrl |
| |"`/logout/impersonate`" |
| |URL to access (via POST) to switch to another user |
| |
| |switchUser.switchUserMatcher |
| |`SwitchUserFilter.switchUserMatcher` |
| |An alternative to `switchUserUrl`, define an `AntPathRequestMatcher` to determine if a request needs to switch user. |
| |
| |switchUser.exitUserMatcher |
| |`SwitchUserFilter.exitUserMatcher` |
| |An alternative to `exitUserUrl`, define an `AntPathRequestMatcher` to determine if a request needs to exit switch user. |
| |
| |switchUser.targetUrl |
| |Same as `successHandler.defaultTargetUrl` |
| |URL for redirect after switching |
| |
| |switchUser.switchFailureUrl |
| |Same as `failureHandler.defaultFailureUrl` |
| |URL for redirect after an error during an attempt to switch |
| |
| |switchUser.usernameParameter |
| |`SwitchUserFilter.SPRING_SECURITY_SWITCH_USERNAME_KEY` |
| |The username request parameter name |
| |==================== |
| |
| === GSP Code |
| |
| One approach to supporting the switch user feature is to add code to one or more of your GSP templates. In this example the current username is displayed, and if the user has switched from another (using the `sec:ifSwitched` tag) then a "`resume`" button is displayed. If not, and the user has the required role, a form is displayed to allow input of the username to switch to: |
| |
| [source,html] |
| .Listing {counter:listing}. Example GSP code to conditionally display a switch user form and resume form |
| ---- |
| <sec:ifLoggedIn> |
| Logged in as <sec:username/> |
| </sec:ifLoggedIn> |
| |
| <sec:ifSwitched> |
| <form action='${request.contextPath}/logout/impersonate' method='POST'> |
| <input type='submit' value="Resume as ${grails.plugin.springsecurity.SpringSecurityUtils.switchedUserOriginalUsername}"/> |
| </form> |
| </sec:ifSwitched> |
| |
| <sec:ifNotSwitched> |
| <sec:ifAllGranted roles='ROLE_SWITCH_USER'> |
| |
| <form action='${request.contextPath}/login/impersonate' method='POST'> |
| Switch to user: <input type='text' name='username'/><br/> |
| <input type='submit' value='Switch'/> |
| </form> |
| |
| </sec:ifAllGranted> |
| </sec:ifNotSwitched> |
| ---- |