How to capture the SAML response of a request in which hidden SAML POST is present? - authentication

I would like to capture the SAML Response from a URL request made which uses hidden SAML authentication. I am able to see the response in Fiddler but how to save it for further analysis. Post the redirect request by the URL, SAML reponse with "200 OK" arrives in fiddler and I want to capture it. Is there any Powershell utility which can be used to do the same or Do I have to automate the Fiddler itself using some module. Please suggest if any other option is also there.
I have tried some snippets with "Invoke-WebRequest" in Powershell but not able to reproduce much regarding the SAML Response.

Tooting my own horn but my chrome plugin will help you with this. It adds a ta to the dev tools console. Then tabs show all traffic and highlights the ones wiyh saml messages. When you click one it will show you the saml xml in clear text nicely formated.

I have tried a lot of things and finally getting it almost done with the help of phantomjs.
var page = require('webpage').create();
page.customHeaders={'Authorization': 'Basic '+btoa('USER:PASSWORD')};
// hook into initial request
page.onResourceRequested = function(request) {
//console.log("Request: "+ JSON.stringify(request, undefined, 4));
var req_json = JSON.stringify(request, undefined, 4);
if (request.method == "POST" && request.postData != null){
//console.log("Request: "+ JSON.stringify(request, undefined, 4));
console.log("SAML Req/Resp: \n" + request.postData);
}
};
// hook to response
page.onResourceReceived = function(response) {
//console.log("Response: "+ JSON.stringify(response, undefined, 4));
var resp_json = JSON.stringify(response, undefined, 4);
};
page.open("https://yourURLwithhiddenSAML");
For now I am able to get the postdata with SAMLRequest and SAMLResponse and redirecting the output to some file. However, there is one more thing I have noticed. If I add
phantom.exit();
inside the function I am not able to get the complete request/response lifecycle which contains SAML.

Related

Getting A Refresh Token From Google Using An Authorization Token Posted in Java

I have read many posts, all the Google documentation I can find and tried many iterations of the following and still can't get an access and refresh token. I do get an authorization code but can't seem to get that to trade for the access and refresh tokens.
if(authCode == null || authCode.equals("")) {
String url = "https://accounts.google.com/o/oauth2/v2/auth?"
+ "scope=https://mail.google.com/&"
+ "response_type=code&"
+ "redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&"
+ "client_id=" + clientId +
"&access_type=offline";
URI uri = new URI(url);
logger.debug("URI for auth is: " + uri);
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
Desktop.getDesktop().browse(uri);
}
}
else {
logger.debug("Refreshing");
initRefreshToken();
}
With that, I get an access code I can cut and paste (just testing and trying to get this to work first) in my properties to get the refresh and access token.
In the initRefreshToken() method, the source is like this:
if(refreshToken.equals("")) {
logger.debug("Getting refresh token");
HttpPost post = new HttpPost("https://oauth2.googleapis.com/token");
// add request parameter, form parameters
List<NameValuePair> urlParameters = new ArrayList<>();
urlParameters.add(new BasicNameValuePair("code", authCode));
urlParameters.add(new BasicNameValuePair("client_id", clientId));
urlParameters.add(new BasicNameValuePair("client_secret", clientSecret));
urlParameters.add(new BasicNameValuePair("redirect_uri", "http://localhost:8000/"));
urlParameters.add(new BasicNameValuePair("grant_type", "authorization_code"));
try {
post.setEntity(new UrlEncodedFormEntity(urlParameters));
System.out.println("***** URL: " + urlParameters);
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = httpClient.execute(post);
System.out.println(EntityUtils.toString(response.getEntity()));
}
If this is a second or subsequent time using the code, what will be printed is:
Refersh token:
***** URL: [code=4/1AY0e-g..., client_id=370...i1h2u1s.apps.googleusercontent.com, client_secret=bAOH..., redirect_uri=https://localhost:8000/, grant_type=authorization_code]
{
"error": "invalid_grant",
"error_description": "Bad Request"
}
If the code is run and it's the first time using an authentication code, it will print:
{
"error": "redirect_uri_mismatch",
"error_description": "Bad Request"
}
I read in the Google console that exceptions are made for localhost domains so there's no need to register them. However, if there were a need to register them, it won't let you register them anyway as a domain must be a top level domain you own in order to register it. Therefore, how do I register localhost and/or exchange an authorization code for an access and refresh token in Java?
Thank you for your help.
DaImTo provided a great video about this and in that video and the blog post associated with it, the redirect_uri is listed correctly as: "urn:ietf:wg:oauth:2.0:oob". I didn't find this in the documentation but when I added it to my source code, I got access and refresh tokens as a response. Thank you very much for that help, DaImTo.

403 access denied to the website with proper login/pass through google script

var url = "https://web-site_name/page/?format=json&var_data-organization_dates&xlsexport=true";
var payload =
{
"login" : "login",
"password" : "pass",
};
var options =
{
"method" : "post",
"payload" : payload,
"followRedirects" : false
};
var login = UrlFetchApp.fetch("https://web-site_name/page/" , options);
var sessionDetails = login.getAllHeaders()['Set-Cookie'];
Logger.log(login.getAllHeaders());
here is the part of the code I try to use, to automate export of the data from web-site, i do have proper login and password and able to download file in json (opened in xsl) manually, I've got the address to the downloaded file in network in developer tools, but i have a problem on the first stage - when trying to authorize to the web-site - access denied. I've tried the code, given in answers on stackoverflow, but it still doesn't work.
How to make an url fetch request correctly, depends on the website you want to access and the authentication they uses
In the simplest case, your website requires HTTP basic authentification, in this case the correct syntax would be
var authHeader = 'Basic ' + Utilities.base64Encode(login + ':' + pass);
var options = {
headers: {Authorization: authHeader}
}
If your website uses a different authentication form, you might need to provide an access token.
In any case: the authentication credentials go into headers, not into payload!
payload is the data that you want to post = upload to the website.
If you want export data from the website - that is download data - you do not need a payload and the correct method would be get, not post. Btw., if the method is get, you do not need to specify it.
Please see here for more information and samples.

How can I read the LtpaToken2 token from my XMLHttpRequest response?

I'm trying to debug another developers code which looks like this:
xhr.open("POST", url, true, this.state.userid, this.state.password);
xhr.withCredentials = true;
xhr.onload = () => {
console.log("here is our packet " + JSON.stringify(xhr));
if (xhr.status === 200) {
var test = xhr.getAllResponseHeaders();
var respoheader = JSON.stringify(xhr.responseHeaders);
var token = respoheader.substring(
respoheader.indexOf("LtpaToken2"),
respoheader.indexOf(
";",
respoheader.indexOf("LtpaToken2")
)
);
console.log("token is parsed ===" + token);
When I run this query from Postman I see two "Set-Cookie" headers added to the response, and one has the content "LtpaToken2=YpMnhu...", which is apparently what I need to grab. But when I run the code above, it does not include this header. I apparently need to grab this token for future calls to another API.
Can someone explain what I'm doing wrong? How can I capture this token, or how am I supposed to connect to another API without this token? As it seems to always be the case with IBM tech, I can find almost ZERO documentation about LtpaTokens.

Using Node JS to proxy http and modify response

I'm trying to write a front end to an API service with Node JS.
I'd like to be able to have a user point their browser at my node server and make a request. The node script would modify the input to the request, call the api service, then modify the output and pass back to the user.
I like the solution here (with Express JS and node-http-proxy) as it passes the cookies and headers directly from the user through my site to the api server.
proxy request in node.js / express
I see how to modify the input to the request, but i can't figure out how to modify the response. Any suggestions?
transformer-proxy could be useful here. I'm the author of this plugin and I'm answering here because I found this page when looking for the same question and wasn't satisfied with harmon as I don't want to manipulate HTML.
Maybe someone else is looking for this and finds it useful.
Harmon is designed to plug into node-http-proxy https://github.com/No9/harmon
It uses trumpet and so is stream based to work around any buffering problems.
It uses an element and attribute selector to enable manipulation of a response.
This can be used to modify output response.
See here: https://github.com/nodejitsu/node-http-proxy/issues/382#issuecomment-14895039
http-proxy-interceptor is a middleware I wrote for this very purpose. It allows you to modify the http response using one or more transform streams. There are tons of stream-based packages available (like trumpet, which harmon uses), and by using streams you can avoid buffering the entire response.
var httpProxy = require('http-proxy');
var modifyResponse = require('http-proxy-response-rewrite');
var proxy = httpProxy.createServer({
target:'target server IP here',
});
proxy.listen(8001);
proxy.on('error', function (err, req, res) {
res.writeHead(500, {
'Content-Type': 'text/plain'
});
res.end('Something went wrong. And we are reporting a custom error message.');
});
proxy.on('proxyRes', function (proxyRes, req, res) {
modifyResponse(res, proxyRes.headers['content-encoding'], function (body) {
if (body && (body.indexOf("<process-order-response>")!= -1)) {
var beforeTag = "</receipt-text>"; //tag after which u can add data to
// response
var beforeTagBody = body.substring(0,(body.indexOf(beforeTag) + beforeTag.length));
var requiredXml = " <ga-loyalty-rewards>\n"+
"<previousBalance>0</previousBalance>\n"+
"<availableBalance>0</availableBalance>\n"+
"<accuruedAmount>0</accuruedAmount>\n"+
"<redeemedAmount>0</redeemedAmount>\n"+
"</ga-loyalty-rewards>";
var afterTagBody = body.substring(body.indexOf(beforeTag)+ beforeTag.length)+
var res = [];
res.push(beforeTagBody, requiredXml, afterTagBody);
console.log(res.join(""));
return res.join("");
}
return body;
});
});

Backbone.js and user authentication

I have been wondering for quite a while how I would go about authenticating users using Backbone because I have been reading a few articles about it and a lot of them are talking about tokens and keys.. But I just want to be able to sign in a user and register a user like you would normally.
I was thinking that on the web app start up there would be a request to the route '/me' and then the server gives the user back appropriate information if he/she is logged in.
Like if the route came back with {loggedIn: false} the backbone router would send the user to the login/register pages only. But if it came back with a users profile information then it would obviously mean he had a session.
Is this an okay way of going back user authentication when using Backbone?
Short answer: wire up $.ajax to respond to 401 (Unauthorized) status codes.
Long answer: We're consuming a RESTful api from a single page website. when the server detects an unauthorized request, it just returns a 401. The client will redirect to /login?#requested/resource.
/login will prompt for authorization (redirect to google's oath server in our case) then add an authorization cookie and redirect to the originally requested #requested/resource
we're also sending the auth cookie on every $.ajax request.
Hopefully this is helpful.
define(
[
'jquery',
'jquery.cookie'
],
function ($) {
var redirectToLogin = function () {
var locationhref = "/login";
if (location.hash && location.hash.length > 0) {
locationhref += "?hash=" + location.hash.substring(1);
}
location.href = locationhref;
};
var $doc = $(document);
$doc.ajaxSend(function (event, xhr) {
var authToken = $.cookie('access_token');
if (authToken) {
xhr.setRequestHeader("Authorization", "Bearer " + authToken);
}
});
$doc.ajaxError(function (event, xhr) {
if (xhr.status == 401)
redirectToLogin();
});
});