1 package org.codehaus.redback.rest.services.interceptors;
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
23 import org.apache.archiva.redback.users.User;
24 import org.apache.archiva.redback.users.UserManager;
25 import org.apache.cxf.jaxrs.ext.RequestHandler;
26 import org.apache.cxf.jaxrs.model.ClassResourceInfo;
27 import org.apache.cxf.message.Message;
28 import org.apache.archiva.redback.authentication.AuthenticationException;
29 import org.apache.archiva.redback.authentication.AuthenticationResult;
30 import org.apache.archiva.redback.authorization.RedbackAuthorization;
31 import org.codehaus.plexus.redback.policy.AccountLockedException;
32 import org.codehaus.plexus.redback.policy.MustChangePasswordException;
33 import org.codehaus.plexus.redback.system.SecuritySession;
34 import org.apache.archiva.redback.users.UserNotFoundException;
35 import org.codehaus.redback.integration.filter.authentication.HttpAuthenticationException;
36 import org.codehaus.redback.integration.filter.authentication.basic.HttpBasicAuthentication;
37 import org.codehaus.redback.rest.services.RedbackAuthenticationThreadLocal;
38 import org.codehaus.redback.rest.services.RedbackRequestInformation;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41 import org.springframework.stereotype.Service;
43 import javax.inject.Inject;
44 import javax.inject.Named;
45 import javax.servlet.http.HttpServletRequest;
46 import javax.servlet.http.HttpServletResponse;
47 import javax.ws.rs.core.Response;
50 * This interceptor will check if the user is already logged in the session.
51 * If not ask the redback system to authentication trough BASIC http
52 * If the user is logged the AuthenticationResult will in the cxf message with the key AuthenticationResult.class
54 * @author Olivier Lamy
57 @Service( "authenticationInterceptor#rest" )
58 public class AuthenticationInterceptor
59 extends AbstractInterceptor
60 implements RequestHandler
63 @Named( value = "userManager#configurable" )
64 private UserManager userManager;
67 @Named( value = "httpAuthenticator#basic" )
68 private HttpBasicAuthentication httpAuthenticator;
70 private Logger log = LoggerFactory.getLogger( getClass() );
72 public Response handleRequest( Message message, ClassResourceInfo classResourceInfo )
75 RedbackAuthorization redbackAuthorization = getRedbackAuthorization( message );
76 if ( redbackAuthorization == null )
78 log.warn( "http path {} doesn't contain any informations regarding permissions ",
79 message.get( Message.REQUEST_URI ) );
80 // here we failed to authenticate so 403 as there is no detail on karma for this
81 // it must be marked as it's exposed
82 return Response.status( Response.Status.FORBIDDEN ).build();
84 HttpServletRequest request = getHttpServletRequest( message );
85 HttpServletResponse response = getHttpServletResponse( message );
87 if ( redbackAuthorization.noRestriction() )
89 // maybe session exists so put it in threadLocal
90 // some services need the current user if logged
91 SecuritySession securitySession = httpAuthenticator.getSecuritySession( request.getSession( true ) );
93 if ( securitySession != null )
95 RedbackRequestInformation redbackRequestInformation =
96 new RedbackRequestInformation( securitySession.getUser(), request.getRemoteAddr() );
97 RedbackAuthenticationThreadLocal.set( redbackRequestInformation );
101 // maybe there is some authz in the request so try it but not fail so catch Exception !
104 AuthenticationResult authenticationResult =
105 httpAuthenticator.getAuthenticationResult( request, response );
107 if ( ( authenticationResult == null ) || ( !authenticationResult.isAuthenticated() ) )
111 // FIXME this is already called previously but authenticationResult doesn't return that
112 User user = userManager.findUser( (String) authenticationResult.getPrincipal() );
113 RedbackRequestInformation redbackRequestInformation =
114 new RedbackRequestInformation( user, request.getRemoteAddr() );
116 RedbackAuthenticationThreadLocal.set( redbackRequestInformation );
117 message.put( AuthenticationResult.class, authenticationResult );
119 catch ( Exception e )
129 AuthenticationResult authenticationResult = httpAuthenticator.getAuthenticationResult( request, response );
131 if ( ( authenticationResult == null ) || ( !authenticationResult.isAuthenticated() ) )
133 throw new HttpAuthenticationException( "You are not authenticated." );
135 // FIXME this is already called previously but authenticationResult doesn't return that
136 User user = userManager.findUser( (String) authenticationResult.getPrincipal() );
137 RedbackRequestInformation redbackRequestInformation =
138 new RedbackRequestInformation( user, request.getRemoteAddr() );
140 RedbackAuthenticationThreadLocal.set( redbackRequestInformation );
141 message.put( AuthenticationResult.class, authenticationResult );
145 catch ( UserNotFoundException e )
147 log.debug( "UserNotFoundException for path {}", message.get( Message.REQUEST_URI ) );
148 return Response.status( Response.Status.FORBIDDEN ).build();
150 catch ( AccountLockedException e )
152 log.debug( "account locked for path {}", message.get( Message.REQUEST_URI ) );
153 return Response.status( Response.Status.FORBIDDEN ).build();
156 catch ( MustChangePasswordException e )
158 log.debug( "must change password for path {}", message.get( Message.REQUEST_URI ) );
159 return Response.status( Response.Status.FORBIDDEN ).build();
162 catch ( AuthenticationException e )
164 log.debug( "failed to authenticate for path {}", message.get( Message.REQUEST_URI ) );
165 return Response.status( Response.Status.FORBIDDEN ).build();