Access ServiceNow API which is okta Enabled - okta

I would like to get list of all Incidents which are in "Awaiting caller feedback State" in ServiceNow. Our servicenow is Okta enabled.
Can you please let us know how can I access Servicenow API which is Okta enabled.

The ServiceNow REST Api uses basic authentication by default. This is separate from the authentication method used to login users. You should be able to use the default example to make a call without worrying about Okta. Here's their Python example:
#Need to install requests package for python
import requests
# Set the request parameters
url = 'https://instance.service-now.com/api/now/table/problem?sysparm_limit=1'
# Eg. User name="username", Password="password" for this code sample.
user = 'username'
pwd = 'password'
# Set proper headers
headers = {"Accept":"application/xml"}
# Do the HTTP request
response = requests.get(url, auth=(user, pwd), headers=headers)
# Check for HTTP codes other than 200
if response.status_code != 200:
print('Status:', response.status_code, 'Headers:', response.headers, 'Error Response:', response.content)
exit()
# Decode the XML response into a dictionary and use the data
print(response.content)

Related

django-rest-framework using HttpOnly Cookie

After using djangorestframework-jwt in an unsafe way for over year I've finally decided that I would like to get it working in a safer fashion.
I've read everywhere that is not good to save a JWT token in the local client (for example, local storage) and that the best solution is to use HttpOnly cookies instead.
I understood that an HttpOnly cookie is a cookie indeed, that can be saved but not read by the browser. So I thought it could be used like the following:
get_token: the client requests an authorization token to the server by sending user and password: if user and password are valid the server responds with an httpOnly cookie that can be stored but not read by the client.
Every request the client does from now on are authorized because inside the HttpOnly cookie there is a valid authorization token.
refresh_token: once the client needs to refresh the token, it only needs to request a refresh_token: if the sent cookie contains a valid token, the server will respond with an updated HttpOnly cookie with the new token.
I'm now trying to use djangorestframework-jwt by using HttpOnly cookie and the JWT_AUTH_COOKIE configuration seems to be the most fitting one:
You can set JWT_AUTH_COOKIE a string if you want to use http cookies in addition to the Authorization header as a valid transport for the token. The string you set here will be used as the cookie name that will be set in the response headers when requesting a token. The token validation procedure will also look into this cookie, if set. The 'Authorization' header takes precedence if both the header and the cookie are present in the request.
Default is None and no cookie is set when creating tokens nor accepted when validating them.
After giving a string value to JWT_AUTH_COOKIE I received an httpOnly cookie as expected.
The problem:
When I call refreshToken I get the following response:
{"token":["This field is required."]}
True, I'm not sending any token in the request's HEADER and that is what I want since the client isn't supposed to keep it saved anywhere.
And that is where I'm getting confused:
If i'm not wrong from now on every request the client does to the server, the cookie should be added to the request.
Shouldn't the server check the cookie after it sees that no token has been passed in the Header? How is it supposed to work if not like this?
Also posted a Github issue here if anyone wants to contribute for improvements: https://github.com/jpadilla/django-rest-framework-jwt/issues/482
The issue that you observe is correct as the refresh token api has not been implemented with the cookies.
This could be a bug in the code itself. But nothing restrict you from fixing this issue.
You can patch the view to take care of cookie based auth as well. Add below code to the top of your urls.py and it will take care of the same
from rest_framework_jwt.settings import api_settings
if api_settings.JWT_AUTH_COOKIE:
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework_jwt.serializers import RefreshJSONWebTokenSerializer
from rest_framework_jwt.views import RefreshJSONWebToken
RefreshJSONWebTokenSerializer._declared_fields.pop('token')
class RefreshJSONWebTokenSerializerCookieBased(RefreshJSONWebTokenSerializer):
def validate(self, attrs):
if 'token' not in attrs:
if api_settings.JWT_AUTH_COOKIE:
attrs['token'] = JSONWebTokenAuthentication().get_jwt_value(self.context['request'])
return super(RefreshJSONWebTokenSerializerCookieBased, self).validate(attrs)
RefreshJSONWebToken.serializer_class = RefreshJSONWebTokenSerializerCookieBased
I've added this middleware to my Django (3.1):
class YankTokenRefreshFromHeaderIntoTheBody(MiddlewareMixin):
"""
for Django Rest Framework JWT's POST "/token-refresh" endpoint --- check for a 'token' in the request.COOKIES
and if, add it to the body payload.
"""
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
return response
def process_view(self, request, view_func, *view_args, **view_kwargs):
if request.path == '/v1/token-refresh' and 'token' in request.COOKIES:
data = json.loads(request.body)
data['token'] = request.COOKIES['token']
request._body = json.dumps(data).encode('utf-8')
return None
Then I added it here in my settings:
MIDDLEWARE = [
'myproj.utils.middleware.YankTokenRefreshFromHeaderIntoTheBody',
...
...
]
And that's it. Django REST framework JWT's token-refresh endpoint will now work as it will find the 'token' key/value in there.
Few things to note:
I chose 'token' as the name of the cookie holding tte JWT token. Yours may vary of course.
I changed the endpoint's name to /v1/token-refresh -- You'd need to change that too if you are using the original named endpoint.

API Gateway custom authorizer

I'm new to API Gateway. I try to use the "custom authorizer". I followed below document and used sample code that website provided.
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html
The "Lambda Authorizer of the TOKEN type" is work.
curl -v -H 'x-custom-auth: xxxxx" https://xxxxx.execute-api.us-west-1.amazonaws.com/Prod/
For the "Lambda Authorizer of the REQUEST type", I can input header, queryValue1, stageValue1 and accountId for testing via aws console.
But...
I'm confused about the "request type" and did not know how to pass the queryValue1, stageValue1 and accountId to API Gateway.
Can anyone help me to figure it out?
Regardless of which type of Authorizer you use, API Gateway will receive the same headers and parameters that you originally sent.
Your Authorizer cannot modify the original request details (but it include an auth context which API Gateway can also read).
In the example you're referencing:
if (headers.HeaderAuth1 === "headerValue1"
&& queryStringParameters.QueryString1 === "queryValue1"
&& stageVariables.StageVar1 === "stageValue1"
&& requestContext.accountId === "123456789012") {
callback(null, generateAllow('me', event.methodArn));
} else {
callback("Unauthorized");
}
What they're saying is that the REQUEST authorizer is expecting specific values in the request object:
If all the values match, the authorizer will Allow the request to continue. API Gateway will receive the same request object (with all the same parameters).
If not all the values match, the authorizer will Deny the request returning 403 Unauthorized; API Gateway will not receive the request.
Each of the properties in the example are sourced in the following ways:
AccountId is set automatically by AWS
StageVar1 comes from the deployed API's stage settings (API Name > Stages > Stage Name > Stage Variables)
HeaderAuth and QueryString1 are sent by the HTTP client (e.g. curl)

I am sending a valid PUT request to the GitHub API, but GitHub is not merging my pull request

Please ignore the ugly Ruby code, it's only here for illustration purposes of my attempt to merge a pull request using the GitHub API.
def merge_pull_request(github_profile_name, repo_name, pull_request_number, personal_access_token)
uri = URI("https://api.github.com/repos/#{github_profile_name}/#{repo_name}/pulls/#{pull_request_number}/merge?personal_access_token=#{personal_access_token}")
Net::HTTP.start(uri.host, uri.port,
:use_ssl => uri.scheme == 'https') do |http|
request = Net::HTTP::Put.new uri
response = http.request request # Net::HTTPResponse object
puts response.body
end
end
When I input in the correct parameters though, this is the response I get:
{"message":"Not Found","documentation_url":"https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-button"}
What happened?
The GitHub API's response is misleading. What is actually going on is that my personal access token is not authorized to merge pull requests. This was a silly error on my part...my personal access token was only authorized specifically for "user scope", but I forgot to click on the checkbox for the "repo scope". "Scopes" are how GitHub defines whether you have access to a specific field (such as the ability to control a User's profile or to merge a Pull Request), and so it is very essential to manage your personal access token's scopes properly if you want GitHub API to behave.
You can access profile information about your personal access token by going into Settings -> Personal Access Token, and then edit your Personal Access Token to grant and revoke "scopes".

JSON interaction after OAuth2/OmniAuth authentication

Context: I'm trying to interact with Twitter via JSON and no libraries as i'm practicing to interact with a newly released receipt printer(themprinter.com) which has no helper libraries. I need to OAuth with the printer then make the appropriate calls to register my device, print, verify online/offline status etc.
I've successfully authenticated with Twitter via OmniAuth's Twitter Gem. I can pull all the data from the Authentication Hash here - https://github.com/arunagw/omniauth-twitter
...now what? I want to be able to make a JSON call with my OAuth credentials to Twitter and pull my timeline or any other such data. Can anyone provide any sample code that will allow me a starting point to tinker with and work off of?
Twitter provides REST API. Here's how you might create a GET REST request
request = Net::HTTP::Get.new(url, initheader = header)
http_request = Net::HTTP.new(host, port)
response = http_request.start {|http| http.request(request)}
here's an example of the request URL:
https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=twitterapi&count=2

How to control a cisco IP-Phone from the CLI?

I've a Cisco IP-Phone 7945 and I want to control it from my CLI. For example I want to start a command like
call start 12345 #12345 is the number I want to call
or
call cancel
Anybody knows a tool or something similiar?
I'm writing a rails app and I want to start a call from within the app after a certain action.
The 7945 has a web interface that permits execution of commands, including a "Dial" command, by authenticated users.
Your rails app would connect to the phone at http://phone-ip-address/CGI/Execute and POST some XML that looks like this:
<CiscoIPPhoneExecute>
<ExecuteItem URL="Dial:12345" />
</CiscoIPPhoneExecute>
The authentication is done with HTTP Basic Auth and the back-end authenticator is determined by what phone system your 7945 is connected to. If Cisco Call Manager, it uses the assigned Call Manager user information.
Look for the IP Phone Services guides on cisco.com for details. Quick links:
HTTP Requests and Header Settings
CiscoIPPhone XML Objects
Internal URI Features
Short answer: it's not a CLI but it is straightforward to program a dialer by interacting with the phone over HTTP.
I know this is an old thread, but thought I'd post this working code example in Ruby. Tested on the CP-8941 phone. Username & password schemes will vary. Our system is set up to interface to Active Directory, so the username and password are those of our Windows login.
require "net/http"
require "uri"
phone = "ip-of-your-phone"
user = "your-username-goes-here"
secret = "your-password-goes-here"
prefix = "91"
todial = "number-to-dial-goes-here"
uri = URI.parse("http://#{phone}/CGI/Execute")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri)
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri)
request.basic_auth(user, secret)
request.set_form_data({"XML" => %(<CiscoIPPhoneExecute><ExecuteItem URL="Dial:#{prefix}#{todial}" /></CiscoIPPhoneExecute>) })
response = http.request(request)

Resources