source: trunk/grails-app/controllers/dbnp/authentication/LoginController.groovy @ 2083

Last change on this file since 2083 was 2083, checked in by work@…, 11 years ago

shibboleth changes - in development...

  • Property svn:keywords set to Rev Author Date
File size: 8.5 KB
Line 
1package dbnp.authentication
2
3import grails.converters.JSON
4
5import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
6
7import org.springframework.security.authentication.AccountExpiredException
8import org.springframework.security.authentication.CredentialsExpiredException
9import org.springframework.security.authentication.DisabledException
10import org.springframework.security.authentication.LockedException
11import org.springframework.security.core.context.SecurityContextHolder as SCH
12import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter
13import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
14import org.codehaus.groovy.grails.commons.ConfigurationHolder
15
16import dbnp.authentication.*
17
18class LoginController {
19        /**
20         * Dependency injection for the authenticationTrustResolver.
21         */
22        def authenticationTrustResolver
23
24        /**
25         * Dependency injection for the springSecurityService.
26         */
27        def springSecurityService
28
29        /**
30         * Dependency injection for the GSCF authentication service
31         */
32        def authenticationService
33
34        /**
35         * Default action; redirects to 'defaultTargetUrl' if logged in, /login/auth otherwise.
36         */
37        def index = {
38                if (springSecurityService.isLoggedIn()) {
39                        redirect uri: SpringSecurityUtils.securityConfig.successHandler.defaultTargetUrl
40                }
41                else {
42                        redirect action: auth, params: params
43                }
44        }
45
46        /**
47         * Show the login page.
48         */
49        def auth = {
50                def config = SpringSecurityUtils.securityConfig
51
52                if (springSecurityService.isLoggedIn()) {
53                        if (params.returnURI) {
54                                // see basefilters
55                                redirect uri: params.returnURI
56                        } else {
57                                redirect uri: config.successHandler.defaultTargetUrl
58                        }
59                        return
60                } else if (request.getHeaderNames().find{ it.toLowerCase() == 'useShibboleth'.toLowerCase() }) {
61                        // authenticated through shibboleth?
62                        if (request.getHeaderNames().find{ it.toLowerCase() == 'persistent-id'.toLowerCase() }) {
63                                // get shibboleth data
64                                // note: sometimes apache makes the request headers lowercase, sometimes
65                                //               it doesn't. To make sure it always works we use a case insensitive
66                                //               finder to find the request header name
67                                def shibPersistentId    = request.getHeader(request.getHeaderNames().find{ it.toLowerCase() == 'persistent-id'.toLowerCase() })
68                                def shibUid                             = request.getHeader("uid")
69                                def shibEmail                   = request.getHeader(request.getHeaderNames().find{ it.toLowerCase() == 'Shib-InetOrgPerson-mail'.toLowerCase() })
70                                def shibOrganization    = request.getHeader(request.getHeaderNames().find{ it.toLowerCase() == 'schacHomeOrganization'.toLowerCase() })
71                                def shibDisplayName             = request.getHeader(request.getHeaderNames().find{ it.toLowerCase() == 'displayName'.toLowerCase() })
72
73                                // does a user exist with this username?
74                                def user                                = SecUser.findByUsername(shibPersistentId)
75println "user: "
76println user
77                                if (!user) {
78println "creating user"
79                                        // no, create a new user
80                                        user = new SecUser()
81                                        user.username           = shibPersistentId
82                                        user.password           = springSecurityService.encodePassword("myDummyPassword", shibPersistentId)
83                                        user.email                      = shibEmail
84                                        user.displayName        = shibDisplayName
85                                        user.organization       = shibOrganization
86                                        user.uid                        = shibUid
87                                        user.shibbolethUser     = true
88                                        user.enabled            = true
89                                        user.userConfirmed      = true
90                                        user.adminConfirmed     = true
91                                        user.accountExpired     = false
92                                        user.accountLocked      = false
93                                        user.save(failOnError:true, flush: true)
94println user
95                                }
96
97                                // login user
98                                springSecurityService.reauthenticate(user.username, user.password)
99println "bla"
100                                // redirect user
101                                if (params.returnURI) {
102                                        // see basefilters
103                                        redirect uri: params.returnURI
104                                } else {
105                                        redirect uri: config.successHandler.defaultTargetUrl
106                                }
107                        }
108                } else {
109                        println "nope..."
110                }
111
112                String view = 'auth'
113                String postUrl = "${request.contextPath}${config.apf.filterProcessesUrl}"
114                render view: view, model: [postUrl: postUrl, rememberMeParameter: config.rememberMe.parameter]
115        }
116
117        /**
118         * Shows the login page for users from a module
119         */
120        def auth_remote = {
121                def consumer = params.consumer
122                def token = params.token
123               
124                // Silent means that the user will be sent back, regardless of his login state. He will not
125                // be redirected to the login page.
126                def silent = params.silent ? Boolean.valueOf( params.silent ) : false;
127               
128                if (consumer == null || token == null) {
129                        throw new Exception("Consumer and Token must be given!");
130                }
131
132                log.info( "Remote authentication with " + consumer + " and " + token )
133               
134                def returnUrl;
135               
136                // If no returnUrl is given, find the previous one from the session
137                if( params.returnUrl ) {
138                        returnUrl = params.returnUrl;
139                        session.authRemoteUrl = returnUrl;
140                } else if( session.authRemoteUrl ) {
141                        returnUrl = session.authRemoteUrl;
142                }
143
144                // If the user is already authenticated with this session_id, redirect
145                // him
146                if (authenticationService.isRemotelyLoggedIn(consumer, token)) {
147                        if (returnUrl) {
148                                redirect url: returnUrl
149                        } else {
150                                redirect controller: 'home'
151                        }
152                        return;
153                }
154
155                // If the user is already logged in locally, we log him in and
156                // immediately redirect him
157                if (authenticationService.isLoggedIn()) {
158                        authenticationService.logInRemotely(consumer, token, authenticationService.getLoggedInUser())
159
160                        if (returnUrl) {
161                                redirect url: returnUrl
162                        } else {
163                                redirect controller: 'home'
164                        }
165                        return;
166                }
167               
168                // On silent login, the user should be sent back anyway
169                if( silent ) {
170                        if (returnUrl) {
171                                redirect url: returnUrl
172                        } else {
173                                redirect controller: 'home'
174                        }
175                }
176               
177                // Otherwise we show the login screen
178                def config = SpringSecurityUtils.securityConfig
179                String view = 'auth'
180                String postUrl = "${request.contextPath}${config.apf.filterProcessesUrl}"
181               
182                String redirectUrl = g.createLink(controller: 'login', action: 'auth_remote', params: [consumer: params.consumer, token: params.token], absolute: true)
183                render view: view, model: [postUrl: postUrl,
184                        rememberMeParameter: config.rememberMe.parameter, redirectUrl: redirectUrl]
185        }
186
187        /**
188         * Show denied page.
189         */
190        def denied = {
191                if (springSecurityService.isLoggedIn() &&
192                        authenticationTrustResolver.isRememberMe(SCH.context?.authentication)) {
193                        // have cookie but the page is guarded with IS_AUTHENTICATED_FULLY
194                        redirect action: full, params: params
195                }
196        }
197
198        /**
199         * Login page for users with a remember-me cookie but accessing a IS_AUTHENTICATED_FULLY page.
200         */
201        def full = {
202                def config = SpringSecurityUtils.securityConfig
203                render view: 'auth', params: params,
204                        model: [hasCookie: authenticationTrustResolver.isRememberMe(SCH.context?.authentication),
205                                postUrl: "${request.contextPath}${config.apf.filterProcessesUrl}"]
206        }
207
208        /**
209         * Callback after a failed login. Redirects to the auth page with a warning message.
210         */
211        def authfail = {
212                def username = session[UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
213                String msg = ''
214                def exception = session[AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY]
215                if (exception) {
216                        if (exception instanceof AccountExpiredException) {
217                                msg = SpringSecurityUtils.securityConfig.errors.login.expired
218                        }
219                        else if (exception instanceof CredentialsExpiredException) {
220                                msg = SpringSecurityUtils.securityConfig.errors.login.passwordExpired
221                        }
222                        else if (exception instanceof DisabledException) {
223                                msg = SpringSecurityUtils.securityConfig.errors.login.disabled
224                        }
225                        else if (exception instanceof LockedException) {
226                                msg = SpringSecurityUtils.securityConfig.errors.login.locked
227                        }
228                        else {
229                                msg = SpringSecurityUtils.securityConfig.errors.login.fail
230                        }
231                }
232
233                if (springSecurityService.isAjax(request)) {
234                        // set output header to json
235                        response.contentType = 'application/json'
236
237                        render([error: msg] as JSON)
238                }
239                else {
240                        flash.message = msg
241                        redirect action: auth, params: params
242                }
243        }
244
245        /**
246         * The Ajax success redirect url.
247         */
248        def ajaxSuccess = {
249                // set output header to json
250                response.contentType = 'application/json'
251
252                render([success: true, username: springSecurityService.authentication.name] as JSON)
253        }
254
255        /**
256         * The Ajax denied redirect url.
257         */
258        def ajaxDenied = {
259                // set output header to json
260                response.contentType = 'application/json'
261
262                render([error: 'access denied'] as JSON)
263        }
264}
Note: See TracBrowser for help on using the repository browser.