My team has just started creating RESTful services for data that has previously been handled by a large monolithic legacy application. We want to document the api with Swagger UI and I have set up with one problem.
I need to pass a SAML token as a header parameter, otherwise when we try to click on the "Try it out!" button I get a 401 Authentication error. How do I add a field to the Swagger UI so that someone can put a String for a SAML token to be sent in the request?
This is actually really easy. I saw references to the answer in the documentation but I didn't really understand what it was saying. There is a field at the top next to where your service URL goes and you can use that field to input a string to pass as a header value. That input field has an id of #input_apiKey.
Then in the index.html file you just add a line to the addApiKeyAuthorization() javascript function telling it to take the value of that field and pass it as whatever value you need.
Example:
function addApiKeyAuthorization(){
var key = $('#input_apiKey')[0].value;
if(key && key.trim() != "") {
swaggerUi.api.clientAuthorizations.add("samlToken", new SwaggerClient.ApiKeyAuthorization("samlToken", key, "header"));
swaggerUi.api.clientAuthorizations.add("Content-Type", new SwaggerClient.ApiKeyAuthorization("Content-Type", "application/json", "header"));
swaggerUi.api.clientAuthorizations.add("Accept", new SwaggerClient.ApiKeyAuthorization("Accept", "application/json", "header"));
}
}
$('#input_apiKey').change(addApiKeyAuthorization);
This sets the Content-Type and Accept headers to the same values for every request, and takes the value in that input field at the top of the page in the green header and sets it as my SAML token. So now if I paste in a valid SAML string my request works and I get data back!
I had a GWT servelt on whose doGet method, I created a cookie as shown below:
Cookie nameCookie = new Cookie("name","adam");
response.addCookie(nameCookie);
I tried to read this on the client side as
String name = Cookies.getCookie("name");
But the output of string variable name was coming out as undefined.
I solved it by finding out that while creating a cookie, you also have to set the path for it.
So in the server side,
Cookie nameCookie = new Cookie("name","adam");
nameCookie.setPath("/");
response.addCookie(nameCookie);
Now the following client side code returns the proper value as adam
String name = Cookies.getCookie("name");
I just found out that there is an existing default cookie name in Cookie before i actually adds my cookie name into it. That default cookie is JSESSIONID.
Collection<String> cookies = Cookies.getCookieNames();
for (String cookie : cookies) {
String cookieValue = Cookies.getCookie(cookie);
String[] itemMeaningIDcompanyMeaningID=cookie.split("_");
}
If i live the default cookie there, then i have a problem cos I need to convert cookie name into array so i may split the default cookie & that could cause runtime error.
i suspect that the default cookie is used for something else in GWT, so if i remove it then the system may not run properly.
So my question is, should i remove that default cookie or i just leave it there?
JSESSIONID is a cookie generated by the servlet container (like Tomcat or Jetty) and used for session management. You should leave it there unless you don't use sessions and don't plan to use them ever (which is rarely the case for any non trivial webapp).
I am using Apache CXF framework for my REST based service.
In the HTTPServletResponse, I am adding a cookie (using addCookie(Cookie cookie) method) but it is not being added successfully because, whenever I call the same API again, I couldn't see/use the added cookie.
I am using a REST client to call the API and I could see Set-Cookie header in the Respose Headers, but it is not being set.
What would be the problem here?
Well, the cookie is set actually.You will notice that further requests to your api carry the cookie along with them in the "Request Headers". To check the cookie, include the following code snippet in your Service Implementation:
In the implementation class, add the following annotation
#Context
private HttpHeaders headers;
Now, in the method of that class where you want to check the headers, add this code
if(headers.getRequestHeaders() != null) {
for(Entry<String, List<String>> entry : headers.getRequestHeaders().entrySet()) {
System.out.println("entry.getKey() >>>>>>>>>>> "+entry.getKey());
System.out.println("entry.getValue() >>>>>>>>>> "+entry.getValue());
}
}
Here, entry.getKey() will show you the header name and entry.getValue() will be showing a list of string values that this key is holding. If set, your cookie will appear under the header "cookie". I hope that helps.
Thanks.
How to add a parameters to the Google OAuth 2.0 redirect_uri?
Just like this:
redirect_uri=http://www.example.com/redirect.html?a=b
The b of a=b is random.
Anyone can help ?
You cannot add anything to the redirect uri, redirect uri is constant as set
in the app settings of Oauth.
eg :http://www.example.com/redirect.html
To pass several parameters to your redirect uri, have them stored in state
parameter before calling Oauth url, the url after authorization will send the same parameters to your redirect uri as
state=THE_STATE_PARAMETERS
So for your case,do this:
/1. create a json string of your parameters ->
{ "a" : "b" , "c" : 1 }
/2. do a base64UrlEncode , to make it URL safe ->
stateString = base64UrlEncode('{ "a" : "b" , "c" : 1 }');
This is a PHP example of base64UrlEncoding & decoding (http://en.wikipedia.org/wiki/Base64#URL_applications) :
function base64UrlEncode($inputStr)
{
return strtr(base64_encode($inputStr), '+/=', '-_,');
}
function base64UrlDecode($inputStr)
{
return base64_decode(strtr($inputStr, '-_,', '+/='));
}
So now state would be something like: stateString -> asawerwerwfgsg,
Pass this state in OAuth authorization URL:
https://accounts.google.com/o/oauth2/auth?
client_id=21302922996.apps.googleusercontent.com&
redirect_uri=https://www.example.com/back&
scope=https://www.google.com/m8/feeds/&
response_type=token&
state=asdafwswdwefwsdg,
For server side flow it will come along with token :
http://www.example.com/redirect.html?token=sdfwerwqerqwer&state=asdafwswdwefwsdg,
For client side flow it will come in the hash along with access token:
http://www.example.com/redirect.html#access_token=portyefghsdfgdfgsdgd&state=asdafwswdwefwsdg,
Retrieve the state, base64UrlDecode it, json_decode it, and you have your data.
See more about google OAuth 2 here:
http://code.google.com/apis/accounts/docs/OAuth2.html
Since the accepted answer does expose the actual data and misuses the state parameter instead of sticking to a nonce to protect against CSRF, I'll try to show a proper method. Rather than passing (read exposing) data it should be kept local. Hydrate it before the request and re-hydrate it after a validated request. "Validated" here means that the state-nonce of request and response match.
You need some kind of temporary client side storage. E.g. for SPA or general websites keep it in state or use the browser's localStorage, a session (or a signed cookie). For mobile apps they should use memory or any other local storage.
Before sending the request generate a nonce (see below) that will be used as state parameter for the request. Store the nonce together with the custom state (e.g. a json) in local storage.
For example, the nonce could be ih4f984hf and the custom state {"role": "customer"}. Then you could store data for re-hydration for that request like this:
"ih4f984hf": {
"role": "customer"
}
Then use only the nonce as value for the state parameter of the request. (If you absolutely want to combine the nonce and data into the state value be sure to encrypt it and be aware that the length of the value is limited!)
When receiving a response you get the value of the state parameter back. Look it up and if it matches the value in the local storage you may process the data using the stored state. If the nonces do not match the request is potentially from an attacker and should not be processed.
Generating the nonce
Remember that the nature of a nonce is that it is used once only and must be unpredictable! Unpredictable here means ideally random, but practically pseudo-random is ok if the entropry is high enough - in web apps you might want to check Web API Crypto which is supported pretty well.
For further readings this might be helpful:
http://www.thread-safe.com/2014/05/the-correct-use-of-state-parameter-in.html
https://datatracker.ietf.org/doc/html/draft-bradley-oauth-jwt-encoded-state-00
https://auth0.com/docs/protocols/state-parameters#set-and-compare-state-parameter-values
If you are in .NET you could save the parameters in the Session
HttpContext.Current.Session[{varname}]
and redirect to the authorization page without parameters
Response.Redirect(your_uri_approved_with_no_querystring_parameters);
In Javascript (Node), you could set the state property to an object of key value pairs.
const oAuth2Client = await new google.auth.OAuth2(
clientId: <clientId>,
clientSecret: <clientSecret>,
redirectUrl: <redirectUrl>,
);
return await oAuth2Client.generateAuthUrl({
access_type: "offline",
scope: <scopes>,
state: JSON.stringify({ a: "y", b: "z" }),
});
On google authorization complete, it returns of the state, code etc from ulr,
const params = JSON.parse(state); // { a: "y", b: "z" }
You can redirect parameter with url as below,
When you get response from google than you can pass parameter with url,
See below php code for same,
if (isset($_GET['code'])) {
$client->authenticate();
$_SESSION['token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL) . '?r=page/view');
}
In above example r=page/view is parameter on which i want the response with parameter