1 | package dbnp.authentication |
---|
2 | |
---|
3 | import grails.converters.JSON |
---|
4 | |
---|
5 | import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils |
---|
6 | |
---|
7 | import org.springframework.security.authentication.AccountExpiredException |
---|
8 | import org.springframework.security.authentication.CredentialsExpiredException |
---|
9 | import org.springframework.security.authentication.DisabledException |
---|
10 | import org.springframework.security.authentication.LockedException |
---|
11 | import org.springframework.security.core.context.SecurityContextHolder as SCH |
---|
12 | import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter |
---|
13 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter |
---|
14 | |
---|
15 | class LoginController { |
---|
16 | /** |
---|
17 | * Dependency injection for the authenticationTrustResolver. |
---|
18 | */ |
---|
19 | def authenticationTrustResolver |
---|
20 | |
---|
21 | /** |
---|
22 | * Dependency injection for the springSecurityService. |
---|
23 | */ |
---|
24 | def springSecurityService |
---|
25 | |
---|
26 | /** |
---|
27 | * Dependency injection for the GSCF authentication service |
---|
28 | */ |
---|
29 | def authenticationService |
---|
30 | |
---|
31 | /** |
---|
32 | * Default action; redirects to 'defaultTargetUrl' if logged in, /login/auth otherwise. |
---|
33 | */ |
---|
34 | def index = { |
---|
35 | if (springSecurityService.isLoggedIn()) { |
---|
36 | redirect uri: SpringSecurityUtils.securityConfig.successHandler.defaultTargetUrl |
---|
37 | } |
---|
38 | else { |
---|
39 | redirect action: auth, params: params |
---|
40 | } |
---|
41 | } |
---|
42 | |
---|
43 | /** |
---|
44 | * Show the login page. |
---|
45 | */ |
---|
46 | def auth = { |
---|
47 | def config = SpringSecurityUtils.securityConfig |
---|
48 | if (springSecurityService.isLoggedIn()) { |
---|
49 | if (params.returnURI) { |
---|
50 | // see basefilters |
---|
51 | redirect uri: params.returnURI |
---|
52 | } else { |
---|
53 | redirect uri: config.successHandler.defaultTargetUrl |
---|
54 | } |
---|
55 | return |
---|
56 | } |
---|
57 | |
---|
58 | String view = 'auth' |
---|
59 | String postUrl = "${request.contextPath}${config.apf.filterProcessesUrl}" |
---|
60 | render view: view, model: [postUrl: postUrl, rememberMeParameter: config.rememberMe.parameter] |
---|
61 | } |
---|
62 | |
---|
63 | /** |
---|
64 | * Shows the login page for users from a module |
---|
65 | */ |
---|
66 | def auth_remote = { |
---|
67 | def consumer = params.consumer |
---|
68 | def token = params.token |
---|
69 | |
---|
70 | if (consumer == null || token == null) { |
---|
71 | throw new Exception("Consumer and Token must be given!"); |
---|
72 | } |
---|
73 | |
---|
74 | def returnUrl = params.returnUrl |
---|
75 | |
---|
76 | // If the user is already authenticated with this session_id, redirect |
---|
77 | // him |
---|
78 | if (authenticationService.isRemotelyLoggedIn(consumer, token)) { |
---|
79 | if (returnUrl) { |
---|
80 | redirect url: returnUrl |
---|
81 | } else { |
---|
82 | redirect controller: 'home' |
---|
83 | } |
---|
84 | } |
---|
85 | |
---|
86 | // If the user is already logged in locally, we log him in and |
---|
87 | // immediately redirect him |
---|
88 | if (authenticationService.isLoggedIn()) { |
---|
89 | authenticationService.logInRemotely(consumer, token, authenticationService.getLoggedInUser()) |
---|
90 | |
---|
91 | if (returnUrl) { |
---|
92 | redirect url: returnUrl |
---|
93 | } else { |
---|
94 | redirect controller: 'home' |
---|
95 | } |
---|
96 | } |
---|
97 | |
---|
98 | // Otherwise we show the login screen |
---|
99 | def config = SpringSecurityUtils.securityConfig |
---|
100 | String view = 'auth' |
---|
101 | String postUrl = "${request.contextPath}${config.apf.filterProcessesUrl}" |
---|
102 | String redirectUrl = g.createLink(controller: 'login', action: 'auth_remote', params: [consumer: params.consumer, token: params.token, returnUrl: params.returnUrl], absolute: true) |
---|
103 | render view: view, model: [postUrl: postUrl, |
---|
104 | rememberMeParameter: config.rememberMe.parameter, redirectUrl: redirectUrl] |
---|
105 | } |
---|
106 | |
---|
107 | /** |
---|
108 | * Show denied page. |
---|
109 | */ |
---|
110 | def denied = { |
---|
111 | if (springSecurityService.isLoggedIn() && |
---|
112 | authenticationTrustResolver.isRememberMe(SCH.context?.authentication)) { |
---|
113 | // have cookie but the page is guarded with IS_AUTHENTICATED_FULLY |
---|
114 | redirect action: full, params: params |
---|
115 | } |
---|
116 | } |
---|
117 | |
---|
118 | /** |
---|
119 | * Login page for users with a remember-me cookie but accessing a IS_AUTHENTICATED_FULLY page. |
---|
120 | */ |
---|
121 | def full = { |
---|
122 | def config = SpringSecurityUtils.securityConfig |
---|
123 | render view: 'auth', params: params, |
---|
124 | model: [hasCookie: authenticationTrustResolver.isRememberMe(SCH.context?.authentication), |
---|
125 | postUrl: "${request.contextPath}${config.apf.filterProcessesUrl}"] |
---|
126 | } |
---|
127 | |
---|
128 | /** |
---|
129 | * Callback after a failed login. Redirects to the auth page with a warning message. |
---|
130 | */ |
---|
131 | def authfail = { |
---|
132 | def username = session[UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY] |
---|
133 | String msg = '' |
---|
134 | def exception = session[AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY] |
---|
135 | if (exception) { |
---|
136 | if (exception instanceof AccountExpiredException) { |
---|
137 | msg = SpringSecurityUtils.securityConfig.errors.login.expired |
---|
138 | } |
---|
139 | else if (exception instanceof CredentialsExpiredException) { |
---|
140 | msg = SpringSecurityUtils.securityConfig.errors.login.passwordExpired |
---|
141 | } |
---|
142 | else if (exception instanceof DisabledException) { |
---|
143 | msg = SpringSecurityUtils.securityConfig.errors.login.disabled |
---|
144 | } |
---|
145 | else if (exception instanceof LockedException) { |
---|
146 | msg = SpringSecurityUtils.securityConfig.errors.login.locked |
---|
147 | } |
---|
148 | else { |
---|
149 | msg = SpringSecurityUtils.securityConfig.errors.login.fail |
---|
150 | } |
---|
151 | } |
---|
152 | |
---|
153 | if (springSecurityService.isAjax(request)) { |
---|
154 | // set output header to json |
---|
155 | response.contentType = 'application/json' |
---|
156 | |
---|
157 | render([error: msg] as JSON) |
---|
158 | } |
---|
159 | else { |
---|
160 | flash.message = msg |
---|
161 | redirect action: auth, params: params |
---|
162 | } |
---|
163 | } |
---|
164 | |
---|
165 | /** |
---|
166 | * The Ajax success redirect url. |
---|
167 | */ |
---|
168 | def ajaxSuccess = { |
---|
169 | // set output header to json |
---|
170 | response.contentType = 'application/json' |
---|
171 | |
---|
172 | render([success: true, username: springSecurityService.authentication.name] as JSON) |
---|
173 | } |
---|
174 | |
---|
175 | /** |
---|
176 | * The Ajax denied redirect url. |
---|
177 | */ |
---|
178 | def ajaxDenied = { |
---|
179 | // set output header to json |
---|
180 | response.contentType = 'application/json' |
---|
181 | |
---|
182 | render([error: 'access denied'] as JSON) |
---|
183 | } |
---|
184 | } |
---|