Java Soap请求未经授权
我需要编写JavaSOAP客户机代码,以便在客户请求时使用web服务。当我调用java客户机代码时,我得到了401个未经授权的响应代码。然而,当我从邮递员那里打来电话时,一切都很好。下面是Java客户机代码Java Soap请求未经授权,java,web-services,soap,wsdl,wsdl2java,Java,Web Services,Soap,Wsdl,Wsdl2java,我需要编写JavaSOAP客户机代码,以便在客户请求时使用web服务。当我调用java客户机代码时,我得到了401个未经授权的响应代码。然而,当我从邮递员那里打来电话时,一切都很好。下面是Java客户机代码 import org.apache.commons.codec.digest.DigestUtils; import org.apache.http.auth.AuthenticationException; import org.apache.http.client.AuthCache;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.auth.AuthenticationException;
import org.apache.http.client.AuthCache;
import org.apache.http.impl.client.BasicAuthCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.*;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringReader;
import java.io.StringWriter;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.text.SimpleDateFormat;
import java.util.*;
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
Logger log = LoggerFactory.getLogger(DemoApplication.class);
static {
//disableSslVerification();
}
public static void disableSslVerification() {
try
{
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
}
};
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
private final String REALM = "Restricted";
private final String SEPARATOR = ", ";
private final String QUOTE = "\"";
private final String NONCE = Long.toString(new Random().nextLong(), 36);
private String setAuthorizationHeader(String method, String username, String password,String nonce) throws AuthenticationException {
DigestScheme digestScheme = new DigestScheme();
Map<String,String> params = new HashMap<>();
String digest4 = DigestUtils.sha1Hex(username + ":" + REALM + ":" + password +new Date().getTime());
String digest2 = DigestUtils.md5Hex(method + ":" + "/");
params.put("uri","/soap/sp");
params.put("realm","Restricted");
params.put("nonce",nonce);
params.put("nc","01");
params.put("cnonce","0a458m12");
params.put("qop","auth");
params.put("methodname","POST");
params.put("algorithm","MD5");
String md5Hex = DigestScheme.createDigest("arbor","arbortt",params);
String header = DigestScheme.createDigestHeader("arbor",params,md5Hex);
String value = "Digest " + header;
return value;
}
public String calculateNonce() {
Date d = new Date();
SimpleDateFormat f = new SimpleDateFormat("yyyy:MM:dd:hh:mm:ss");
String fmtDate = f.format(d);
Random rand = new Random(100000);
Integer randomInt = rand.nextInt();
return DigestUtils.sha1Hex(fmtDate + randomInt.toString());
}
@Override
public void run(String... args) throws Exception {
System.setProperty("javax.net.ssl.trustStore","C:\\Users\\devuser\\Desktop\\keystorefile");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
disableSslVerification();
RestTemplate restTemplate = new RestTemplate();
String request = "<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:urn=\"urn:com.example.demo.PeakflowSP\">\n" +
" <soapenv:Header/>\n" +
" <soapenv:Body>\n" +
" <urn:getDosAlertSummaries soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n" +
" <filter xsi:type=\"xsd:string\"></filter>\n" +
" <count xsi:type=\"xsd:unsignedInt\"></count>\n" +
" </urn:getDosAlertSummaries>\n" +
" </soapenv:Body>\n" +
"</soapenv:Envelope>";
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_XML));
headers.setContentType(MediaType.APPLICATION_XML);
String nonce = calculateNonce();
headers.add("ETag",nonce);
headers.add("Authorization",setAuthorizationHeader("getDosAlertSummaries","arbor","arbortt",nonce));
HttpEntity<String> entity = new HttpEntity<>(request, headers);
ResponseEntity<String> response = restTemplate.postForEntity("https://10.34.34.71/soap/sp", entity, String.class);
String str = response.getBody();
str = str.replace("xsi:type=\"ns1:DosAlertSummaryArray\"","");
str = str.replace("xsi:type=\"xsd:unsignedInt\"","");
str = str.replace("xsi:type=\"xsd:string\"","");
str = str.replace("xsi:type=\"xsd:boolean\"","");
str = str.replace("xsi:type=\"ns1:DosAlertSummary\"","");
str = str.replace("xsi:type=\"ns1:AlertDirection\"","");
str = str.replace("xsi:type=\"xsd:float\"","");
str = str.replace("xsi:type=\"xsd:dateTime\"","");
str = str.replace("xsi:type=\"ns1:AlertResource\"","");
str = str.replace("xsi:type=\"ns1:AlertManagedObject\"","");
str = str.replace("xsi:type=\"ns1:AlertImportance\"","");
str = str.replace("xsi:type=\"ns1:Annotation\"","");
str = str.replace("xsi:type=\"ns1:unitType\"","");
log.info(response.toString());
XMLInputFactory xif = XMLInputFactory.newFactory();
XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(str));
xsr.nextTag();
xsr.nextTag();
xsr.nextTag();
xsr.nextTag();
Transformer transformer = TransformerFactory.newInstance().newTransformer();
StringWriter stringWriter = new StringWriter();
transformer.transform(new StAXSource(xsr), new StreamResult(stringWriter));
StringReader sr = new StringReader(stringWriter.toString());
JAXBContext jaxbContext = JAXBContext.newInstance(DosAlertSummaries.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
DosAlertSummaries loginResult = (DosAlertSummaries) unmarshaller.unmarshal(sr);
}
邮递员请求日志:
Digest username="arbor", realm="Restricted",
nonce="Nf7oZOFzBQA=04e0c7c96bad6b7d2eabe2ec03831f55c13cde0d",
uri="/soap/sp", algorithm="MD5", qop=auth, nc=01, cnonce="0a458m12",
response="480da02481f50f76a7fbc82a63869e2e"
从邮递员处请求xml:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:getDosAlertSummaries xmlns:ns1="urn:com.example.demo.PeakflowSP"
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<filter xsi:type="xsd:string" />
<count xsi:type="xsd:unsignedInt">100</count>
</ns1:getDosAlertSummaries>
</soapenv:Body>
</soapenv:Envelope>
100
当我取postman创建的nonce值而不是在代码中计算时,我得到200。谁能告诉我哪里做错了?问题可以是nonce值。如果是,如何正确计算nonce值
谢谢您可以记录您的请求吗?事实上,你从你的程序中提出的请求和你从邮递员那里提出的请求是不同的。我会确保您的所有头都是相同的。当请求没有设置用户代理时,某些服务返回401s。@SamOrozco这是我的请求日志,来自程序:Digest username=“arbor”,realm=“Restricted”,nonce=“d90b71aa44b311113dd392e64e6d9347444d3b40”,uri=“/soap/sp”,qop=“auth”,algorithm=“MD5”,nc=01,cnence=“0a458m12”,response=“297349367d0faa283a6649a004e104d1”邮差请求日志:摘要用户名=“arbor”,realm=“Restricted”,nonce=“Nf7oZOFzBQA=04E0C7C96BAD6B7D2EABEC0381F55C13CDE0D”,uri=“/soap/sp”,algorithm=“MD5”,qop=auth,nc=01,cnonce=“0a458m12”,response=“480da02481f50f76a7fbc82a63869e2e”@MCO我设置了用户代理,我没有工作。
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:getDosAlertSummaries xmlns:ns1="urn:com.example.demo.PeakflowSP"
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<filter xsi:type="xsd:string" />
<count xsi:type="xsd:unsignedInt">100</count>
</ns1:getDosAlertSummaries>
</soapenv:Body>
</soapenv:Envelope>