swagger-ui shows 401 only at remote host

2,321 views
Skip to first unread message

gabrielp

unread,
Feb 14, 2015, 3:47:57 PM2/14/15
to swagger-sw...@googlegroups.com
Hi,

I also asked this at stackoverflow but got no answer yet (yes, I am a little bit impatient and yes, I am a little bit under pressure :)). 
I will double post my stackoverflow entry, if somebody does not want to visit the side.

I integrated swagger with swagger-ui into my Spring-based, REST-like, basic auth 'secured' service. Everything shows up and looks fine, but I cannot use the 'Try it out' button. I always get a "401 Unauthorized". I checked via the Chrome console and find that the "Authorization" header is not sent. 

Now to the main problem: This ONLY happens when I deploy the service to my remote server. On localhost everything works fine, swagger-ui sends the "Authorization" header and I can use the 'Try it out' button. 

My configurations:
CORSFilter

public class CorsFilter implements Filter {
   
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
   
HttpServletResponse response = (HttpServletResponse) res;
    response
.setHeader("Access-Control-Allow-Origin", "*");
    response
.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
    response
.setHeader("Access-Control-Allow-Headers", "Authorization");
    chain
.doFilter(req, res);
   
}
}

appServlet.xml
<default-servlet-handler />
<beans:bean class="com.mangofactory.swagger.configuration.SpringSwaggerConfig" />
<context:property-placeholder location="classpath:/swagger.properties" />
<resources location="classpath:swagger-ui/" mapping="/swagger-ui/**" />



swagger-ui index.html

if (url && url.length > 1) {
      url
= decodeURIComponent(url[1]);
} else {
      url
= "http://$REMOTE_SERVER:8080/myapp/api-docs";
}
...
function addApiKeyAuthorization() {
   
var key = $('#input_apiKey')[0].value;
    log
("key: " + key);
   
if(key && key.trim() != "") {
        log
("added key " + key);
        window
.authorizations.add("basic", new ApiKeyAuthorization("Authorization", "$MY_BASIC_AUTH_CODE", "header"));
   
}
 
}


Does anyone know why this happens? Via Google I only find the answer: enable CORS, add Authorization header, ... Yeah, I did that. But maybe wrong? I also tried it with PasswordAuthorization in swagger-ui's index.html (obviously with no success):

window.authorizations.add( "Basic", new PasswordAuthorization("Authorization", username, password))


as well as 

if (url && url.length > 1) {
  url
= decodeURIComponent(url[1]);
} else {
  url
= "http://localhost:8080/myapp/api-docs";
}


Thanks for any answer, I'll provide more information if needed.

swagger-ui version: develop_2.0, swgger-springmvc version: 0.9.5, Spring version: 3.2.2.RELEASE
Updating Spring is not feasable atm.

Tony Tam

unread,
Feb 14, 2015, 4:07:46 PM2/14/15
to swagger-sw...@googlegroups.com
Can you please update to master for swagger ui?  Note the window.authorizations must be set before initializing swagger ui. 

Can you share the swagger json created from the spring mvc server?


--
You received this message because you are subscribed to the Google Groups "Swagger" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

gabrielp

unread,
Feb 14, 2015, 4:42:30 PM2/14/15
to swagger-sw...@googlegroups.com
Thanks for the fast answer :)

I updated to the master branch. If I set 
if (url && url.length > 1) {
  url
= decodeURIComponent(url[1]);
} else {
  url
= "http://localhost:8080/myapp/api-docs";
}

then I get 
"Can't read from server. It may not have the appropriate access-control-origin settings."

With 
if (url && url.length > 1) {
  url
= decodeURIComponent(url[1]);
} else {
  url
= "http://$REMOTE_SERVER:8080/myapp/api-docs";
}

I still get the 401 (but only on the remote location).

Note the window.authorizations must be set before initializing swagger ui. 
How do I do that? I have to admit: I have no clue on how to properly use Javascript. 
The JSON-file (from GET /myapp/api-docs):
{"apiVersion":"1.0","apis":[{"description":"controller1_description","path":"/default/controller1","position":0},{"description":"Handles geofences of polls.","path":"/default/controller1","position":0},{"description":"controller2_description","path":"/default/controller1","position":0},{"description":"controller3_description","path":"/default/controller1","position":0}],"authorizations":{},"info":{"contact":"Contact Email","description":"Api Description","license":"Licence Type","licenseUrl":"License URL","termsOfServiceUrl":"Api terms of service","title":"default Title"},"swaggerVersion":"1.2"}

Ron Ratovsky

unread,
Feb 16, 2015, 8:08:36 AM2/16/15
to swagger-sw...@googlegroups.com
Can you share your index.html?

--
You received this message because you are subscribed to the Google Groups "Swagger" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
-----------------------------------------
http://swagger.io
https://twitter.com/SwaggerApi
-----------------------------------------

gabrielp

unread,
Feb 16, 2015, 9:12:24 AM2/16/15
to swagger-sw...@googlegroups.com
<!DOCTYPE html>
<html>
<head>
  <title>Swagger UI</title>
  <link href='css/typography.css' media='screen' rel='stylesheet' type='text/css'/>
  <link href='css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
  <link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
  <link href='css/reset.css' media='print' rel='stylesheet' type='text/css'/>
  <link href='css/screen.css' media='print' rel='stylesheet' type='text/css'/>
  <script type="text/javascript" src="lib/shred.bundle.js"></script>
  <script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script>
  <script src='lib/jquery.slideto.min.js' type='text/javascript'></script>
  <script src='lib/jquery.wiggle.min.js' type='text/javascript'></script>
  <script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
  <script src='lib/handlebars-2.0.0.js' type='text/javascript'></script>
  <script src='lib/underscore-min.js' type='text/javascript'></script>
  <script src='lib/backbone-min.js' type='text/javascript'></script>
  <script src='lib/swagger-client.js' type='text/javascript'></script>
  <script src='swagger-ui.js' type='text/javascript'></script>
  <script src='lib/highlight.7.3.pack.js' type='text/javascript'></script>
  <script src='lib/marked.js' type='text/javascript'></script>

  <!-- enabling this will enable oauth2 implicit scope support -->
  <script src='lib/swagger-oauth.js' type='text/javascript'></script>
  <script type="text/javascript">
    $(function () {
      var url = window.location.search.match(/url=([^&]+)/);
      if (url && url.length > 1) {
        url = decodeURIComponent(url[1]);
      } else {
      }
      window.swaggerUi = new SwaggerUi({
        url: url,
        dom_id: "swagger-ui-container",
        supportedSubmitMethods: ['get', 'post', 'delete', 'options'],
        onComplete: function(swaggerApi, swaggerUi){
          if(typeof initOAuth == "function") {
            /*
            initOAuth({
              clientId: "your-client-id",
              realm: "your-realms",
              appName: "your-app-name"
            });
            */
          }
          $('pre code').each(function(i, e) {
            hljs.highlightBlock(e)
          });
        },
        onFailure: function(data) {
          log("Unable to Load SwaggerUI");
        },
        docExpansion: "none",
        sorter : "alpha"
      });

      function addApiKeyAuthorization() {
        var key = $('#input_apiKey')[0].value;
        log("key: " + key);
        if(key && key.trim() != "") {
            log("added key " + key);
            window.authorizations.add("basic", new ApiKeyAuthorization("Authorization", "$MY_BASIC_AUTH_CODE", "header"));
        }
      }

      $('#input_apiKey').change(function() {
        addApiKeyAuthorization();
      });

      // if you have an apiKey you would like to pre-populate on the page for demonstration purposes...
      /*
        var apiKey = "myApiKeyXXXX123456789";
        $('#input_apiKey').val(apiKey);
        addApiKeyAuthorization();
      */

      window.swaggerUi.load();
  });
  </script>
</head>

<body class="swagger-section">
<div id='header'>
  <div class="swagger-ui-wrap">
    <a id="logo" href="http://swagger.io">swagger</a>
    <form id='api_selector'>
      <div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/></div>
      <div class='input'><input placeholder="api_key" id="input_apiKey" name="apiKey" type="text"/></div>
      <div class='input'><a id="explore" href="#">Explore</a></div>
    </form>
  </div>
</div>

<div id="message-bar" class="swagger-ui-wrap">&nbsp;</div>
<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
</body>
</html>


On Saturday, February 14, 2015 at 9:47:57 PM UTC+1, gabrielp wrote:

gabrielp

unread,
Feb 18, 2015, 2:21:09 PM2/18/15
to swagger-sw...@googlegroups.com
Hi,

so I just tried it again without changing anything (server was not messed with/ the app was not redeployed) and ... magic! Now it works. As this is magically working I expect it to fail again on random occasions. I'll just keep you updated, if it happens again. 

Thank you for your time.


On Saturday, February 14, 2015 at 9:47:57 PM UTC+1, gabrielp wrote:
Reply all
Reply to author
Forward
0 new messages