]> source.dussan.org Git - archiva.git/blob
9e85ae5539fb0a49c62aa6fde1dfd5b6bc956f7a
[archiva.git] /
1 package org.apache.archiva.redback.integration.util;
2
3 /*
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements.  See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership.  The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License.  You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied.  See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  */
21
22 import javax.annotation.Resource;
23 import javax.servlet.http.Cookie;
24 import javax.servlet.http.HttpServletRequest;
25 import javax.servlet.http.HttpServletResponse;
26
27 import org.apache.archiva.redback.keys.AuthenticationKey;
28 import org.apache.archiva.redback.keys.KeyManager;
29 import org.apache.archiva.redback.keys.KeyManagerException;
30 import org.apache.archiva.redback.keys.KeyNotFoundException;
31 import org.apache.archiva.redback.policy.CookieSettings;
32 import org.apache.archiva.redback.system.SecuritySystem;
33 import org.codehaus.plexus.util.StringUtils;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36 import org.springframework.stereotype.Service;
37
38 /**
39  * AutoLoginCookies
40  *
41  * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
42  * @version $Id$
43  */
44 @Service("autoLoginCookies")
45 public class AutoLoginCookies
46 {
47     
48     private Logger log = LoggerFactory.getLogger( getClass() );
49     
50     @Resource
51     private SecuritySystem securitySystem;
52
53     /**
54      * Cookie key for the Remember Me functionality.
55      */
56     private static final String REMEMBER_ME_KEY = "rbkRememberMe";
57
58     /**
59      * Cookie key for the signon cookie.
60      */
61     private static final String SIGNON_KEY = "rbkSignon";
62
63     public AuthenticationKey getRememberMeKey(HttpServletResponse httpServletResponse, HttpServletRequest httpServletRequest )
64     {
65         if ( !isRememberMeEnabled() )
66         {
67             return null;
68         }
69
70         Cookie rememberMeCookie = getCookie( httpServletRequest, REMEMBER_ME_KEY );
71
72         if ( rememberMeCookie == null )
73         {
74             log.debug( "Remember Me Cookie Not Found: {}", REMEMBER_ME_KEY );
75             return null;
76         }
77
78         // Found user with a remember me key.
79         String providedKey = rememberMeCookie.getValue();
80
81         log.debug( "Found remember me cookie : {}", providedKey );
82
83         CookieSettings settings = securitySystem.getPolicy().getRememberMeCookieSettings();
84         return findAuthKey( REMEMBER_ME_KEY, providedKey, settings.getDomain(), settings.getPath(), httpServletResponse, httpServletRequest );
85     }
86
87     public void setRememberMeCookie( String principal, HttpServletResponse httpServletResponse, HttpServletRequest httpServletRequest )
88     {
89         if ( !isRememberMeEnabled() )
90         {
91             return;
92         }
93
94         try
95         {
96             CookieSettings settings = securitySystem.getPolicy().getRememberMeCookieSettings();
97             int timeout = settings.getCookieTimeout();
98             KeyManager keyManager = securitySystem.getKeyManager();
99             AuthenticationKey authkey = keyManager.createKey( principal, "Remember Me Key", timeout );
100
101             Cookie cookie = createCookie( REMEMBER_ME_KEY, authkey.getKey(), settings.getDomain(), settings.getPath(), httpServletRequest );
102             if ( timeout > 0 )
103             {
104                 cookie.setMaxAge( timeout );
105             }
106             httpServletResponse.addCookie( cookie );
107
108         }
109         catch ( KeyManagerException e )
110         {
111             log.warn( "Unable to set remember me cookie." );
112         }
113     }
114
115     public void removeRememberMeCookie( HttpServletResponse httpServletResponse, HttpServletRequest httpServletRequest )
116     {
117         CookieSettings settings = securitySystem.getPolicy().getRememberMeCookieSettings();
118         removeCookie( httpServletResponse, httpServletRequest, REMEMBER_ME_KEY, settings.getDomain(), settings.getPath() );
119     }
120
121     public AuthenticationKey getSignonKey( HttpServletResponse httpServletResponse, HttpServletRequest httpServletRequest )
122     {
123         Cookie ssoCookie = getCookie( httpServletRequest, SIGNON_KEY );
124
125         if ( ssoCookie == null )
126         {
127             log.debug( "Single Sign On Cookie Not Found: {}", SIGNON_KEY );
128             return null;
129         }
130
131         // Found user with a single sign on key.
132
133         String providedKey = ssoCookie.getValue();
134
135         log.debug( "Found sso cookie : {}", providedKey );
136
137         CookieSettings settings = securitySystem.getPolicy().getSignonCookieSettings();
138         return findAuthKey( SIGNON_KEY, providedKey, settings.getDomain(), settings.getPath(), httpServletResponse, httpServletRequest );
139     }
140
141     public void setSignonCookie( String principal, HttpServletResponse httpServletResponse, HttpServletRequest httpServletRequest )
142     {
143         try
144         {
145             CookieSettings settings = securitySystem.getPolicy().getSignonCookieSettings();
146             int timeout = settings.getCookieTimeout();
147             KeyManager keyManager = securitySystem.getKeyManager();
148             AuthenticationKey authkey = keyManager.createKey( principal, "Signon Session Key", timeout );
149
150             /* The path must remain as "/" in order for SSO to work on installations where the only
151              * all of the servers are installed into the same web container but under different 
152              * web contexts.
153              */
154             Cookie cookie = createCookie( SIGNON_KEY, authkey.getKey(), settings.getDomain(), settings.getPath(), httpServletRequest );
155             if ( timeout > 0 )
156             {
157                 cookie.setMaxAge( timeout );
158             }
159             httpServletResponse.addCookie( cookie );
160
161         }
162         catch ( KeyManagerException e )
163         {
164             log.warn( "Unable to set single sign on cookie." );
165
166         }
167     }
168
169     public void removeSignonCookie( HttpServletResponse httpServletResponse, HttpServletRequest httpServletRequest )
170     {
171         CookieSettings settings = securitySystem.getPolicy().getSignonCookieSettings();
172         removeCookie( httpServletResponse, httpServletRequest, SIGNON_KEY, settings.getDomain(), settings.getPath() );
173     }
174
175     private static String getWebappContext( HttpServletRequest httpRequest )
176     {
177         // Calculate the webapp context.
178         String webappContext = httpRequest.getContextPath();
179
180         if ( StringUtils.isEmpty( webappContext ) )
181         {
182             // Still empty?  means you are a root context.
183             webappContext = "/";
184         }
185
186         return webappContext;
187     }
188
189     public boolean isRememberMeEnabled()
190     {
191         return securitySystem.getPolicy().getRememberMeCookieSettings().isEnabled();
192     }
193
194     private AuthenticationKey findAuthKey( String cookieName, String providedKey, String domain, String path,
195                                            HttpServletResponse httpServletResponse, HttpServletRequest httpServletRequest )
196     {
197         try
198         {
199             AuthenticationKey authkey = securitySystem.getKeyManager().findKey( providedKey );
200
201             log.debug( "Found AuthKey: {}", authkey );
202
203             return authkey;
204         }
205         catch ( KeyNotFoundException e )
206         {
207             log.info( "Invalid AuthenticationKey {} submitted. Invalidating cookie.", providedKey );
208
209             // Invalid Cookie.  Remove it.
210             removeCookie( httpServletResponse, httpServletRequest, cookieName, domain, path );
211         }
212         catch ( KeyManagerException e )
213         {
214             log.error( "KeyManagerException: " + e.getMessage(), e );
215         }
216
217         return null;
218     }
219
220     private static Cookie getCookie( HttpServletRequest request, String name )
221     {
222         Cookie[] cookies = request.getCookies();
223
224         Cookie cookie = null;
225         if ( cookies != null && !StringUtils.isEmpty( name ) )
226         {
227             for ( int i = 0; i < cookies.length && cookie == null; i++ )
228             {
229                 if ( StringUtils.equals( name, cookies[i].getName() ) )
230                 {
231                     cookie = cookies[i];
232                 }
233             }
234         }
235
236         return cookie;
237     }
238
239     private static void removeCookie( HttpServletResponse response, HttpServletRequest httpRequest, String cookieName, String domain, String path )
240     {
241         Cookie cookie = createCookie( cookieName, "", domain, path, httpRequest );
242         cookie.setMaxAge( 0 );
243         response.addCookie( cookie );
244     }
245
246     private static Cookie createCookie( String cookieName, String value, String domain, String path, HttpServletRequest httpRequest )
247     {
248         Cookie cookie = new Cookie( cookieName, value );
249         if ( domain != null )
250         {
251             cookie.setDomain( domain );
252         }
253         if ( path != null )
254         {
255             cookie.setPath( path );
256         }
257         else
258         {
259             // default to the context path, otherwise you get /security and such in some places
260             cookie.setPath( getWebappContext( httpRequest ) );
261         }
262         return cookie;
263     }
264 }