I have built Spring WS application (based on Spring WS 2.2.3) that exposes a small web service with couple of Operations. Each Operation receives input parameters to search a backend database and return response. Some of the parameters are mandatory (e.g. Street Name) and the Client have requested that if a request to the service is missing some of these mandatory parameters (e.g. empty Street Name) then my service should return proper SOAP Fault with HTTP status of 400.
My exception handling is working fine and I am able to return the correct SOAP Fault to the client if some a required parameter was missing form the request message and Spring WS takes care of the rest by wrapping a SOAP Fault and sends it back to the client with status code of 500 like the following:
HTTP/1.1 500 Internal Server Error
Server: Apache-Coyote/1.1
Accept: text/xml, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
SOAPAction: ""
Content-Type: text/xml;charset=utf-8
Content-Length: 503
Date: Thu, 10 Dec 2015 22:28:02 GMT
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring xml:lang="en">Street Name is required</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Which is good except that I really want the HTTP status code to be '400 Bad Request' instead of the '500 Internal Server Error' I can't figure out how to change the status code from 500 to 400 and get similar response like the following:
HTTP/1.1 400 Bad Request
Server: Apache-Coyote/1.1
Accept: text/xml, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
SOAPAction: ""
Content-Type: text/xml;charset=utf-8
Content-Length: 503
Date: Thu, 10 Dec 2015 22:28:02 GMT
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring xml:lang="en">Street Name is required</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Any ideas?
Related
How to add custom metrics to /info endpoint in Spring Actuator 2.7.0?
Currently have the following related to actuator.
I have verified that info.app.version can retrieve the proper value from pom.xml using #Value.
pom.xml
<version>0.0.1-SNAPSHOT</version>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.7.0</version>
</dependency>
application.properties
info.app.version=#project.version#
management.endpoint.info.enabled=true
management.endpoints.web.exposure.include=info,health
But despite this I am only getting an empty response on /info.
Response header:
< HTTP/1.1 200
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Type: application/vnd.spring-boot.actuator.v3+json
< Transfer-Encoding: chunked
< Date: Wed, 15 Jun 2022 04:12:47 GMT
* Received 7 B chunk
* Received 5 B chunk
* Connection #26 to host localhost left intact
Response body :
{}
My understanding is any property under info is included in /info endpoint. Or does this not work on actuator v2+ ?
Source
From the Spring-Boot 2.6 release notes https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.6-Release-Notes#actuator-env-infocontributor-disabled-by-default
You need to enable the info env property:
management.info.env.enabled=true
Latest spring boot requires two things to be set up:
1- exposing the endpoint in application.properties file:
management.endpoints.web.exposure.include=info, health
You can use a wildcard and expose all endpoints if you want
management.endpoints.web.exposure.include=*
2- enabling info.env in application.properties:
management.info.env.enabled=true
When i perform a request using HTTP POST method from Angular, response comes without set-cookie header, contrary when I perform a request using HTTP GET method response comes with set-cookie Header.
I know that when POST method is used a preflight OPTIONS request is automatically issued by a browser. I am looking for advice what can i make so after POST method request client get set-cookie header as it already works with GET method?
My Angular request:
this.http.post<UserDto>("//localhost:8080/users", this.user, {withCredentials: true}).subscribe( user => {
alert("User created successfully.");
});;
Those are response headers i get:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Methods: POST,PUT,DELETE,GET,OPTIONS
Access-Control-Allow-Origin: http://localhost:4200
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 0
Date: Sun, 05 May 2019 09:22:55 GMT
Expires: 0
Pragma: no-cache
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
And my request headers:
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: pl-PL,pl;q=0.9,en-US;q=0.8,en;q=0.7
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: POST
Connection: keep-alive
Host: localhost:8080
Origin: http://localhost:4200
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36
My Spring Security configuration:
#Configuration
#EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.
cors().and().
csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and().addFilterBefore(
new StatelessCSRFFilter(), CsrfFilter.class);
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(ImmutableList.of("http://localhost:4200"));
configuration.setAllowedMethods(Arrays.asList("POST","PUT","DELETE","GET","OPTIONS"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
I have found such an advice:
" I got it to work by adding a response filter for the pre-flight OPTIONS request that works without credentials.
<security-constraint>
<display-name>No check for options</display-name>
<web-resource-collection>
<web-resource-name>All Access</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>OPTIONS</http-method>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
I am not sure how to implement that solution is spring.
The CORS configuration has been set up correctly on the SpringFramework backend, as the methods succeed as expected, and Angular does set the cookies for GET requests. It is only POST operations that do not succeed if not preceded by HTTP.GET request.
I'm using retrofit to communicate with my restful web service. The GET requests are working okay, the problem is when I try to make a POST request.
In my web service I have this method:
#POST
#Path("/byPeriodo")
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public List<ItemProdutividade> getProdutividadeByPeriodo(#FormParam("dataInicial")
Date dataInicial, #FormParam("dataFinal") Date dataFinal,
#FormParam("cpf") long cpf){
return service.getProdutividadeByPeriodo(DateUtils.toLocalDate(dataInicial),
DateUtils.toLocalDate(dataFinal), cpf);
}
And in Android side I have this:
#FormUrlEncoded
#POST("produtividade/byPeriodo/")
Call<List<ItemProdutividade>> getProdutividadeByPeriodo(#Field("dataInicial") Date dataInicial,
#Field("dataFinal") Date dataFinal,
#Field("cpf") long cpf);
When I execute I get the following error:
HTTP STATUS 400 - BAD REQUEST -The request sent by the client was
syntactically incorrect.
Someone knows what I have to do?
EDIT:
Using the retrofit log, this is the output:
12-16 20:06:33.521 7333-8993/br.com.empresa.oprojeto D/OkHttp: --> POST /oprojeto.webservice/rest/produtividade/byPeriodo/ HTTP/1.1
12-16 20:06:33.521 7333-8993/br.com.empresa.oprojeto D/OkHttp: dataInicial=Tue%20Dec%2016%2020%3A06%3A33%20BRST%202014&dataFinal=Wed%20Dec%2016%2020%3A06%3A33%20BRST%202015&cpf=12345678987
12-16 20:06:33.521 7333-8993/br.com.empresa.oprojeto D/OkHttp: --> END POST (125-byte body)
12-16 20:06:33.581 7333-8993/br.com.empresa.oprojeto D/OkHttp: <-- HTTP/1.1 400 Bad Request (64ms)
12-16 20:06:33.581 7333-8993/br.com.empresa.oprojeto D/OkHttp: Server: Apache-Coyote/1.1
12-16 20:06:33.581 7333-8993/br.com.empresa.oprojeto D/OkHttp: Content-Type: text/html;charset=utf-8
12-16 20:06:33.581 7333-8993/br.com.empresa.oprojeto D/OkHttp: Content-Language: en
12-16 20:06:33.581 7333-8993/br.com.empresa.oprojeto D/OkHttp: Content-Length: 1033
12-16 20:06:33.581 7333-8993/br.com.empresa.oprojeto D/OkHttp: Date: Wed, 16 Dec 2015 22:06:31 GMT
12-16 20:06:33.581 7333-8993/br.com.empresa.oprojeto D/OkHttp: Connection: close
12-16 20:06:33.581 7333-8993/br.com.empresa.oprojeto D/OkHttp: OkHttp-Selected-Protocol: http/1.1
12-16 20:06:33.581 7333-8993/br.com.empresa.oprojeto D/OkHttp: OkHttp-Sent-Millis: 1450303593575
12-16 20:06:33.581 7333-8993/br.com.empresa.oprojeto D/OkHttp: OkHttp-Received-Millis: 1450303593591
12-16 20:06:33.581 7333-8993/br.com.empresa.oprojeto D/OkHttp: <!DOCTYPE html><html><head><title>Apache Tomcat/8.0.29 - Error report</title><style type="text/css">H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}.line {height: 1px; background-color: #525D76; border: none;}</style> </head><body><h1>HTTP Status 400 - Bad Request</h1><div class="line"></div><p><b>type</b> Status report</p><p><b>message</b> <u>Bad Request</u></p><p><b>description</b> <u>The request sent by the client was syntactically incorrect.</u></p><hr class="line"><h3>Apache Tomcat/8.0.29</h3></body></html>
12-16 20:06:33.581 7333-8993/br.com.empresa.oprojeto D/OkHttp: <-- END HTTP (1033-byte body)
I finally solved the problem. I was sending type java.util.Date as a parameter and I decided to change to type Long (or long). So, my web service method is now:
#POST
#Path("/byPeriodo")
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public List<ItemProdutividade> getProdutividadeByPeriodo(#FormParam("dataInicial")
long dataInicial, #FormParam("dataFinal") long dataFinal,
#FormParam("cpf") long cpf){
return service.getProdutividadeByPeriodo(DateUtils.toLocalDate(new Date(dataInicial)),
DateUtils.toLocalDate(new Date(dataFinal)), cpf);
}
The secret was to change type Date to long and do that: new Date(long).
I am trying to access a SOAP service. To do this I am creating the SOAP request manually (which I preefer). The problem is that when I do
URL urli = new URL("http://www.myserver.com//x/y/z/a/b/c/d/myUrlWS.jws");
HttpURLConnection c = (HttpURLConnection) urli.openConnection();
c.setRequestMethod("POST");
c.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
c.setRequestProperty("Content-Length", bytes.length+"");
c.setRequestProperty("SOAPAction", "");
...
c.getInputStream();
The thing is that the http header shows this way:
POST /x/y/z/a/b/c/d/myUrlWS.jws
...(reset of http header)...
SOAP Message
I am getting an error form the server and I think that the POST in the http should be like:
POST /
or
POST /action
or
POST /myUrlWS.jws
So I dont know how to change the POST parameter in the header. How do I do that without changing the connection URL/address?
EDIT - The SOAP Reply from server
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"><env:Header/><env:Body><env:Fault><faultcode>env:Server</faultcode><faultstring>[Server CodecHandler] Failed to decode
-> Unable to find xml element for parameter: documentos
</faultstring><detail><java:string xmlns:java="java.io">weblogic.wsee.codec.CodecException: Unable to find xml element for parameter: documentos
</java:string></detail></env:Fault></env:Body></env:Envelope>
FULL HTTP REQUEST
POST /x/y/z/a/b/c/d/myUrlWS.jws HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction:
User-Agent: Java/1.7.0_75
Host: wwwW.somehost.some.gov.br
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-Length: 2026
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:WL5G3N0="http://schemas.xmlsoap.org/wsdl/" xmlns:WL5G3N1="http://www.openuri.org/" xmlns:WL5G3N2="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:WL5G3N3="http://www.openuri.org/2006/12/wsdl/upgradedJWS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOAP-ENV:Body>
<WL5G3N1:enviarDados xmlns:WL5G3N1="http://www.openuri.org/">
<emitente>
<CNPJEmitente>11111111</CNPJEmitente>
<Email>my#email.com</Email>
</emitente>
<documentos>
<Documento>
<TipoPagamento>1</TipoPagamento>
<TipoDocumento>2</TipoDocumento>
<DataPagamento>13/04/15</DataPagamento>
<ItensPagamentos>
<ItemPagamento>
<TipoId>1</TipoId>
<Cnpj>1111111111</Cnpj>
<CodigoProduto>11111</CodigoProduto>
<DataFatoGerador>13/04/15</DataFatoGerador>
<DataVencimento>13/04/15</DataVencimento>
<DddContribuinte>16</DddContribuinte>
<EnderecoContribuinte>SOME NAME</EnderecoContribuinte>
<MunicipioContribuinte>NAME</MunicipioContribuinte>
<UFContribuinte>SP</UFContribuinte>
<CepContribuinte>11111111</CepContribuinte>
<TelefoneContribuinte>111111</TelefoneContribuinte>
<Natureza>1</Natureza>
<NomeRazaoSocial>SOME NAME</NomeRazaoSocial>
<NotaFiscalCnpj>1111111</NotaFiscalCnpj>
<NotaFiscalDataEmissao>2014-12-04</NotaFiscalDataEmissao>
<NotaFiscalNumero>111111</NotaFiscalNumero>
<NotaFiscalSerie>1</NotaFiscalSerie>
<NotaFiscalTipo>NF-e</NotaFiscalTipo>
<NumControleContribuinte>111111</NumControleContribuinte>
<TipoApuracao>2</TipoApuracao>
<PeriodoReferenciaAno>2015</PeriodoReferenciaAno>
<PeriodoReferenciaMes>04</PeriodoReferenciaMes>
<PeriodoReferenciaDecendio>2</PeriodoReferenciaDecendio>
<DiaVencimento>13/04/15</DiaVencimento>
<ValorICMSPrincipal>221.21</ValorICMSPrincipal>
<ValorTotal>221.21</ValorTotal>
</ItemPagamento>
</ItensPagamentos>
</Documento>
</documentos>
</WL5G3N1:enviarDados>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
WSDL here:
WSDL
By looking at the exeption that you Got, I can guess that your SOAP payload message is malformed.
The each tag of XML message should be mentioned by a namespace. In your case you are mentioning the namespace as "WL5G3N1" in the following tag.
<WL5G3N1:enviarDados xmlns:WL5G3N1="http://www.openuri.org/">
So You should use WL5G3N1 throughout the message for refering each and every XML element.
So the following XML should work.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:WL5G3N0="http://schemas.xmlsoap.org/wsdl/" xmlns:WL5G3N1="http://www.openuri.org/"
xmlns:WL5G3N2="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:WL5G3N3="http://www.openuri.org/2006/12/wsdl/upgradedJWS"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOAP-ENV:Body>
<WL5G3N1:enviarDados xmlns:WL5G3N1="http://www.openuri.org/">
<WL5G3N1:emitente>
<WL5G3N1:CNPJEmitente>11111111</WL5G3N1:CNPJEmitente>
<WL5G3N1:Email>my#email.com</WL5G3N1:Email>
</WL5G3N1:emitente>
<WL5G3N1:documentos>
<WL5G3N1:Documento>
<WL5G3N1:TipoPagamento>1</WL5G3N1:TipoPagamento>
<WL5G3N1:TipoDocumento>2</WL5G3N1:TipoDocumento>
<WL5G3N1:DataPagamento>13/04/15</WL5G3N1:DataPagamento>
<WL5G3N1:ItensPagamentos>
<WL5G3N1:ItemPagamento>
<WL5G3N1:TipoId>1</WL5G3N1:TipoId>
<WL5G3N1:Cnpj>1111111111</WL5G3N1:Cnpj>
<WL5G3N1:CodigoProduto>11111</WL5G3N1:CodigoProduto>
<WL5G3N1:DataFatoGerador>13/04/15</WL5G3N1:DataFatoGerador>
<WL5G3N1:DataVencimento>13/04/15</WL5G3N1:DataVencimento>
<WL5G3N1:DddContribuinte>16</WL5G3N1:DddContribuinte>
<WL5G3N1:EnderecoContribuinte>SOME NAME</WL5G3N1:EnderecoContribuinte>
<WL5G3N1:MunicipioContribuinte>NAME</WL5G3N1:MunicipioContribuinte>
<WL5G3N1:UFContribuinte>SP</WL5G3N1:UFContribuinte>
<WL5G3N1:CepContribuinte>11111111</WL5G3N1:CepContribuinte>
<WL5G3N1:TelefoneContribuinte>111111
</WL5G3N1:TelefoneContribuinte>
<WL5G3N1:Natureza>1</WL5G3N1:Natureza>
<WL5G3N1:NomeRazaoSocial>SOME NAME</WL5G3N1:NomeRazaoSocial>
<WL5G3N1:NotaFiscalCnpj>1111111</WL5G3N1:NotaFiscalCnpj>
<WL5G3N1:NotaFiscalDataEmissao>2014-12-04</WL5G3N1:NotaFiscalDataEmissao>
<WL5G3N1:NotaFiscalNumero>111111</WL5G3N1:NotaFiscalNumero>
<WL5G3N1:NotaFiscalSerie>1</WL5G3N1:NotaFiscalSerie>
<WL5G3N1:NotaFiscalTipo>NF-e</WL5G3N1:NotaFiscalTipo>
<WL5G3N1:NumControleContribuinte>111111
</WL5G3N1:NumControleContribuinte>
<WL5G3N1:TipoApuracao>2</WL5G3N1:TipoApuracao>
<WL5G3N1:PeriodoReferenciaAno>2015</WL5G3N1:PeriodoReferenciaAno>
<WL5G3N1:PeriodoReferenciaMes>04</WL5G3N1:PeriodoReferenciaMes>
<WL5G3N1:PeriodoReferenciaDecendio>2
</WL5G3N1:PeriodoReferenciaDecendio>
<WL5G3N1:DiaVencimento>13/04/15</WL5G3N1:DiaVencimento>
<WL5G3N1:ValorICMSPrincipal>221.21</WL5G3N1:ValorICMSPrincipal>
<WL5G3N1:ValorTotal>221.21</WL5G3N1:ValorTotal>
</WL5G3N1:ItemPagamento>
</WL5G3N1:ItensPagamentos>
</WL5G3N1:Documento>
</WL5G3N1:documentos>
</WL5G3N1:enviarDados>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I'm trying to send a request to a web service that has "Wssp1.2-2007-Https-UsernameToken-Digest.xml" as policy.
below is my code, I'm using apache cxf library on eclipse:
public static void main(String[]args){
CardDetails_Service cds = new CardDetails_Service();
CardDetails cdsPort = cds.getCardDetailsPort();
//End_Init_load
//Retrieve the client object from the port
Client client = ClientProxy.getClient(cdsPort);
Endpoint cxfEndpoint = client.getEndpoint();
Map<String, Object> ctx = ((BindingProvider) cdsPort).getRequestContext();
ctx.put("ws-security.username", "weblogicdev");
ctx.put("ws-security.password", "weblogic123");
client.getInInterceptors().add(new LoggingInInterceptor());
client.getOutInterceptors().add(new LoggingOutInterceptor());
CustomerRequestParam crp = new CustomerRequestParam();
crp.setCustomerID("dasd");
crp.setDataLevel("adsa");
crp.setInstitution("11");
CustomerResponseParam crpResponse = cdsPort.getCardDetailByCustomerOperation(crp);
System.out.println(crpResponse.getResponseDetails().getResponseCode()+"]["+crpResponse.getResponseDetails().getResponseDescription());
}
When I change the policy of the web service to Wssp1.2-2007-Https-UsernameToken-Plain.xml, the code above works, and I get a response.
But when I switch it back to digest, it doesn't work.
Below is an output of the generated request of the requests in both policies:
UsernameToken-Digest:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="1">
<wsu:Timestamp wsu:Id="TS-9cec2846-7695-4c8b-b7c3-4c8cf6887b9e">
<wsu:Created>2014-06-26T12:55:32.262Z
</wsu:Created>
<wsu:Expires>2014-06-26T13:00:32.262Z
</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken wsu:Id="UsernameToken-36511701-a842-4ba5-8e29-dc8841fb3a61">
<wsse:Username>weblogicdev
</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">m5nhNFD+LT9e9sk8CAClHdFNTdQ=
</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">MKlsVkLpcQykOosbGnszvg==
</wsse:Nonce>
<wsu:Created>2014-06-26T12:55:32.270Z
</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</SOAP-ENV:Header>
<soap:Body>
<CustomerRequest xmlns="www.mdsl.eft.cms.com">
<Institution>11
</Institution>
<Customer_ID>dasd
</Customer_ID>
<Data_Level>adsa
</Data_Level>
</CustomerRequest>
</soap:Body>
</soap:Envelope>
UsernameToken-Plain:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="1">
<wsu:Timestamp wsu:Id="TS-9140d6d2-ce36-4efd-aedd-bfc338480993">
<wsu:Created>2014-06-26T12:45:49.342Z
</wsu:Created>
<wsu:Expires>2014-06-26T12:50:49.342Z
</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken wsu:Id="UsernameToken-a16f2785-c64d-44df-87e8-b8b840612192">
<wsse:Username>weblogicdev
</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">weblogic123
</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</SOAP-ENV:Header>
<soap:Body>
<CustomerRequest xmlns="www.mdsl.eft.cms.com">
<Institution>11
</Institution>
<Customer_ID>dasd
</Customer_ID>
<Data_Level>adsa
</Data_Level>
</CustomerRequest>
</soap:Body>
</soap:Envelope>
The requests are changing to suit the switch of policies but I don't understand why I'm getting a "Failed to assert identity with UsernameToken".
For more info, below is the full trace:
Jun 26, 2014 5:32:18 PM io.netty.util.internal.logging.Slf4JLogger info
INFO: Your platform does not provide complete low-level API for accessing direct buffers reliably. Unless explicitly requested, heap buffer will always be preferred to avoid potential system unstability.
Jun 26, 2014 5:32:19 PM org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDL
INFO: Creating Service {http://test/}CardDetails from WSDL: https://localhost:7002/testWebService/CardDetailsPort?wsdl
Jun 26, 2014 5:32:19 PM org.apache.cxf.services.CardDetails.CardDetailsPort.CardDetails
INFO: Outbound Message
---------------------------
ID: 1
Address: https://localhost:7002/TestWebService/CardDetailsPort
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml
Headers: {Accept=[*/], SOAPAction=["urn:Test/getCardDetailByCustomerOperation"]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="1"><wsu:Timestamp wsu:Id="TS-2f3ad257-f56f-4658-8553-2867143f2188"><wsu:Created>2014-06-26T14:32:19.664Z</wsu:Created><wsu:Expires>2014-06-26T14:37:19.664Z</wsu:Expires></wsu:Timestamp><wsse:UsernameToken wsu:Id="UsernameToken-bcb0d1b1-3ee3-4182-bdc6-476f86006153"><wsse:Username>weblogicdev</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">iqb9Xe1/GqwfPW0CU1NOO96eH2I=</wsse:Password><wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">3BkQP6r7MPJrs5AIohRwEQ==</wsse:Nonce><wsu:Created>2014-06-26T14:32:19.671Z</wsu:Created></wsse:UsernameToken></wsse:Security></SOAP-ENV:Header><soap:Body><CustomerRequest xmlns="www.mdsl.eft.cms.com"><Institution>11</Institution><Customer_ID>dasd</Customer_ID><Data_Level>adsa</Data_Level></CustomerRequest></soap:Body></soap:Envelope>
--------------------------------------
Jun 26, 2014 5:32:19 PM org.apache.cxf.services.CardDetails.CardDetailsPort.CardDetails
INFO: Inbound Message
----------------------------
ID: 1
Response-Code: 500
Encoding: UTF-8
Content-Type: text/xml;charset="utf-8"
Headers: {Content-Length=[380], Content-Type=[text/xml;charset="utf-8"], Date=[Thu, 26 Jun 2014 14:32:19 GMT], X-ORACLE-DMS-ECID=[37cb61f8f3397d86:62376f09:146d4fa0d76:-8000-0000000000000c23], X-Powered-By=[Servlet/2.5 JSP/2.1]}
Payload: <?xml version='1.0' encoding='UTF-8'?><env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"><env:Body><env:Fault xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><faultcode>wsse:FailedAuthentication</faultcode><faultstring>Failed to assert identity with UsernameToken.</faultstring></env:Fault></env:Body></env:Envelope>
--------------------------------------
Jun 26, 2014 5:32:19 PM org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor handleMessage
WARNING: Request does not contain Security header, but it's a fault.
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Failed to assert identity with UsernameToken.
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:159)
at $Proxy35.getCardDetailByCustomerOperation(Unknown Source)
at Test.Tester.main(Tester.java:83)
Caused by: org.apache.cxf.binding.soap.SoapFault: Failed to assert identity with UsernameToken.
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:84)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:51)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:40)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:113)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:69)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:34)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:798)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1636)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1525)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1330)
at org.apache.cxf.transport.http.netty.client.NettyHttpConduit$NettyWrappedOutputStream.close(NettyHttpConduit.java:153)
at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:56)
at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:215)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:638)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:514)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:423)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:326)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:279)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:137)
... 2 more
By default, WebLogic doesn't store the password in a retrievable manner, necessary for the digest method to work.
To fix it, in the admin console, go to providers configuration of your security realms setting (by default: Security Realm -> myrealm -> Providers) and for the DefaultAuthenticator, under the Provider Specific tab, make sure Enable Password Digests is enabled.
Also make sure that wsse:PasswordDigest is active in the DefaultIdentityAsserter settings.
NOTE: After you turn on Enable Password Digests, you have to reset the password of any user(s) you want to participate in the authentication for you web service.
From page 6 of this Document
Password_Digest = Base64 ( SHA-1 ( nonce + created + password ) )
Can you verify that your digest is correctly following this formula?
The actual code that performs the validation on the server side can be found here