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 | |
---|
15 | /** |
---|
16 | * Dependency injection for the authentication service. |
---|
17 | */ |
---|
18 | def authenticateService |
---|
19 | |
---|
20 | /** |
---|
21 | * Dependency injection for OpenIDConsumer. |
---|
22 | */ |
---|
23 | def openIDConsumer |
---|
24 | |
---|
25 | /** |
---|
26 | * Dependency injection for OpenIDAuthenticationProcessingFilter. |
---|
27 | */ |
---|
28 | def openIDAuthenticationProcessingFilter |
---|
29 | |
---|
30 | private final authenticationTrustResolver = new AuthenticationTrustResolverImpl() |
---|
31 | |
---|
32 | def index = { |
---|
33 | if (isLoggedIn()) { |
---|
34 | redirect uri: '/' |
---|
35 | } |
---|
36 | else { |
---|
37 | redirect action: auth, params: params |
---|
38 | } |
---|
39 | } |
---|
40 | |
---|
41 | def loggedOut = { |
---|
42 | flash['message'] = 'Successfully logged out' |
---|
43 | auth() |
---|
44 | } |
---|
45 | |
---|
46 | /** |
---|
47 | * Show the login page. |
---|
48 | */ |
---|
49 | def auth = { |
---|
50 | |
---|
51 | nocache(response) |
---|
52 | |
---|
53 | if (isLoggedIn()) { |
---|
54 | redirect uri: '/' |
---|
55 | return |
---|
56 | } |
---|
57 | |
---|
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 | } |
---|
73 | |
---|
74 | render view: view, model: [postUrl: postUrl] |
---|
75 | } |
---|
76 | |
---|
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 | } |
---|
93 | |
---|
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 | } |
---|
106 | |
---|
107 | /** |
---|
108 | * The Ajax success redirect url. |
---|
109 | */ |
---|
110 | def ajaxSuccess = { |
---|
111 | nocache(response) |
---|
112 | render '{success: true}' |
---|
113 | } |
---|
114 | |
---|
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 | } |
---|
124 | |
---|
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 | } |
---|
132 | |
---|
133 | // Denial page (data|view|json) for Ajax access. |
---|
134 | def deniedAjax = { |
---|
135 | //this is example: |
---|
136 | render "{error: 'access denied'}" |
---|
137 | } |
---|
138 | |
---|
139 | /** |
---|
140 | * login failed |
---|
141 | */ |
---|
142 | def authfail = { |
---|
143 | |
---|
144 | def username = session[AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY] |
---|
145 | def msg = '' |
---|
146 | def exception = session[AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY] |
---|
147 | if (exception) { |
---|
148 | if (exception instanceof DisabledException) { |
---|
149 | msg = "[$username] is disabled." |
---|
150 | } |
---|
151 | else { |
---|
152 | msg = "[$username] wrong username/password." |
---|
153 | } |
---|
154 | } |
---|
155 | |
---|
156 | if (isAjax()) { |
---|
157 | render "{error: '${msg}'}" |
---|
158 | } |
---|
159 | else { |
---|
160 | flash.message = msg |
---|
161 | redirect action: auth, params: params |
---|
162 | } |
---|
163 | } |
---|
164 | |
---|
165 | /** |
---|
166 | * Check if logged in. |
---|
167 | */ |
---|
168 | private boolean isLoggedIn() { |
---|
169 | return authenticateService.isLoggedIn() |
---|
170 | } |
---|
171 | |
---|
172 | private boolean isAjax() { |
---|
173 | return authenticateService.isAjax(request) |
---|
174 | } |
---|
175 | |
---|
176 | /** cache controls */ |
---|
177 | private void nocache(response) { |
---|
178 | response.setHeader('Cache-Control', 'no-cache') // HTTP 1.1 |
---|
179 | response.addDateHeader('Expires', 0) |
---|
180 | response.setDateHeader('max-age', 0) |
---|
181 | response.setIntHeader ('Expires', -1) //prevents caching at the proxy server |
---|
182 | response.addHeader('cache-Control', 'private') //IE5.x only |
---|
183 | } |
---|
184 | } |
---|