validate signature for saml2 response redirect java sha256 encryption - saml-2.0

I'm trying to validate SAML response in order to redirect the client to appropriate page. Here is my Servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String samlParam = request.getParameter(GeneralConstants.SAML_RESPONSE_KEY);
if (samlParam != null) {
// how to validate signature in order to redirect?
// String queryString = request.getQueryString();
// byte[] signatureFromQueryString = RedirectBindingSignatureUtil.getSignatureValueFromSignedURL(queryString);
} else {
// ...
}
}
Encryption Method is set SHA256 from Saml Server for current (Relying party trusts). I'm using picketlink (https://issues.jboss.org/browse/PLINK-621) library but since it doesn't support SHA256 encryption i have to write signature validation myself...

Related

Changing apache camel message type to InOut

From what I understand, an InOut message is one where a response can be received from the destination.
However, I have not been able to find any example of how to convert a message to InOut type, and how to access the response from the destination
For example, given a route like:
from("direct:start").to("smtps://smtp.gmail.com:465?username=user#gmail.com&password=usrpw&to=address#gmail.com")
How to convert the message routed to smtps component into InOut type?
Can I expect a response from the smtp component, e.g. indicating that the message was sent successfully?
how to access this response?
By default, each ".to(uri)" are in InOut. The body in the next step will be replaced by the response of the InOut destination. For example, in HTTP component, if you have the following route :
from(direct:start)
.to(http://...)
.log(INFO, "${body}")
The response to the http call will be logged.
If you don't find good informations in the document, I highly recommend you to check the code of the related producer to know what's returned or can be used.
https://github.com/apache/camel
For example, for SMTP, I haven't found the doc saying what's happening to the body, but the code is pretty much clear :
public void process(final Exchange exchange) {
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
try {
ClassLoader applicationClassLoader = getEndpoint().getCamelContext().getApplicationContextClassLoader();
if (applicationClassLoader != null) {
Thread.currentThread().setContextClassLoader(applicationClassLoader);
}
MimeMessage mimeMessage;
final Object body = exchange.getIn().getBody();
if (body instanceof MimeMessage) {
// Body is directly a MimeMessage
mimeMessage = (MimeMessage) body;
} else {
// Create a message with exchange data
mimeMessage = new MimeMessage(sender.getSession());
getEndpoint().getBinding().populateMailMessage(getEndpoint(), mimeMessage, exchange);
}
if (LOG.isDebugEnabled()) {
LOG.debug("Sending MimeMessage: {}", MailUtils.dumpMessage(mimeMessage));
}
sender.send(mimeMessage);
// set the message ID for further processing
exchange.getIn().setHeader(MailConstants.MAIL_MESSAGE_ID, mimeMessage.getMessageID());
} catch (MessagingException e) {
exchange.setException(e);
} catch (IOException e) {
exchange.setException(e);
} finally {
Thread.currentThread().setContextClassLoader(tccl);
}
}
Your exchange will have an header with the MAIL_ID ("CamelMailMessageId"), and in case of any messaging exception, the exception will be propagated. The body seems to be left untouched, even if it's InOut.

Codename one application is not able to connect with server using https request

We have created codename one application which using https request.
I have not made any changes in code.
Earlier the request could be sent using https but now their is a problem and i am unable to connect to the server using https request but i am able to connect same https url using postman.
The connection code snippet is following please refer it
new APIHandler().PropertiesLoad();
ConnectionRequest req = new ConnectionRequest() {
protected void handleErrorResponseCode(int code, String message) {
if (code != 200) {
// do something
}
}
};
req.setUrl(properties.getProperty("https_url"));
req.setPost(true);
req.setTimeout(Constant.TIMEOUT);
req.addArgument("FirstName", fName;
req.addArgument("SecondName", sName);
req.addArgument("BirthDate", bDate);
req.addArgument("Password", pWord);
NetworkManager.getInstance().addErrorListener((e) -> e.consume());
NetworkManager.getInstance().addToQueueAndWait(req);
byte[] data = req.getResponseData();
if (data == null) {
}
result = new String(data);
} catch (Exception e) {
//get nullpointer exception because result get null
result = "";
}
return result;

How to send FCM message from Appengine server on cloud code works local server

How to do it in cloud AppEngine without billing.
I am able to get Token from Javascript but sending messages to the server for notification. Create JSON object for downstream data/notification. On the server saying billing for the socket.
private void localappengine(HttpServletResponse response, String ENDPOINT_URL) throws IOException {
HttpClient client = new DefaultHttpClient();
Log.info("after client");
HttpPost post = new HttpPost(ENDPOINT_URL);
String deviceToken="cthG-hesotM:APA91bGg_tLg7TqvpY4aAvzHpyBK2mTTOT2KgO94tDFcLGPakcS9vmXkYEIe4Vh0Mo5ka1COfaXarUEJGWyqDdmVi_kujUfKDtE4C30eZwkPQATXnFrDPJxHxd8iouwsWuRcAk-ZYe_4";
PrintWriter out=response.getWriter();
response.getWriter().println("Hello from myservlet " );
// Create JSON object for downstream data/notification
JSONObject mainNotificationJsonObj = new JSONObject();
JSONObject outerBaseJsonObj = new JSONObject();
try {
// Notification payload has 'title' and 'body' key
mainNotificationJsonObj.put("title", "testing message");
mainNotificationJsonObj.put("body", "Hello I sent it");
// This will be used in case of both 'notification' or 'data' payload
outerBaseJsonObj.put("to", deviceToken);
// Set priority of notification. For instant chat setting
// high will
// wake device from idle state - HIGH BATTERY DRAIN
//outerBaseJsonObj.put(PRIORITY_KEY, PRIORITY_HIGH);
// Specify required payload key here either 'data' or
// 'notification'. We can even use both payloads in single
// message
outerBaseJsonObj.put("notification", mainNotificationJsonObj);
} catch (JSONException e) {
e.printStackTrace();
}
Log.info("before entity");
// Setup http entity with json data and 'Content-Type' header
StringEntity requestEntity = new StringEntity(outerBaseJsonObj.toString());
//(outerBaseJsonObj.toString(), APPLICATION_JSON);
String FIREBASE_SERVER_KEY= "key=AAAA6nN2BxI:APA91bHYotXML0siwL0Pm0LK5iXQ9Ik1kQtdB1ALbJrm5kseUk2zS5gJs6AMHVsX86exEE-JFsIF962YNY1yRyl3yFxGCyMBAH4OKwTn8Ff6vcd6vJMVXutNlP99X8AtOsW8_JIBkyEl";
// Setup required Authorization header
post.setHeader("Authorization", FIREBASE_SERVER_KEY);
post.setHeader("Content-Type", String.valueOf(APPLICATION_JSON));
Log.info("after header");
// Pass setup entity to post request here
post.setEntity(requestEntity);
// Execute apache http client post response
HttpResponse fcmResponse = client.execute(post);
Log.info("after client execute");
// Get status code from FCM server to debug error and success
System.out.println("RESPONSE_CODE" + fcmResponse.getStatusLine().getStatusCode());
// Get response entity from FCM server and read throw lines
BufferedReader rd = new BufferedReader(new InputStreamReader(fcmResponse.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
if (response != null) {
// Print out the response to webpage
PrintWriter out1;
out1 = response.getWriter();
out1.println(result);
System.out.println("This is Result - " + result);
}
}

SAML request signature verification c#

I am creating a SAML Identity provider, and our service provider is using a third party tool Component Space to do their end's work. Identity provider I developed takes login credentials from a user and validates that user on our active directory federation server. If the user is valid then I create an SAMLResponse, sign it with X509Certificate and post it to AssertionConsumerServiceURL which I received from SAMLRequest. Now I need to verify that the SAMLRequest is coming from a valid service provider and has not be modified in between.
Initially the service provider was using HTTP redirect binding and sending the SAMLRequest, SigAlg and Signature in query string, I tried below code to verify the signature, but it always returns false.
public bool VerifyHashDynamic(string Signature, string request)
{
bool isVerified = false;
X509Certificate2 x509 = new X509Certificate2(Server.MapPath(".") + #"\X509Certificate\SP.cer", "password");
byte[] signature = Base64DecodeArray(Signature);
byte[] signedData = Base64DecodeArray(request);
RSACryptoServiceProvider rsaCSP = (RSACryptoServiceProvider)x509.PublicKey.Key;
SHA256Managed hash = new SHA256Managed();
byte[] hashedData;
bool dataOK = rsaCSP.VerifyData(signedData, CryptoConfig.MapNameToOID("SHA256"), signature);
hashedData = hash.ComputeHash(signedData);
isVerified = rsaCSP.VerifyHash(hashedData, CryptoConfig.MapNameToOID("SHA256"), signature);
return isVerified;
}
Is there something wrong in above code, which is allowing the signature verification?
In order to make it work in another way, I asked our service provider to send AuthNRequest with embedded signature (HTTP-POST binding). For signature verification of posted AuthnRequest I tried XMLDocument verification, here is the code:
public Boolean VerifyXml()
{
string mystr = string.Empty;
mystr = "9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMTpuYW1laWQtZm9ybWF0OnVuc3BlY2lmaWVkIiBBbGxvd0NyZWF0ZT0idHJ1ZSIgLz48L3NhbWxwOkF1dGhuUmVxdWVzdD4=";
mystr = GetXmlFromSAML(mystr, false);
mystr = mystr.TrimEnd().TrimStart();
X509Certificate2 myCert = new X509Certificate2(Server.MapPath(".") + #"\X509Certificate\SP.cer");
XmlDocument Doc = new XmlDocument();
Doc.PreserveWhitespace = false;
Doc.XmlResolver = null;
Doc.LoadXml(mystr);
// Check arguments.
if (Doc == null)
throw new ArgumentException("Doc");
// Create a new SignedXml object and pass it
// the XML document class.
SignedXml signedXml = new SignedXml(Doc);
// Find the "Signature" node and create a new
// XmlNodeList object.
XmlNodeList nodeList = Doc.GetElementsByTagName("Signature");
// Throw an exception if no signature was found.
if (nodeList.Count <= 0)
{
throw new CryptographicException("Verification failed: No Signature was found in the document.");
}
// This example only supports one signature for
// the entire XML document. Throw an exception
// if more than one signature was found.
if (nodeList.Count >= 2)
{
throw new CryptographicException("Verification failed: More that one signature was found for the document.");
}
// Load the first <signature> node.
signedXml.LoadXml((XmlElement)nodeList[0]);
// Check the signature and return the result.
return signedXml.CheckSignature(myCert, false);
}
With above verification code I get exception "SignatureDescription could not be created for the signature algorithm supplied". I am not sure how I can have this signature verification working.
Is it really possible to manually verify the SAMLRequest signature with X509Certificate? Is it fine to allow the login check without signature verification of AuthnRequest?
I have been googling all these for last one month, but had no luck. Any help is much appreciated.

Restlet GWT in a Google Gadget

I am developing a GWT app for the Google Apps marketplace. I am using AppEngine with Restlet on the server side. Client side I use the GWT edition of Restlet. This is a great combination. I have my domain objects shared between client and server and as such no need for DTO's or proxies and so on. On the client side I can simply call Restlet resources :
CustomerResourceProxy customerResource = GWT.create(CustomerResourceProxy.class);
customerResource.getClientResource().setReference("/customer");
customerResource.retrieve(new Result<Customer>() { .... }
No need to parse the underlying XML or use JSNI to interpret incoming JSON.
BUT... part of the app is a GMAIL contextual gadget, and I cannot simply use the above code because all communication between a Gadget and the server must pass through GadgetsIO makeRequest.
So... just for the gadget, I will have to make the effort of parsing the XML or using JSNI to interpret the incoming JSON.
Is it überhaupt possible to hack the Restlet GWT client to pass all communication via GadgetsIO and what would it take ? Any pointers very welcome !
K.
I managed to get Restlet resources to work within a Gadget using GWT by making some changes to the Restlet GWT edition :
In GwtClientCall I replaced the standard GWT requestbuilder by the GadgetRequestBuilder (which will IoProvider.makeRequest), like this :
public GwtClientCall(GwtHttpClientHelper helper, String method, String requestUri, boolean hasEntity) {
super(helper, method, requestUri);
Reference requestRef = new Reference(requestUri);
if (requestRef.isRelative() || requestRef.getScheme().startsWith("http")) {
this.requestBuilder = new GadgetsRequestBuilder(method, requestUri);
this.requestBuilder.setTimeoutMillis(getHelper().getSocketConnectTimeoutMs());
this.responseHeadersAdded = false;
} else {
throw new IllegalArgumentException("Only HTTP or HTTPS resource URIs are allowed here");
}
}
In the gadgetsrequestbuilder, I had to make some changes so it would pass the headers in the request :
private GadgetsRequest doSend(String requestData, final RequestCallback callback) throws RequestException {
final RequestOptions options = RequestOptions.newInstance();
options.setMethodType(methodType);
if (requestData != null && requestData.length() > 0) {
options.setPostData(requestData);
}
options.setAuthorizationType(AuthorizationType.SIGNED);
options.setContentType(ContentType.DOM);
setHeaders(options);
final GadgetsRequest gadgetsRequest = new GadgetsRequest(getTimeoutMillis(), callback);
gadgetsRequest.setPending(true);
IoProvider.get().makeRequest(getUrl(), new ResponseReceivedHandler<Object>() {
public void onResponseReceived(ResponseReceivedEvent<Object> event) {
gadgetsRequest.fireOnResponseReceived(event, callback);
}
}, options);
return gadgetsRequest;
}
the gadget container by default strips the response headers, so i manually add the MediaType.APPLICATION_JAVA_OBJECT_GWT
#Override
public Series<org.restlet.client.engine.header.Header> getResponseHeaders() {
final Series<org.restlet.client.engine.header.Header> result = super.getResponseHeaders();
if (!this.responseHeadersAdded && (getResponse() != null)) {
Header[] headers = getResponse().getHeaders();
for (int i = 0; i < headers.length; i++) {
if (headers[i] != null) {
result.add(headers[i].getName(), headers[i].getValue());
}
}
result.add(HeaderConstants.HEADER_CONTENT_TYPE, MediaType.APPLICATION_JAVA_OBJECT_GWT.toString());
this.responseHeadersAdded = true;
}
return result;
}
A lot of dialogboxes for debugging later, it works :-)

Resources