2013-06-13 2 views
3

Я создал веб-сервис. Он работает нормально. Теперь я пытаюсь реализовать аутентификацию. Для этого я использую перехватчики CXF. По какой-то причине перехватчики не срабатывают. Что мне не хватает? Это мой первый веб-сервис.CXF InInterceptor не работает

import javax.annotation.Resource; 
import javax.inject.Inject; 
import javax.jws.WebMethod; 
import javax.jws.WebParam; 
import javax.jws.WebService; 
import javax.xml.ws.WebServiceContext; 

import org.apache.cxf.interceptor.InInterceptors; 

@WebService 
@InInterceptors(interceptors = "ws.BasicAuthAuthorizationInterceptor") 
public class Service { 

    @WebMethod 
    public void test(@WebParam(name = "value") Integer value) throws Exception { 
     System.out.println("Value = " + value); 
    }  
} 

-

package ws; 

import java.io.IOException; 
import java.io.OutputStream; 
import java.net.HttpURLConnection; 
import java.util.Arrays; 
import java.util.List; 
import java.util.Map; 
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; 

public class BasicAuthAuthorizationInterceptor extends SoapHeaderInterceptor { 

@Override 
public void handleMessage(Message message) throws Fault { 
    System.out.println("**** GET THIS LINE TO CONSOLE TO SEE IF INTERCEPTOR IS FIRING!!!"); 
    AuthorizationPolicy policy = message.get(AuthorizationPolicy.class); 

    // If the policy is not set, the user did not specify credentials. 
    // 401 is sent to the client to indicate that authentication is required. 
    if (policy == null) { 
     sendErrorResponse(message, HttpURLConnection.HTTP_UNAUTHORIZED); 
     return; 
    } 

    String username = policy.getUserName(); 
    String password = policy.getPassword(); 

    // CHECK USERNAME AND PASSWORD 
    if (!checkLogin(username, password)) { 
     System.out.println("handleMessage: Invalid username or password for user: " 
       + policy.getUserName()); 
     sendErrorResponse(message, HttpURLConnection.HTTP_FORBIDDEN); 
    } 
} 

private boolean checkLogin(String username, String password) { 
    if (username.equals("admin") && password.equals("admin")) { 
     return true; 
    } 
    return false; 
} 

private void sendErrorResponse(Message message, int responseCode) { 
    Message outMessage = getOutMessage(message); 
    outMessage.put(Message.RESPONSE_CODE, responseCode); 

    // Set the response headers 
    @SuppressWarnings("unchecked") 
    Map<String, List<String>> responseHeaders = (Map<String, List<String>>) 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) { 
     e.printStackTrace(); 
    } 
} 

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(); 
} 

} 

теперь я борюсь с этим в течение нескольких дней. Не знаю, что делать с Google. Помощь приветствуется.

ответ

7

Я нашел решение. Я пропускал следующую строку в файле MANIFEST.MF в военном проекте:

Зависимости: org.apache.cxf

Maven не includint этой линии по себе, так что я должен был найти обходной путь. Я нашел об этом here. В нем говорится: при использовании аннотаций на конечных точках/обработчиках, таких как Apache CXF (@InInterceptor, @GZIP, ...) не забудьте добавить правильную зависимость модуля в манифесте. В противном случае ваши аннотации не подбираются и добавляются в индекс аннотации JBoss Application Server 7, в результате чего они полностью и молча игнорируются.

This, где я узнал, как изменить файл MANIFEST.MF.

Одним словом, я добавил файл манифеста в свой проект и ссылался на него в pom.xml. Надеюсь, это поможет кому-то.

+1

+1 для ясного объяснения, в чем проблема и обращение с maven как «человек»: «Maven не включал эту линию сам по себе» :) – Sikorski

2

Ответ, предоставленный Феликс, является точным. Мне удалось решить проблему, используя его инструкции. Для завершения здесь находится конфигурация maven, которая позволяет использовать ваш собственный файл MANIFEST.MF, расположенный в папке META-INF.

 <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-war-plugin</artifactId> 
      <configuration> 
       <archive> 
        <manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile> 
       </archive> 
      </configuration> 
     </plugin> 

и здесь содержится соответствующее содержание содержимого файла MANIFEST.MF, который я использовал.

Manifest-Version: 1.0 
Description: yourdescription 
Dependencies: org.apache.ws.security,org.apache.cxf 
Смежные вопросы