I want to implement custom handler that will check if request contains all required security headers.
The "head" part of the request looks as follows:
<soapenv:Header xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<header1>value of header one</header1>
<header2>value of header two</header2>
<wsse:Security soap:mustUnderstand="1" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>X</wsse:Username>
<wsse:Password>X</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
I tried to get access to the seciurity header and I can't.
First way which I tried was:
public class MyCustomHandler implements
SOAPHandler<SOAPMessageContext> {
public boolean handleMessage(SOAPMessageContext smc) {
SOAPMessage message = smc.getMessage();
SOAPHeader header = message.getSOAPHeader();
Iterator iterator = header.getChildElements();
while (iterator.hasNext()) {
SOAPElement element = (SOAPElement) iterator.next();
log.debug(element.getValue());
log.debug(element.getLocalName());
}
return true;
}
public boolean handleFault(SOAPMessageContext smc) {
logToSystemOut(smc);
return true;
}
public void close(MessageContext messageContext) {
}
...
Unfortunetaly the "while" loop logged only header1 and header2 but there is nothing about "Seciurity".
I tried also getChilds(Qname) but it also does not work.
You might want to try using the SOAPPart of the message:
if (!((Boolean) messageContext.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue()) {
SOAPPart msg = messageContext.getMessage().getSOAPPart();
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
final Map<String, String> namespaceMap = new HashMap<String, String>();
namespaceMap.put("soap", "http://schemas.xmlsoap.org/soap/envelope/");
namespaceMap.put("wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
NamespaceContext nsContext = new NamespaceContext() {
#Override
public Iterator<String> getPrefixes(String namespaceURI) {
List<String> prefixes = new ArrayList<String>();
for (String url : namespaceMap.values()) {
if (url.equals(namespaceURI)) {
prefixes.add(url);
}
}
return prefixes.iterator();
}
#Override
public String getPrefix(String namespaceURI) {
return getPrefixes(namespaceURI).next();
}
#Override
public String getNamespaceURI(String prefix) {
return namespaceMap.get(prefix);
}
};
xPath.setNamespaceContext(nsContext);
String userName = (String) xPath.evaluate("/soap:Envelope/soap:Header/wsse:Security/wsse:UsernameToken/wsse:Username/text()", msg,
XPathConstants.STRING);
String password = (String) xPath.evaluate("/soap:Envelope/soap:Header/wsse:Security/wsse:UsernameToken/wsse:Password/text()", msg,
XPathConstants.STRING);
}
I also added a check for "only inbound" messages. You don't want to check for security-stuff on you replies I assume.
Does this work for you (I just typed this down. Didnt really test it so you might have a compile issue)?
Related
I am trying to send Get request using RestSharp but getting this message in response:Bad Request/
{"Message":"P1001: No Ids were specified"}. Could someone help please to figure out that? Seems like it's not adding Parameter list to the Request Body...
Here is my code:
public partial class DTO
{
public List<string> evidenceIds { get; set; }
}
public RestRequest GetPlayRequest(Method requestType, string token)
{
DTO MyObject = new DTO();
MyObject.evidenceIds = new List<string>();
MyObject.evidenceIds.Add("6F00CAE1-F16E-47F6-AF3F-D10305DD7859");
string jsonString = JsonConvert.SerializeObject(MyObject);
var restRequest = new RestRequest(requestType);
restRequest.RequestFormat = DataFormat.Json;
restRequest.AddParameter("text/json", jsonString, ParameterType.RequestBody);
restRequest.AddHeader("Organization", "Bofa");
restRequest.AddHeader("Username", "Admin");
restRequest.AddParameter("Authorization", "Bearer " + token, ParameterType.HttpHeader);
return restRequest;
}
The request with all params
The Content response after sending the request
I can suggest the following:
public RestRequest GetPlayRequest(Method method, string token)
{
var obj = new DTO { evidenceIds = new string[]
{"6F00CAE1-F16E-47F6-AF3F-D10305DD7859" }
};
return new RestRequest(method)
.AddJsonBody(obj)
.AddHeader("Organization", "Bofa")
.AddHeader("Username", "Admin");
.AddHeader("Authorization", $"Bearer {token}");
}
I am working on a migration project from j2ee to Springboot.. I do struggle to upload a file in spring boot. As in the J2EE application "org.apache.tomcat.util.http.fileupload" is used, to upload a file, I thought as spring-boot has embedded tomcat, it is going to work, but unfortunately it doesn't. I have to work with Multipart.. I can't make it false at any time. Same thing I tried with apache common end up with same result. Here is my code .. could you please suggest me how to proceed .. your help would really appreciated..
I have two filters too.. for testing I use postman
import org.apache.tomcat.util.http.fileupload.FileItemIterator;
import org.apache.tomcat.util.http.fileupload.FileItemStream;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
#RestController
#RequestMapping("/v2")
public class PDFExtractController {
private static final long serialVersionUID = 1L;
private static Logger log = Logger.getLogger(PDFExtractController.class);
// #RequestHeader(PESConstants.CLIENT_CONTEXT) String intuit_clientcontext, // deleted from the function parameter
#RequestMapping(value = "document/{DocType}",method =RequestMethod.POST,consumes = "multipart/form-data")
public ResponseData fileUpload(#PathVariable("DocType") String docType, HttpServletRequest request){
boolean isMultipartContent = ServletFileUpload.isMultipartContent(request);
String provider = null;
String password = null;
boolean verbose = false;
if (isMultipartContent) {
// Grab the content
try {
ServletFileUpload fileUpload = new ServletFileUpload();
FileItemIterator items = fileUpload.getItemIterator(request);
while (items.hasNext()) {
FileItemStream item = items.next();
String fieldname = item.getFieldName();
if (PESConstants.PARAM_PROVIDER.equals(fieldname)) {
provider = PdfServletMgr.getTextValue(item);
SplunkMgr.addtoMDC(MDCFieldNames.PROVIDER.getValue(), provider.trim());
}
else if (PESConstants.PARAM_VERBOSE.equals(fieldname)) {
verbose = "true".equals(PdfServletMgr.getTextValue(item));
}
if (PESConstants.PARAM_PDF.equals(fieldname) && "form".equalsIgnoreCase(docType)) {
file = PdfServletMgr.getValue(item);
}
else if (PESConstants.PARAM_PASSWORD.equals(fieldname)) {
password = PdfServletMgr.getTextValue(item);
}
}
}
}
}
}
I changed my Mapping as below, and it started working...
#RequestMapping(value = "document/{DocType}",method =RequestMethod.POST)
public ResponseData fileUpload(#PathVariable("DocType") String docType, #RequestParam("pdf") MultipartFile[] multipartfiles,HttpServletRequest request){
ResponseData responseData = new ResponseData();
System.out.println("your code in between...");
return responseData;
}
I want to implement a custom Content-Type validation filter so that a custom error model on a 415 Unsupported Media Type can be provided.
Something like this:
public class ValidateContentTypeFilterAttribute : ActionFilterAttribute
{
private const string JsonMimeType = "application/json";
public override void OnActionExecuting(ActionExecutingContext context)
{
string requestMethod = context.HttpContext.Request.Method.ToUpper();
if (requestMethod == WebRequestMethods.Http.Post || requestMethod == WebRequestMethods.Http.Put)
{
if (request.ContentType != JsonMimeType)
{
// "Unsupported Media Type" HTTP result.
context.Result = new HttpUnsupportedMediaTypeResult();
return;
}
}
}
}
The problem is that the MVC pipeline seems to be "catching" unsupported or invalid Content-Type values before executing any custom filters. Even the 'application/xml' content type will be refused.
Where would this be configured?
My MVC configuration consists of not much more than this:
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvc()
.AddJsonOptions(options =>
{
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
options.SerializerSettings.DefaultValueHandling = DefaultValueHandling.Include;
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
options.SerializerSettings.Converters.Add(new SquidJsonConverter());
})
.AddMvcOptions(options =>
{
options.Filters.Add(typeof(ValidateAntiForgeryTokenAttribute));
options.Filters.Add(typeof(ValidateContentTypeFilterAttribute));
options.Filters.Add(typeof(ValidateAcceptFilterAttribute));
options.Filters.Add(typeof(ValidateModelFilterAttribute));
});
...
}
Action filters are too late in the processing pipeline for what you are trying to achieve here.
The filter execution order for an "incoming" request is the following:
Authorization filters' OnAuthorization.. method invocation
Resource filters' OnResourceExecuting.. method invocation Model
Model binding happens (this is the place where the content type check is
made)
Action filters' OnActionExecuting.. method invocation
Action execution happens
You could instead create a resource filter. An example:
public class CustomResourceFilter : IResourceFilter
{
private readonly string jsonMediaType = "application/json";
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
public void OnResourceExecuting(ResourceExecutingContext context)
{
if (context.HttpContext.Request.Method == "PUT" || context.HttpContext.Request.Method == "POST")
{
if (!string.Equals(
MediaTypeHeaderValue.Parse(context.HttpContext.Request.ContentType).MediaType,
jsonMediaType,
StringComparison.OrdinalIgnoreCase))
{
context.Result = new JsonResult(new { Error = "An error message here" }) { StatusCode = 415 };
}
}
}
}
If you would like to modify all types of UnsupportedMediaTypeResult responses, then you could write a Result filter instead.
The filter pipeline for outgoing response is:
Action filters' OnActionExecuted... method invocation
Result filters' OnResultExecuting.. method invocation
Result filters' OnResultExecuted.. method invocation
Resource filters' OnResourceExecuted.. method invocation
An example with a Result filter:
public class CustomResultFilter : ResultFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext context)
{
var result = context.Result as UnsupportedMediaTypeResult;
if (result != null)
{
context.Result = new JsonResult(new { Error = "An error message here" }) { StatusCode = 415 };
}
}
}
Hello all I want to use AndroidAsyncHttp for posting data to server.
for that i have 4 Parameters in header and 10 in body request i have done the following code but not working and getting null response..
void callMethod()
{
AsyncHttpClient clinet = new AsyncHttpClient();
HttpPost httpPost = new HttpPost();
httpPost.setHeader("HEADERPRMNAME", "werew");
httpPost.setHeader("HEADERPRMNAME", "werweR");
httpPost.setHeader("HEADERPRMNAME", "Rwerwep");
httpPost.setHeader("HEADERPRMNAME", "werwe");
Network.Request r = new Network.Request();
clinet.addHeader("HEADERPRMNAME"werr");
clinet.addHeader("HEADERPRMNAME", "werwer");
clinet.addHeader("HEADERPRMNAME", "1223134");
clinet.addHeader("HEADERPRMNAME", "wer");
// Headers headers1=Headers.of("HEADERPRMNAME","121");
// Headers headers1=Headers.of("HEADERPRMNAME","12121212");
// Headers headers1=Headers.of("HEADERPRMNAME","werew");
RequestParams requestParams = new RequestParams();
requestParams.put("HEADERPRMNAME", 10);
requestParams.put("HEADERPRMNAME", 1);
clinet.setUserAgent("I HAVE PASSED HERE ALSO AS STRING BUT NOT WORKED");
clinet.post(ctx, "MYURL", requestParams, new TextHttpResponseHandler() {
#Override
public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
System.out.println("PPLLL" + responseString);
}
#Override
public void onSuccess(int statusCode, Header[] headers, String responseString) {
}
});
}
please help me out
I'm trying to upload a file using JavaFX using the HttpRequest. For this purpose I have written the following function.
function uploadFile(inputFile : File) : Void {
// check file
if (inputFile == null or not(inputFile.exists()) or inputFile.isDirectory()) {
return;
}
def httpRequest : HttpRequest = HttpRequest {
location: urlConverter.encodeURL("{serverUrl}");
source: new FileInputStream(inputFile)
method: HttpRequest.POST
headers: [
HttpHeader {
name: HttpHeader.CONTENT_TYPE
value: "multipart/form-data"
}
]
}
httpRequest.start();
}
On the server side, I am trying to handle the incoming data using the Apache Commons FileUpload API using a Jersey REST service. The code used to do this is a simple copy of the FileUpload tutorial on the Apache homepage.
#Path("Upload")
public class UploadService {
public static final String RC_OK = "OK";
public static final String RC_ERROR = "ERROR";
#POST
#Produces("text/plain")
public String handleFileUpload(#Context HttpServletRequest request) {
if (!ServletFileUpload.isMultipartContent(request)) {
return RC_ERROR;
}
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> items = null;
try {
items = upload.parseRequest(request);
}
catch (FileUploadException e) {
e.printStackTrace();
return RC_ERROR;
}
...
}
}
However, I get a exception at items = upload.parseRequest(request);:
org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
I guess I have to add a manual boundary info to the InputStream. Is there any easy solution to do this? Or are there even other solutions?
Have you tried just using the InputStream from HttpServletRequest like so
InputStream is = httpRequest.getInputStream();
BufferedInputStream in = new BufferedInputStream(is);
//Write out bytes
out.close();
is.close();