|
import org.apache.cxf.binding.soap.interceptor.SoapHeaderInterceptor; |
|
import org.apache.cxf.configuration.security.AuthorizationPolicy; |
|
import org.apache.cxf.endpoint.Endpoint; |
|
import org.apache.cxf.interceptor.Fault; |
|
import org.apache.cxf.message.Exchange; |
|
import org.apache.cxf.message.Message; |
|
import org.apache.cxf.transport.Conduit; |
|
import org.apache.cxf.ws.addressing.EndpointReferenceType; |
|
import org.slf4j.Logger; |
|
import org.slf4j.LoggerFactory; |
|
|
|
import java.io.IOException; |
|
import java.io.OutputStream; |
|
import java.net.HttpURLConnection; |
|
import java.util.Arrays; |
|
import java.util.Map; |
|
|
|
public class BasicAuthAuthorizationInterceptor extends SoapHeaderInterceptor { |
|
|
|
protected static final Logger log = LoggerFactory.getLogger(BasicAuthAuthorizationInterceptor.class); |
|
|
|
@Override |
|
public void handleMessage(Message message) throws Fault { |
|
SecurityContextHolder.clear(); |
|
// This is set by CXF |
|
AuthorizationPolicy policy = message.get(AuthorizationPolicy.class); |
|
// If the policy is not set, the user did not specify |
|
// credentials. A 401 is sent to the client to indicate |
|
// that authentication is required |
|
if (policy == null) { |
|
sendErrorResponse(message, HttpURLConnection.HTTP_UNAUTHORIZED); |
|
return; |
|
} |
|
// Verify the password |
|
String realPassword = getAcualPassword(policy.getUserName()); |
|
if (realPassword == null || !realPassword.equals(policy.getPassword())) { |
|
log.warn("Invalid username or password for user: " + policy.getUserName()); |
|
sendErrorResponse(message, HttpURLConnection.HTTP_FORBIDDEN); |
|
} |
|
SecurityContextHolder.setPrincipal(policy.getUserName()); |
|
} |
|
|
|
private String getAcualPassword(String userName) { |
|
return "password"; |
|
} |
|
|
|
private void sendErrorResponse(Message message, int responseCode) { |
|
Message outMessage = getOutMessage(message); |
|
outMessage.put(Message.RESPONSE_CODE, responseCode); |
|
// Set the response headers |
|
Map responseHeaders = (Map) message.get(Message.PROTOCOL_HEADERS); |
|
if (responseHeaders != null) { |
|
responseHeaders.put("WWW-Authenticate", Arrays.asList(new String[]{"Basic realm=realm"})); |
|
responseHeaders.put("Content-length", Arrays.asList(new String[]{"0"})); |
|
} |
|
message.getInterceptorChain().abort(); |
|
try { |
|
getConduit(message).prepare(outMessage); |
|
close(outMessage); |
|
} catch (IOException e) { |
|
log.warn(e.getMessage(), e); |
|
} |
|
} |
|
|
|
private Message getOutMessage(Message inMessage) { |
|
Exchange exchange = inMessage.getExchange(); |
|
Message outMessage = exchange.getOutMessage(); |
|
if (outMessage == null) { |
|
Endpoint endpoint = exchange.get(Endpoint.class); |
|
outMessage = endpoint.getBinding().createMessage(); |
|
exchange.setOutMessage(outMessage); |
|
} |
|
outMessage.putAll(inMessage); |
|
return outMessage; |
|
} |
|
|
|
private Conduit getConduit(Message inMessage) throws IOException { |
|
Exchange exchange = inMessage.getExchange(); |
|
EndpointReferenceType target = exchange.get(EndpointReferenceType.class); |
|
Conduit conduit = exchange.getDestination().getBackChannel(inMessage, null, target); |
|
exchange.setConduit(conduit); |
|
return conduit; |
|
} |
|
|
|
private void close(Message outMessage) throws IOException { |
|
OutputStream os = outMessage.getContent(OutputStream.class); |
|
os.flush(); |
|
os.close(); |
|
} |
|
} |
|
|