This project has retired. For details please refer to its Attic page.
DefaultAuthenticationManager xref
View Javadoc

1   package org.apache.archiva.redback.authentication;
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 org.apache.archiva.redback.policy.AccountLockedException;
23  import org.apache.archiva.redback.policy.MustChangePasswordException;
24  import org.apache.archiva.redback.users.User;
25  import org.apache.archiva.redback.users.UserManager;
26  import org.apache.archiva.redback.users.UserManagerException;
27  import org.slf4j.Logger;
28  import org.slf4j.LoggerFactory;
29  import org.springframework.context.ApplicationContext;
30  import org.springframework.stereotype.Service;
31  
32  import javax.annotation.PostConstruct;
33  import javax.inject.Inject;
34  import javax.inject.Named;
35  import java.util.ArrayList;
36  import java.util.HashMap;
37  import java.util.List;
38  import java.util.Map;
39  
40  
41  /**
42   * DefaultAuthenticationManager: the goal of the authentication manager is to act as a conduit for
43   * authentication requests into different authentication schemes
44   * <p/>
45   * For example, the default implementation can be configured with any number of authenticators and will
46   * sequentially try them for an authenticated result.  This allows you to have the standard user/pass
47   * auth procedure followed by authentication based on a known key for 'remember me' type functionality.
48   *
49   * @author: Jesse McConnell <jesse@codehaus.org>
50   */
51  @Service("authenticationManager")
52  public class DefaultAuthenticationManager
53      implements AuthenticationManager
54  {
55  
56      private Logger log = LoggerFactory.getLogger( getClass() );
57  
58      private List<Authenticator> authenticators;
59  
60      @Inject
61      private ApplicationContext applicationContext;
62  
63      @Inject
64      @Named( value = "userManager#default" )
65      private UserManager userManager;
66  
67      @SuppressWarnings( "unchecked" )
68      @PostConstruct
69      public void initialize()
70      {
71          this.authenticators =
72              new ArrayList<Authenticator>( applicationContext.getBeansOfType( Authenticator.class ).values() );
73      }
74  
75  
76      public String getId()
77      {
78          return "Default Authentication Manager - " + this.getClass().getName() + " : managed authenticators - " +
79              knownAuthenticators();
80      }
81  
82      public AuthenticationResult authenticate( AuthenticationDataSource source )
83          throws AccountLockedException, AuthenticationException, MustChangePasswordException
84      {
85          if ( authenticators == null || authenticators.size() == 0 )
86          {
87              return ( new AuthenticationResult( false, null, new AuthenticationException(
88                  "no valid authenticators, can't authenticate" ) ) );
89          }
90  
91          // put AuthenticationResult exceptions in a map
92          List<AuthenticationFailureCause> authnResultErrors = new ArrayList<AuthenticationFailureCause>();
93          for ( Authenticator authenticator : authenticators )
94          {
95              if ( authenticator.supportsDataSource( source ) )
96              {
97                  AuthenticationResult authResult = authenticator.authenticate( source );
98                  List<AuthenticationFailureCause> authenticationFailureCauses =
99                      authResult.getAuthenticationFailureCauses();
100 
101                 if ( authResult.isAuthenticated() )
102                 {
103                     //olamy: as we can chain various user managers with Archiva
104                     // user manager authenticator can lock accounts in the following case :
105                     // 2 user managers: ldap and jdo.
106                     // ldap correctly find the user but cannot compare hashed password
107                     // jdo reject password so increase loginAttemptCount
108                     // now ldap bind authenticator work but loginAttemptCount has been increased.
109                     // so we restore here loginAttemptCount to 0 if in authenticationFailureCauses
110 
111                     for ( AuthenticationFailureCause authenticationFailureCause : authenticationFailureCauses )
112                     {
113                         User user = authenticationFailureCause.getUser();
114                         if ( user != null )
115                         {
116                             if ( user.getCountFailedLoginAttempts() > 0 )
117                             {
118                                 user.setCountFailedLoginAttempts( 0 );
119                                 if ( !userManager.isReadOnly() )
120                                 {
121                                     try
122                                     {
123                                         userManager.updateUser( user );
124                                     }
125                                     catch ( UserManagerException e )
126                                     {
127                                         log.debug( e.getMessage(), e );
128                                         log.warn( "skip error updating user: {}", e.getMessage() );
129                                     }
130                                 }
131                             }
132                         }
133                     }
134                     return authResult;
135                 }
136 
137                 if ( authenticationFailureCauses != null )
138                 {
139                     authnResultErrors.addAll( authenticationFailureCauses );
140                 }
141                 else
142                 {
143                     if ( authResult.getException() != null )
144                     {
145                         authnResultErrors.add(
146                             new AuthenticationFailureCause( AuthenticationConstants.AUTHN_RUNTIME_EXCEPTION,
147                                                             authResult.getException().getMessage() ) );
148                     }
149                 }
150 
151 
152             }
153         }
154 
155         return ( new AuthenticationResult( false, null, new AuthenticationException(
156             "authentication failed on authenticators: " + knownAuthenticators() ), authnResultErrors ) );
157     }
158 
159     public List<Authenticator> getAuthenticators()
160     {
161         return authenticators;
162     }
163 
164     private String knownAuthenticators()
165     {
166         StringBuilder strbuf = new StringBuilder();
167 
168         for ( Authenticator authenticator : authenticators )
169         {
170             strbuf.append( '(' ).append( authenticator.getId() ).append( ") " );
171         }
172 
173         return strbuf.toString();
174     }
175 }