1 package org.apache.archiva.redback.jsecurity;
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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
22 import org.apache.archiva.redback.policy.AccountLockedException;
23 import org.apache.archiva.redback.policy.UserSecurityPolicy;
24 import org.apache.archiva.redback.rbac.Permission;
25 import org.apache.archiva.redback.rbac.RBACManager;
26 import org.apache.archiva.redback.rbac.RbacManagerException;
27 import org.apache.archiva.redback.rbac.UserAssignment;
28 import org.apache.archiva.redback.users.User;
29 import org.apache.archiva.redback.users.UserManager;
30 import org.apache.archiva.redback.users.UserNotFoundException;
31 import org.jsecurity.authc.AuthenticationException;
32 import org.jsecurity.authc.AuthenticationInfo;
33 import org.jsecurity.authc.AuthenticationToken;
34 import org.jsecurity.authc.SimpleAuthenticationInfo;
35 import org.jsecurity.authc.UsernamePasswordToken;
36 import org.jsecurity.authc.credential.CredentialsMatcher;
37 import org.jsecurity.authz.AuthorizationInfo;
38 import org.jsecurity.authz.SimpleAuthorizationInfo;
39 import org.jsecurity.realm.AuthorizingRealm;
40 import org.jsecurity.subject.PrincipalCollection;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
44 import java.util.HashSet;
45 import java.util.Iterator;
48 public class RedbackRealm
49 extends AuthorizingRealm
51 private Logger log = LoggerFactory.getLogger( RedbackRealm.class );
53 private final UserManager userManager;
55 private final RBACManager rbacManager;
57 private final UserSecurityPolicy securityPolicy;
59 public RedbackRealm( UserManager userManager, RBACManager rbacManager, UserSecurityPolicy securityPolicy )
61 this.userManager = userManager;
62 this.rbacManager = rbacManager;
63 this.securityPolicy = securityPolicy;
67 protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals )
69 final String username = (String) principals.fromRealm( getName() ).iterator().next();
73 final UserAssignment assignment = rbacManager.getUserAssignment( username );
74 final Set<String> roleNames = new HashSet<String>( assignment.getRoleNames() );
75 final Set<String> permissions = new HashSet<String>();
77 for ( Iterator<Permission> it = rbacManager.getAssignedPermissions( username ).iterator(); it.hasNext(); )
79 Permission permission = it.next();
80 permissions.add( permission.getName() );
83 SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo( roleNames );
84 authorizationInfo.setStringPermissions( permissions );
86 return authorizationInfo;
88 catch ( RbacManagerException e )
90 log.error( "Could not authenticate against data source", e );
97 protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token )
98 throws AuthenticationException
102 throw new AuthenticationException( "AuthenticationToken cannot be null" );
105 final UsernamePasswordToken passwordToken = (UsernamePasswordToken) token;
110 user = userManager.findUser( passwordToken.getUsername() );
112 catch ( UserNotFoundException e )
114 log.error( "Could not find user " + passwordToken.getUsername() );
122 if ( user.isLocked() && !user.isPasswordChangeRequired() )
124 throw new PrincipalLockedException( "User " + user.getPrincipal() + " is locked." );
127 if ( user.isPasswordChangeRequired() )
129 throw new PrincipalPasswordChangeRequiredException(
130 "Password change is required for user " + user.getPrincipal() );
133 return new RedbackAuthenticationInfo( user, getName() );
137 public CredentialsMatcher getCredentialsMatcher()
139 return new CredentialsMatcher()
141 public boolean doCredentialsMatch( AuthenticationToken token, AuthenticationInfo info )
143 final String credentials = new String( (char[]) token.getCredentials() );
144 final boolean match = securityPolicy.getPasswordEncoder().encodePassword( credentials ).equals(
145 (String) info.getCredentials() );
148 User user = ( (RedbackAuthenticationInfo) info ).getUser();
151 securityPolicy.extensionExcessiveLoginAttempts( user );
153 catch ( AccountLockedException e )
155 log.info( "User{} has been locked", user.getUsername(), e );
161 userManager.updateUser( user );
163 catch ( UserNotFoundException e )
165 log.error( "The user to be updated could not be found", e );
174 final class RedbackAuthenticationInfo
175 extends SimpleAuthenticationInfo
177 private final User user;
179 public RedbackAuthenticationInfo( User user, String realmName )
181 super( user.getPrincipal(), user.getEncodedPassword(), realmName );
185 public User getUser()