Specifying Oauth2 Redirect URI in SwaggerHub
Hello... I'm new to SwaggerHub and have been stuck on this issue for a while. I'm using an OAuth2.0 flow to allow client access to an AWS Cognito User Pool. In Cognito, client owners are able to configure multiple callback urls. This basically adds them to a whitelist of approved callback URLs (screenshot attached - though doesn't have to be localhost) - although the callback url must be specified when calling theauthorize (oauth2/authorize/) endpoint using the redirect_uri query parameter. It appears that this parameter is fixed when using the access code oauth2 security scheme. Is it at all possible to change this parameter via SwaggerHub? If so, can it also be made a configurable parameter? Thanks much.Solved2.8KViews0likes1CommentMissing a receive token call in the generated client
Hello, I have the following part for securityDefinition in my swagger 2.0 API definition: securityDefinitions: petstore_auth: type: "oauth2" tokenUrl: "http://petstore.swagger.io/oauth/dialog" flow: "password" scopes: write:pets: "modify pets in your account" read:pets: "read your pets" With this API definition I generate a C# API Client with the online Swagger Editor Tool. The generated client code does not include an API call to receive the token from the given Url "http://petstore.swagger.io/oauth/dialog". What am I missing here? Thanks in advance, DavidHow to define OAuth2 ClientCredentials flow with Header parameters and Query parameters
I have an API that is secured by OAuth2 client credentials flow. It takes 3 parameters and returns a token. 1. A subscription key in the header 2. Content type in the header 3. A query in the querystring. How do I define that in the swagger documentation? securityDefinitions: my_auth: type: "oauth2" tokenUrl: "https://mytokenURL/graphql" flow: "application" scopes: read:roster: "read your data" Where do I define that my tokenURL takes 3 parameters (2 in header and 1 in querystring)? Also my tokenURL works with HTTP POST, where can I define that?1.2KViews0likes0Commentsoauth2 authorization dynamic test automation through event handlers
Hi, I created below script, hope you can benefit from it as well... I am relatively new to soapui & test automation, have less then 1 year experience with it and had no previous relevant coding background, so perhaps this might not be 100% efficient... but it does what it needs to do (for me :-) ). First of all, there are already a lot of features within soapui that allow you to dynamically use authorization. At project level you have the "Auth Manager" tab. You can create different profiles and specify for which operations to use which profile. The get access token screens did allow me to authenticate and retrieve an access token, but then we wanted to include my soapui testcases into the build pipeline (via TestRunner.bat command line execution) and there the integrated browser would not work. Even the automation of the browser windows (via front end automation getElementById etc.) would probably not work. So I went with the following approach which gave me sufficient customization possibilities while staying within a generic framework. It makes use of the soapui pro featureRequestFilter.filterRequest within "event handlers". First off, I need a test suite that will go get my authentication tokens. I have several, for easy demonstration I include 2, an oauth2 token (with access & refresh token validity for several hours) and an openid token generation, without refresh, but with limited 1 hour validity. I have 1 test suite which I will run at the start of the project, called "_Authorization". This includes 2 test cases, 1) "oauth2" and 2) "openid". For the first I have following test steps: 1.Groovy script to determine whether token is expired. 2. A rest request to refresh the token (if needed) called "REST Request Refresh_Token". This request uses the parameters client_id, grant_type (refresh), client_secret & refresh_token. (note: before being able to use this I had to manually obtain an access & refresh token first through grant_type (obtain authorization code). After this manual step I can get a new access token via the refresh token request automatically) 3. A datasink to write the new token (access & refresh) to an excel, together with the new expiration date etc. (if needed) 4. A datasource test step. This is were the event handler will go get my oauth2 token to inject in all my other test cases. The second test case "openid" will use a few more steps: 1. DataSource where I have an excel with all my specific "numbers" for which I want to generate a specific openid token. I can provide also a claim via this excel (first name, last name also, might depend on your openid client). In contrary to the above oauth2; the authorization code will be specific for certain parameterized request (for instance request for specificclients, id's, organisation numbers, ...). These request will be authorized with different authentication profiles (claims) that determine who can see what. 2. A rest request test step called "token" to obtain the tokens. This request uses the parameters grant_type, code & redirect_uri. 3. A groovy test step to get and set the properties for each number from my datasource. So here the tokens used by my test cases would be retrieved from the properties within the soapui project. 4. A datasink to write the new token to an excel, together with the new expiration date etc. I write it to an excel file as it is easier to have an overview via an external file. 5. A datasource loop that points back to 2. See below the scripts for: oauth2 test step 1: import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import groovy.time.TimeCategory TimeZone.setDefault(TimeZone.getTimeZone('CET')) testRunner.runTestStepByName("DataSource_external file") def expirydate = context.expand( '${DataSource_external file#expiry_date}' ) Date now = new Date() //expiry date is in string format. We need to convert to Date DateFormat datumformaat = new SimpleDateFormat("EEE MMM d HH:mm:ss z yyyy", Locale.US) Date expirydate_convertedtodate = datumformaat.parse(expirydate) if (expirydate_convertedtodate > now) { log.info "Access Token not expired. We run only the last step called DataSource_external file. This way all requests using this oauth2 authorization will be able to insert this token."; testRunner.gotoStepByName("DataSource_external file") } else { testRunner.runTestStepByName("DataSource_external file") //log.info "Access Token expired! Run the entire test suite to retrieve a new access & refresh token. If this step would fail we need to run manually an obtain access & refresh token rest request." def refresh_token = context.expand( '${DataSource_external file#refresh_token}' ) def client_secret = context.expand( '${DataSource_external file#client_secret}' ) def old_access_token = context.expand( '${DataSource_external file#access_token}' ) // we store it at test case level so rest request step to get the refresh token can use it. testRunner.testCase.setPropertyValue("refresh_token", refresh_token); testRunner.testCase.setPropertyValue("client_secret", client_secret); currentDate = new Date() use( TimeCategory ) { expirydate_minus1hour = currentDate - 3600.seconds expirydate_plus16hours = currentDate + 57600.seconds } testRunner.testCase.setPropertyValue("expirydate", expirydate_plus16hours.toString()) //I included an if statement here as I use also an old access token to test I do not get authorized. Old means that it was refreshed more than 1 hour ago, otherwise it would still be valid if (expirydate_convertedtodate < expirydate_minus1hour) { log.info ("The old access token expired on "+expirydate_convertedtodate+", this is more than 1 hour ago ("+expirydate_minus1hour+"). So this one is no longer valid and we can write it to property old_access_token") testRunner.testCase.setPropertyValue("old_access_token_DOSIS", old_access_token); } else { log.info ("Old access token expired on "+expirydate_convertedtodate+", this is LESS than 1 hour ago ("+expirydate_minus1hour+"). So this one would actually be still valid, so we do NOT write it to property old_access_token") } } Groovy script OpenId step 3: import groovy.time.TimeCategory TimeZone.setDefault(TimeZone.getTimeZone('CET')) def expires_in = context.expand( '${#Project#expires_in}' ) currentDate = new Date() use( TimeCategory ) { expirydate_plus1hour = currentDate + 3600.seconds } def numberA= context.expand( '${DataSource_OpenId#numberA}' ) def firstname = context.expand( '${DataSource_OpenId#first name}' ) def lastname = context.expand( '${DataSource_OpenId#last name}' ) def claim = context.expand( '${DataSource_OpenId#claim}' ) def description= context.expand( '${DataSource_OpenId#description}' ) def token_response = context.expand( '${Token#Response#$[\'id_token\']}' ) log.info ("For property "+omschrijving+" with numberA \""+numberA+"\" we got following token (expires on: "+ expirydate_plus1hour + "): " +token_response) testRunner.testCase.testSuite.project.setPropertyValue ("authorization_"+description, token_response) return expirydate_plus1hour And now the big kicker. The RequestFilter.filterRequest piece of code: //event creates custom header for ALL requests (overwriting the Authorization header if it was already provided in the test steps). import java.util.ArrayList; import java.util.List; import java.util.regex.*; def headers = request.requestHeaders // test step variabelen ophalen def requestname = request.getName() def numberA = context.getProperty("numberA") def numberB = context.getProperty("numberB") // based upon the operation we use in the test steps we will inject another authorization header. So the event listens to the compiled request and will insert the authorization header BEFORE it submits it. String operation = request.getOperation() // first operation is the actual get access & refresh tokens from the authorization service (oauth2 and openid). There is no authorization header needed for these operations. We use test suite _Authorization to dynamically call the authoriztion service and // write the results to an external excel file if ( operation == "RestResource: /authorization/oauth2/token"|| operation == "RestResource: /authorization/openid/token" ) { headers.remove("Authorization"); request.requestHeaders = headers; log.info ("teststep "+ requestname + " concerns operation " + operation + " . This is an authentication request oauth2 or openid, so we do not need to insert an authorization header.") } else // GENERIC - string "(403)", "(401)" or "(_negative_)" in de test step name - we do not pass authorization! This way we can test the actual authorzation, to see we get a 401 or 403 http response code if ( requestname.contains("(403)")|| requestname.contains("(401)")|| requestname.contains("(_negative_)") ) { headers.remove("Authorization"); request.requestHeaders = headers; log.info ("teststep "+ requestname + " authenticion testcase. So we do not insert Authorization heade (capital A). It is possible to manually insert an authorization header (no capital A, so we can distinguish between automatical insertion or manual)") } else // depending on the rest resource endpoint operations, I can insert specific authorization headers. For instance, below operations do not have an input parameter. To be able to generically determine which openid token to insert for each rest request test step // we include in the test step name square brackets with between it the number for which we want to get the openid token, for instance [12345 ] will go and insert the authorziation header token for number 12345, generated in the _Authentication test suite. if ( operation == "RestResource: /api/v1/abc/{id}"|| operation == "RestResource: /api/v1/def" ) { if ( requestnaam.contains("[") ) { Matcher openid = Pattern.compile("(?<=\\[).+?(?=\\])").matcher(requestnaam) def token = context.expand( '${#Project#authorization_'+openid[0]+'}' ) // log.info ("name of the test step is: " + requestnaam +" - with operation: " +operation) // log.info ("In the requstname we have \'[" +openid[0] + "]\', so we inject the authorization OpenId header like geneated in the _Authorization test suite: " +token) headers.remove("Authorization"); headers.put("Authorization", "bearer "+token); request.requestHeaders = headers; } else //Attention, in case of no "[" in the request name we do a default openid authorization { def token = context.expand( '${#Project#authorization_default}' ) log.info ("name of teststep is: " + requestnaam +" - with operation: " +operation) log.info (Default openid authorization, \${#Project#authorization_default} die resulteert in deze OpenId Authorization header: " +token) headers.remove("Authorization"); headers.put("Authorization", "bearer "+token); request.requestHeaders = headers; } } else // In below operation we will have an input parameter for the request. We will read that one and automatically inject the matching openid authorization header we got from the _Authorization test suite. if ( operation == "RestResource: /api/getdata/numberA/{numberA}"|| operation == "RestResource: /api/getotherdata/numberA/{numberA}" ) { def token = ""; if (numberA != null) { token = context.expand( '${#Project#OpenIdToken_'+numberA+'_soapui_default}' ) log.info ("Name of the teststep is: " + requestname +" - with operation: " +operation) log.info ("From the request we get parameter number " +numberA + " which results in following openid token: " +token) headers.remove("Authorization"); headers.put("Authorization", "bearer "+token); request.requestHeaders = headers; } else { log.info "No numberA found in the request parameter, so the result would probably be a bad request (400)"; throw new Exception("No numberA found in the request parameter, so the result would probably be a bad request (400)"); } } else // DEFAULT - we insert another oauth authorization header (not openid) valid for most of my operations { def authorization_oauth = context.expand('${#[_Authentication#_Authentication#DataSource_external file]#authorization_REST}'); headers.remove("Authorization"); headers.put("Authorization",authorization_oauth); request.requestHeaders = headers; log.info ("Name of test step is: " + requestname +" - with operation: " +operation) log.info ("Default event handler applied: Trigger event Authorization header with the general oauth2 token, retrieved from external file: "+authorization_oauth) }2.8KViews1like0CommentsGetting Authorization code using private key JWT as client authenticatoin.
We are implementing UK open banking and authenticating client using JWS Client Assertion using a private key JWT. Post request to autorisation end point is send with signed JWT in body. It is then redirected to user authentication (username and password). Authorization code is recieved which then need to be exchanged with access token. Not able to achieve this using OAthu2 in soapui as there is no option to use signed JWT (in body). Also is it possible to get the access token is two step ? 1. Get authorizatio code by sending the signed JWT in the body 2. Exchange authorization code with access token1.7KViews0likes1CommentHow to test Google API request with Service Account
I am thinking of using service account as authorisation method of a request to Google API but unfortunately I haven't found a reference on how to do it with SOAP UI. Is there a possibility to achieve this or should I just stick to OAuth 2 Flow : Authorization Code Grant method? Thanks!995Views0likes0Commentsjava.lang.RuntimeException: Unable to refresh expired access token.
Hi all. I am trying to Automate the REST APIs (Services) that uses User Level Token Authentication using using Groovy Script and TestRunner.bat file in SoapUI. Groovy Script: where I am generating and hitting the request. NOTE: The below are passed as parameters to this method. strTestStepName, strPathforResp, profilename, respTimepath try { def authContainer = testRunner.testCase.testSuite.project.OAuth2ProfileContainer def profileName = context.expand( '${#Project#profileName}' ) def authProfile = authContainer.getProfileByName(profilename) def oAuthClientFacade = new OltuOAuth2ClientFacade() oAuthClientFacade.requestAccessToken(authProfile) Thread.sleep(1000) def accessToken = authProfile.getAccessToken() log.info accessToken def validate = testRunner.runTestStepByName(strTestStepName); resptime(validate,respTimepath); def httpResponseHeaders = context.testCase.testSteps[strTestStepName].testRequest.response.responseHeaders def strhttpStatus = httpResponseHeaders["#status#"].toString() strResponseXML = testRunner.testCase.testSteps[strTestStepName].testRequest.response.getContentAsString(); strResponseXML = strResponseXML.trim(); log.info strResponseXML fWriteToFile(strPathforResp+".txt",strResponseXML) //--> Writing Response to Local for Further validations } catch(Exception e) { log.info e.message; } The User Token is generated without any issues when I try it manually. But, when I try to run/generate the User Level Token via Groovy Script with TestRunner.bat, I am getting inconsistent Errors - Please see below. Instance#1: Error 2017-08-17 20:45:21,909 INFO [OAuth2RequestFilter] The access token has expired, trying to refresh it. 2017-08-17 20:45:22,586 ERROR [WsdlSubmit] Exception in request: java.lang.RuntimeException: Unable to refresh expired access token. 2017-08-17 20:45:22,587 ERROR [SoapUI] An error occurred [Unable to refresh expired access token.], see error log for details 2017-08-17 20:45:22,589 ERROR [errorlog] java.lang.RuntimeException: Unable to refresh expired access token. java.lang.RuntimeException: Unable to refresh expired access token. at com.eviware.soapui.impl.wsdl.submit.filters.OAuth2RequestFilter.reloadAccessToken(OAuth2RequestFilter.java:140) at com.eviware.soapui.impl.wsdl.submit.filters.OAuth2RequestFilter.filterRestRequest(OAuth2RequestFilter.java:68) at com.eviware.soapui.impl.wsdl.submit.filters.AbstractRequestFilter.filterAbstractHttpRequest(AbstractRequestFilter.java:41) at com.eviware.soapui.impl.wsdl.submit.filters.AbstractRequestFilter.filterRequest(AbstractRequestFilter.java:33) at com.eviware.soapui.impl.wsdl.submit.transports.http.HttpClientRequestTransport.sendRequest(HttpClientRequestTransport.java:172) at com.eviware.soapui.impl.wsdl.WsdlSubmit.run(WsdlSubmit.java:119) at com.eviware.soapui.impl.wsdl.WsdlSubmit.submitRequest(WsdlSubmit.java:79) at com.eviware.soapui.impl.rest.RestRequest.submit(RestRequest.java:192) at com.eviware.soapui.impl.wsdl.teststeps.RestTestRequestStep.run(RestTestRequestStep.java:794) at com.eviware.soapui.impl.wsdl.support.AbstractTestCaseRunner.runTestStep(AbstractTestCaseRunner.java:211) at com.eviware.soapui.impl.wsdl.support.AbstractTestCaseRunner.runTestStepByName(AbstractTestCaseRunner.java:200) at com.eviware.soapui.model.testsuite.TestCaseRunner$runTestStepByName.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116) at Script1.fRunandAPICResponse(Script1.groovy:113) at Script1$fRunandAPICResponse.callCurrent(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:153) at Script1.run(Script1.groovy:58) at com.eviware.soapui.support.scripting.groovy.SoapUIGroovyScriptEngine.run(SoapUIGroovyScriptEngine.java:92) at com.eviware.soapui.impl.wsdl.teststeps.WsdlGroovyScriptTestStep.run(WsdlGroovyScriptTestStep.java:141) at com.eviware.soapui.model.testsuite.TestStep$run.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120) at Script1.run(Script1.groovy:7) at com.eviware.soapui.support.scripting.groovy.SoapUIGroovyScriptEngine.run(SoapUIGroovyScriptEngine.java:92) at com.eviware.soapui.impl.wsdl.teststeps.WsdlGroovyScriptTestStep.run(WsdlGroovyScriptTestStep.java:141) at com.eviware.soapui.impl.wsdl.support.AbstractTestCaseRunner.runTestStep(AbstractTestCaseRunner.java:211) at com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner.runCurrentTestStep(WsdlTestCaseRunner.java:47) at com.eviware.soapui.impl.wsdl.support.AbstractTestCaseRunner.internalRun(AbstractTestCaseRunner.java:138) at com.eviware.soapui.impl.wsdl.support.AbstractTestCaseRunner.internalRun(AbstractTestCaseRunner.java:46) at com.eviware.soapui.impl.wsdl.support.AbstractTestRunner.run(AbstractTestRunner.java:129) at com.eviware.soapui.impl.wsdl.support.AbstractTestRunner.start(AbstractTestRunner.java:77) at com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase.run(WsdlTestCase.java:595) at com.eviware.soapui.tools.SoapUITestCaseRunner.runTestCase(SoapUITestCaseRunner.java:565) at com.eviware.soapui.tools.SoapUITestCaseRunner.runRunner(SoapUITestCaseRunner.java:397) at com.eviware.soapui.tools.AbstractSoapUIRunner.run(AbstractSoapUIRunner.java:204) at com.eviware.soapui.tools.AbstractSoapUIRunner.run(AbstractSoapUIRunner.java:139) at com.eviware.soapui.tools.AbstractSoapUIRunner.runFromCommandLine(AbstractSoapUIRunner.java:114) at com.eviware.soapui.tools.SoapUITestCaseRunner.main(SoapUITestCaseRunner.java:120) Caused by: org.apache.oltu.oauth2.common.exception.OAuthSystemException: org.apache.http.client.ClientProtocolException at org.apache.oltu.oauth2.httpclient4.HttpClient4.execute(HttpClient4.java:119) at org.apache.oltu.oauth2.client.OAuthClient.accessToken(OAuthClient.java:65) at org.apache.oltu.oauth2.client.OAuthClient.accessToken(OAuthClient.java:55) at com.eviware.soapui.impl.rest.actions.oauth.OAuth2TokenExtractor.refreshAccessToken(OAuth2TokenExtractor.java:192) at com.eviware.soapui.impl.rest.actions.oauth.OltuOAuth2ClientFacade.refreshAccessToken(OltuOAuth2ClientFacade.java:72) at com.eviware.soapui.impl.wsdl.submit.filters.OAuth2RequestFilter.reloadAccessToken(OAuth2RequestFilter.java:119) ... 42 more Caused by: org.apache.http.client.ClientProtocolException at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:822) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732) at org.apache.oltu.oauth2.httpclient4.HttpClient4.execute(HttpClient4.java:103) ... 47 more Caused by: org.apache.http.auth.MalformedChallengeException: Authentication challenge is empty at org.apache.http.impl.auth.RFC2617Scheme.parseChallenge(RFC2617Scheme.java:71) at org.apache.http.impl.auth.AuthSchemeBase.processChallenge(AuthSchemeBase.java:115) at org.apache.http.impl.auth.BasicScheme.processChallenge(BasicScheme.java:89) at org.apache.http.impl.client.DefaultRequestDirector.processChallenges(DefaultRequestDirector.java:1183) at org.apache.http.impl.client.DefaultRequestDirector.handleResponse(DefaultRequestDirector.java:1078) at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:482) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820) ... 50 more Instance#2: Error 2017-08-17 17:37:26,559 INFO [log] 2017-08-17 17:37:27,229 WARN [HttpClientSupport$SoapUIHttpClient] Authentication error: Unable to respond to any of these challenges: {bearer=WWW-Authenticate: Bearer} It would help if anyone could assist me in resolving this (or) let me know if there are any workarounds for this issue Note: Due to Security Reasons I cannot share the API details/project files here.1.7KViews0likes0CommentsPosting form values to a rest endpoint
I'm trying to POST to a REST endpoint, utilising a username and password (in order to be returned a token, for an OAuth2 Resource Owner flow). When I add the various form values required as parameters, I'm not seeing them in the body of the request sent.1.8KViews0likes4Comments