[58] | 1 | import org.codehaus.groovy.grails.plugins.springsecurity.RedirectUtils |
---|
| 2 | import org.grails.plugins.springsecurity.service.AuthenticateService |
---|
| 3 | |
---|
| 4 | import org.springframework.security.AuthenticationTrustResolverImpl |
---|
| 5 | import org.springframework.security.DisabledException |
---|
| 6 | import org.springframework.security.context.SecurityContextHolder as SCH |
---|
| 7 | import org.springframework.security.ui.AbstractProcessingFilter |
---|
| 8 | import org.springframework.security.ui.webapp.AuthenticationProcessingFilter |
---|
| 9 | |
---|
| 10 | /** |
---|
| 11 | * Login Controller (Example). |
---|
| 12 | */ |
---|
| 13 | class LoginController { |
---|
| 14 | |
---|
[167] | 15 | /** |
---|
| 16 | * Dependency injection for the authentication service. |
---|
| 17 | */ |
---|
| 18 | def authenticateService |
---|
[58] | 19 | |
---|
[167] | 20 | /** |
---|
| 21 | * Dependency injection for OpenIDConsumer. |
---|
| 22 | */ |
---|
| 23 | def openIDConsumer |
---|
[58] | 24 | |
---|
[167] | 25 | /** |
---|
| 26 | * Dependency injection for OpenIDAuthenticationProcessingFilter. |
---|
| 27 | */ |
---|
| 28 | def openIDAuthenticationProcessingFilter |
---|
[58] | 29 | |
---|
[167] | 30 | private final authenticationTrustResolver = new AuthenticationTrustResolverImpl() |
---|
[58] | 31 | |
---|
[167] | 32 | def index = { |
---|
| 33 | if (isLoggedIn()) { |
---|
| 34 | redirect uri: '/' |
---|
| 35 | } |
---|
| 36 | else { |
---|
| 37 | redirect action: auth, params: params |
---|
| 38 | } |
---|
| 39 | } |
---|
[58] | 40 | |
---|
[59] | 41 | def loggedOut = { |
---|
| 42 | flash['message'] = 'Successfully logged out' |
---|
| 43 | auth() |
---|
| 44 | } |
---|
| 45 | |
---|
[167] | 46 | /** |
---|
| 47 | * Show the login page. |
---|
| 48 | */ |
---|
| 49 | def auth = { |
---|
[58] | 50 | |
---|
[167] | 51 | nocache(response) |
---|
[58] | 52 | |
---|
[167] | 53 | if (isLoggedIn()) { |
---|
| 54 | redirect uri: '/' |
---|
| 55 | return |
---|
| 56 | } |
---|
[58] | 57 | |
---|
[167] | 58 | String view |
---|
| 59 | String postUrl |
---|
| 60 | def config = authenticateService.securityConfig.security |
---|
| 61 | if (config.useOpenId) { |
---|
| 62 | view = 'openIdAuth' |
---|
| 63 | postUrl = "${request.contextPath}/login/openIdAuthenticate" |
---|
| 64 | } |
---|
| 65 | else if (config.useFacebook) { |
---|
| 66 | view = 'facebookAuth' |
---|
| 67 | postUrl = "${request.contextPath}${config.facebook.filterProcessesUrl}" |
---|
| 68 | } |
---|
| 69 | else { |
---|
| 70 | view = 'auth' |
---|
| 71 | postUrl = "${request.contextPath}${config.filterProcessesUrl}" |
---|
| 72 | } |
---|
[58] | 73 | |
---|
[167] | 74 | render view: view, model: [postUrl: postUrl] |
---|
| 75 | } |
---|
[58] | 76 | |
---|
[167] | 77 | /** |
---|
| 78 | * Form submit action to start an OpenID authentication. |
---|
| 79 | */ |
---|
| 80 | def openIdAuthenticate = { |
---|
| 81 | String openID = params['j_username'] |
---|
| 82 | try { |
---|
| 83 | String returnToURL = RedirectUtils.buildRedirectUrl( |
---|
| 84 | request, response, openIDAuthenticationProcessingFilter.filterProcessesUrl) |
---|
| 85 | String redirectUrl = openIDConsumer.beginConsumption(request, openID, returnToURL) |
---|
| 86 | redirect url: redirectUrl |
---|
| 87 | } |
---|
| 88 | catch (org.springframework.security.ui.openid.OpenIDConsumerException e) { |
---|
| 89 | log.error "Consumer error: $e.message", e |
---|
| 90 | redirect url: openIDAuthenticationProcessingFilter.authenticationFailureUrl |
---|
| 91 | } |
---|
| 92 | } |
---|
[58] | 93 | |
---|
[167] | 94 | // Login page (function|json) for Ajax access. |
---|
| 95 | def authAjax = { |
---|
| 96 | nocache(response) |
---|
| 97 | //this is example: |
---|
| 98 | render """ |
---|
| 99 | <script type='text/javascript'> |
---|
| 100 | (function() { |
---|
| 101 | loginForm(); |
---|
| 102 | })(); |
---|
| 103 | </script> |
---|
| 104 | """ |
---|
| 105 | } |
---|
[58] | 106 | |
---|
[167] | 107 | /** |
---|
| 108 | * The Ajax success redirect url. |
---|
| 109 | */ |
---|
| 110 | def ajaxSuccess = { |
---|
| 111 | nocache(response) |
---|
| 112 | render '{success: true}' |
---|
| 113 | } |
---|
[58] | 114 | |
---|
[167] | 115 | /** |
---|
| 116 | * Show denied page. |
---|
| 117 | */ |
---|
| 118 | def denied = { |
---|
| 119 | if (isLoggedIn() && authenticationTrustResolver.isRememberMe(SCH.context?.authentication)) { |
---|
| 120 | // have cookie but the page is guarded with IS_AUTHENTICATED_FULLY |
---|
| 121 | redirect action: full, params: params |
---|
| 122 | } |
---|
| 123 | } |
---|
[58] | 124 | |
---|
[167] | 125 | /** |
---|
| 126 | * Login page for users with a remember-me cookie but accessing a IS_AUTHENTICATED_FULLY page. |
---|
| 127 | */ |
---|
| 128 | def full = { |
---|
| 129 | render view: 'auth', params: params, |
---|
| 130 | model: [hasCookie: authenticationTrustResolver.isRememberMe(SCH.context?.authentication)] |
---|
| 131 | } |
---|
[58] | 132 | |
---|
[167] | 133 | // Denial page (data|view|json) for Ajax access. |
---|
| 134 | def deniedAjax = { |
---|
| 135 | //this is example: |
---|
| 136 | render "{error: 'access denied'}" |
---|
| 137 | } |
---|
[58] | 138 | |
---|
[167] | 139 | /** |
---|
| 140 | * login failed |
---|
| 141 | */ |
---|
| 142 | def authfail = { |
---|
[58] | 143 | |
---|
[167] | 144 | def username = session[AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY] |
---|
| 145 | def msg = '' |
---|
[166] | 146 | def person = Person.findByLoginName(username) |
---|
[167] | 147 | def exception = session[AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY] |
---|
| 148 | if (exception) { |
---|
| 149 | if (exception instanceof DisabledException) { |
---|
| 150 | msg = "[$username] is disabled." |
---|
| 151 | } |
---|
[172] | 152 | else if (person?.authorities?.isEmpty()) { |
---|
| 153 | msg = "[$username] has no granted authority." |
---|
[166] | 154 | } |
---|
[167] | 155 | else { |
---|
| 156 | msg = "[$username] wrong username/password." |
---|
| 157 | } |
---|
| 158 | } |
---|
[58] | 159 | |
---|
[167] | 160 | if (isAjax()) { |
---|
| 161 | render "{error: '${msg}'}" |
---|
| 162 | } |
---|
| 163 | else { |
---|
| 164 | flash.message = msg |
---|
| 165 | redirect action: auth, params: params |
---|
| 166 | } |
---|
| 167 | } |
---|
[58] | 168 | |
---|
[167] | 169 | /** |
---|
| 170 | * Check if logged in. |
---|
| 171 | */ |
---|
| 172 | private boolean isLoggedIn() { |
---|
| 173 | return authenticateService.isLoggedIn() |
---|
| 174 | } |
---|
[58] | 175 | |
---|
[167] | 176 | private boolean isAjax() { |
---|
| 177 | return authenticateService.isAjax(request) |
---|
| 178 | } |
---|
[58] | 179 | |
---|
[167] | 180 | /** cache controls */ |
---|
| 181 | private void nocache(response) { |
---|
| 182 | response.setHeader('Cache-Control', 'no-cache') // HTTP 1.1 |
---|
| 183 | response.addDateHeader('Expires', 0) |
---|
| 184 | response.setDateHeader('max-age', 0) |
---|
| 185 | response.setIntHeader ('Expires', -1) //prevents caching at the proxy server |
---|
| 186 | response.addHeader('cache-Control', 'private') //IE5.x only |
---|
| 187 | } |
---|
[58] | 188 | } |
---|