Базовая аутентификация клиента веб-службы Java
Я создал веб-службу JAX-WS поверх Glassfish, для которой требуется базовая HTTP-аутентификация.
Теперь я хочу создать автономный клиент Java-приложения для этой веб-службы, но не знаю, как передать имя пользователя и пароль.
Он работает с обозревателем Eclipse Web Service, и, изучив проводку, я обнаружил следующее:
POST /SnaProvisioning/SnaProvisioningV1_0 HTTP/1.1
Host: localhost:8080
Content-Type: text/xml; charset=utf-8
Content-Length: 311
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: IBM Web Services Explorer
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: ""
Authorization: Basic Z2VybWFuOmdlcm1hbg==
Connection: close
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://ngin.ericsson.com/sna/types/v1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<q0:listServiceScripts/>
</soapenv:Body>
</soapenv:Envelope>
Как передать имя пользователя и пароль в этом заголовке "Авторизация", используя код Java? Это хешируется или что-то в этом роде? Какой алгоритм?
Без обеспечения безопасности у меня есть работающий автономный клиент Java:
SnaProvisioning myPort = new SnaProvisioning_Service().getSnaProvisioningV10Port();
myPort.listServiceScripts();
Ответы
Ответ 1
Оказалось, что существует простой, стандартный способ достичь того, что я хотел:
import java.net.Authenticator;
import java.net.PasswordAuthentication;
Authenticator myAuth = new Authenticator()
{
@Override
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication("german", "german".toCharArray());
}
};
Authenticator.setDefault(myAuth);
Никаких пользовательских классов "солнца" или внешних зависимостей, и ничего не закодировать вручную.
Я знаю, что безопасность BASIC не безопасна, но мы также используем HTTPS.
Ответ 2
Способ JAX-WS для базовой аутентификации
Service s = new Service();
Port port = s.getPort();
BindingProvider prov = (BindingProvider)port;
prov.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "myusername");
prov.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "mypassword");
port.call();
Ответ 3
для клиента Axis2
это может быть полезно
...
serviceStub = new TestBeanServiceStub("<WEB SERVICE URL>"); // Set your value
HttpTransportProperties.Authenticator basicAuthenticator = new HttpTransportProperties.Authenticator();
List<String> authSchemes = new ArrayList<String>();
authSchemes.add(Authenticator.BASIC);
basicAuthenticator.setAuthSchemes(authSchemes);
basicAuthenticator.setUsername("<UserName>"); // Set your value
basicAuthenticator.setPassword("<Password>"); // Set your value
basicAuthenticator.setPreemptiveAuthentication(true);
serviceStub._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.AUTHENTICATE, basicAuthenticator);
serviceStub._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, "false");
...
Ответ 4
В другом контексте, посвященном базовой аутентификации, он состоит из заголовка, содержащего пару ключ/значение:
Авторизация: Basic Z2VybWFuOmdlcm1hbg ==
где " Авторизация" - это заголовок,
и значение заголовков имеет строку ( " Basic" плюс плюс пустое пространство), объединенное с " Z2VybWFuOmdlcm1hbg ==", которые являются пользователем и пароль в базе 64 с двойной точкой
String name = "username";
String password = "secret";
String authString = name + ":" + password;
String authStringEnc = new BASE64Encoder().encode(authString.getBytes());
...
objectXXX.header("Authorization", "Basic " + authStringEnc);
Ответ 5
Если вы используете реализацию JAX-WS для своего клиента, например Metro Web Services, следующий код показывает, как передавать имя пользователя и пароль в заголовках HTTP:
MyService port = new MyService();
MyServiceWS service = port.getMyServicePort();
Map<String, List<String>> credentials = new HashMap<String,List<String>>();
credentials.put("username", Collections.singletonList("username"));
credentials.put("password", Collections.singletonList("password"));
((BindingProvider)service).getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS, credentials);
Затем последующие вызовы службы будут аутентифицированы. Помните, что пароль кодируется только с помощью Base64, поэтому я рекомендую вам использовать другой дополнительный механизм, такой как клиентские сертификаты, для повышения безопасности.
Ответ 6
Это сработало для меня:
BindingProvider bp = (BindingProvider) port;
Map<String, Object> map = bp.getRequestContext();
map.put(BindingProvider.USERNAME_PROPERTY, "aspbbo");
map.put(BindingProvider.PASSWORD_PROPERTY, "9FFFN6P");
Ответ 7
Чтобы упростить вашу жизнь, вам может потребоваться использовать инфраструктуру JAX-WS, такую как Apache CXF или Apache Axis2.
Вот ссылка, которая описывает, как настроить WS-Security для Apache CXF → http://cxf.apache.org/docs/ws-security.html
ИЗМЕНИТЬ
Кстати, в поле Authorization
просто используется простая кодировка Base64.
В соответствии с этим (http://www.motobit.com/util/base64-decoder-encoder.asp), декодированное значение german:german
.
Ответ 8
Если вы используете JAX-WS, у меня работает следующее:
//Get Web service Port
WSTestService wsService = new WSTestService();
WSTest wsPort = wsService.getWSTestPort();
// Add username and password for Basic Authentication
Map<String, Object> reqContext = ((BindingProvider)
wsPort).getRequestContext();
reqContext.put(BindingProvider.USERNAME_PROPERTY, "username");
reqContext.put(BindingProvider.PASSWORD_PROPERTY, "password");