We have our development website password protected with htaccess and htpasswd. We have REST API on our dev website and we are able to bypass the password protection when we are not using any authorization header by passing the username and password as Basic Auth Type. Please check the below screenshot
Postman Authorization Type
However, we are having few other APIs as well where we need to pass the bearer(token) as authorization header. In this case we are not able to pass multiple authorization header for both htaccess password and token.
Is there a way we can pass both the htaccess authorization header as well as the API authorization header? Or can we bypass password protection only for API calls and not for the website?
For additional information, we are using Apache/2.4.28.
Thanks
Super old question, but I just ran into this issue and figured out you can combine the Basic Auth and the Bearer Token into 1 Authorization call.
This is how I did it with Postman:
Create the Basic Auth to get past your htaccess pw:
Go to the Headers section and copy the Hashed Basic Auth Value:
Still in Headers add a new Authorization Key. For the Value add your copied Basic Auth Hash and then your Bearer token. Should look like this:
Basic dGVhbToxxxXXXxxxXx== Bearer 2|XDIrp...wqhKCzvOpK
Now go back to the Authorization Tab (Step 1) and Change the Basic Auth back to Inherit Auth from parent
The final Header should look like this:
Now you can get through the htaccess and authenticate your Api route with the bearer token.
If you use postman basic authentication with username add password it will bypass the htaccess.
If you using through code, encode your "username:password" using base64 and pass it in the headers as,
'Authorization': "Basic BASE64ENCODE"
Related
When I send request with Postman and check response header I can see this:
When I try with old PAT I created, or with OAuth token after validation (I created app and validated user with OAuth flow from my DB, so I used this token in Postman just to check) to call GitHub REST API like this: https://api.github.com/repos/djordjeviclazar/rep/branches
and set access_token in header like in documentation, I can see in headers X-RateLimit-Limit is 60, and I could see that X-RateLimit-Remaining is less than 60.
From documentation:
For API requests using Basic Authentication or OAuth, you can make up to 5,000 requests per hour.
Authenticated requests are associated with the authenticated user, regardless of whether Basic Authentication or an OAuth token was used. This means that all OAuth applications authorized by a user share the same quota of 5,000 requests per hour when they authenticate with different tokens owned by the same user.
So I guess that means I can't make more tokens and expect more than 5000 requests per hour, but why only 60, why API treats my requests as anonymous? Also I think that Search API is more limiting. What is the right way to access GitHub REST API?
The issue is that this call is not authenticated since you've specified:
Add To Headers
Key: access_token
Value: {{PAT}}
It will add an HTTP header with the following value: access_token: [PAT value] which is not processed by Github.
Checkout the headers sent in the headers tab it should print Authorization: Token YOUR_TOKEN or Authorization: Bearer YOUR_TOKEN
The following configuration will work correctly:
Add To Headers
Key: Authorization
Value: Token {{PAT}} (also Bearer {{PAT}} works)
You can also use Authorization of Type Bearer Token which is the same as Bearer XXXX:
Also, you can also disable Authorization (to the value No), and in the headers, just append the Authorization header:
Note that the usage of access_token in the url query parameters has been deprecated since end 2019
I am using POSTMAN to test OAuth2.0 AuthCode flow for MSGraph. Following are details of the same:
AuthCode URL : https://login.microsoftonline.com/{tenant_id}/oauth2/authorize
AccessToken URL : https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token
When i did some research to see how to test OAuth2.0 using POSTMAN. I was able to find some threads which helped me to generate the access token and hit the user profile api to get the user details as shown in the screenshot below:
But, i have a weird requirement where in, i would like to generate an AuthCode in a separate request, then use it in another request to get the Access Token and then use the access token to get the user details in a separate request.
Can someone please help me with the Above requirement.
You can first request the authorization code in your browser:
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id={your-client-id}
&response_type=code
&redirect_uri=https://localhost:4500/web/completeoauth/ms
&response_mode=query
&scope=https://graph.microsoft.com/mail.read
&state=12345
Then use the authorization code to request the token in postman:
Update:
If you don’t want to use a browser, just don’t check the Authorize using browser checkbox, and then set the Callback URL to your Redirect URIs. When you request a token, it will prompt you to log in.
After you log in,it will return the access token directly to you.But you will not see the code, this is because the system directly exchanges your code for token and returns it to you.
In Postman, in the test tab of the first request, you need to store the AuthCode in an environment variable: pm.environment.set("authCode", authCode).
You then can use that in the pre-request script of the next request via pm.environment.get("authCode") or in the headers or as url parameter: {{authCode}}.
I'm using Ember.js and Node. I already have json web token based authentication set up and am now trying to use LinkedIn's REST API to get information for my user profiles.
I'm able to redirect my users to the LinkedIn authorization code endpoint (Step 2 in this guide: https://developer.linkedin.com/docs/oauth2), but I'm getting stuck on Step 3 (Exchange Authorization Code for Access Token). When I make the POST request with the correct parameters, I get a 401 unauthorized_client error no matter how I try and make the request.
I'm making the request directly from my Node server, and using the request module. I've tried including the params as query params, and as part of the body. I've tried adjusting the headers and the url encoding but nothing seems to change the 401 error.
This is the call I need to be making according to the guide:
POST /uas/oauth2/accessToken HTTP/1.1
Host: www.linkedin.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=987654321&redirect_uri=https%3A%2F%2Fwww.myapp.com%2Fauth%2Flinkedin&client_id=123456789&client_secret=shhdonottell
This should not happen if you are POSTing the correct parameters. You can rather try it with an alternative way. With the authorization code you received in Step 2, use request based service like POSTMAN and try getting the response again. If you get it using that it means there has been some error while you are making the request.
Make sure to properly provide the headers.
Even after the POSTMAN service if you get an unauthorized response, confirm your client_id and client_secret.
Please note that for 2-legged authentication, the grant_type should always be "client_credentials". Also, you only need to supply the client_id and client_secret as parameters, nothing more. See the sample in the LinkedIn documentation. It looks like you try to do a 3-legged authentication request.
I am currently looking for a way to secure a REST API using token based authentication. I am developing the API in Python using Flask and have discovered the flask-security extension which seems to have a lot of interesting features.
One of the features mentioned in the documentation is Token Authentication.
According to the documentation:
Token based authentication is enabled by retrieving the user auth
token by performing an HTTP POST with the authentication details as
JSON data against the authentication endpoint. A successful call to
this endpoint will return the user’s ID and their authentication
token. This token can be used in subsequent requests to protected
resources.
I am however still a bit confused on how to implement this feature using flask-security.
Some online research has led me to using things such as #auth_token_required but I am having some trouble to put everything together. The flask-security documentation itself is not very helpful.
For example, how can a user get an authentication token? what is the authentication endpoints?
It would be great if you could lead me in the right direction. Code examples would be awesome too :-)
Endpoint is /login, you post your credentials as json request body:
{'email':'john#smit.com', 'password':'1234'}
However for this to work you need to disable the csrf tokens in your flask app (thanks Mandar Vaze):
app.config['WTF_CSRF_ENABLED'] = False
Then you do each request with the token in the HTTP headers:
Authentication-Token:WyI1NTE1MjhmNDMxY2Q3NTEwOTQxY2ZhYTgiLCI2Yjc4NTA4MzBlYzM0Y2NhZTdjZjIxNzlmZjhiNTA5ZSJd.B_bF8g.t1oUMxHr_fQfRUAF4aLpn2zjja0
Or as query string:
http://localhost:5000/protected?auth_token=WyI1NTE1MjhmNDMxY2Q3NTEwOTQxY2ZhYTgiLCI2Yjc4NTA4MzBlYzM0Y2NhZTdjZjIxNzlmZjhiNTA5ZSJd.B_bF8g.t1oUMxHr_fQfRUAF4aLpn2zjja0
Client example in python 3:
import requests
import json
#do the login
r = requests.post('http://localhost:5000/login',
data=json.dumps({'email':'john#smit.com', 'password':'1234'}),
headers={'content-type': 'application/json'})
response = r.json()
print(response) #check response
token = response['response']['user']['authentication_token'] #set token value
#Now you can do authorised calls
r = requests.get('http://localhost:5000/protected',
headers={'Authentication-Token': token})
print(r.text)
Angular example snippet to obtain the token:
$http.post('/login', {"email": $scope.formdata.login,"password":$scope.formdata.password}).
success(function(results) {
$window.sessionStorage.token = results.response.user.authentication_token;
});
Angular example snippet to visit protected pages:
if ($window.sessionStorage.getItem('token')) {
config.headers['Authentication-Token'] = $window.sessionStorage.getItem('token');
}
I found Flask-Security's token-based not a good candidate for my project. I recommend using JWT token instead.
The problems with Flask-Security's token based authentication.
Need to disable CSRF globally, this is not good when you also have a traditional web application in which CSRF token is desirable
No easy way to renew the token ( without submitting password again )
Can not control the payload of the token, there's no API to put/get data to/from the token
That token, by design, only works with one Flask app. So if your frontend app needs to talk with multiple restful apis, this wont work well
Check out JWT (pyjwt or flask-jwt) token, it solves all the above problems and more.
Authentication endpoint is /login
Look at the code of flask-security here specifically views.py: _render_json()
login() calls _render_json which in turn calls get_auth_token() - and returns the auth token.
Problem (for me) is to get this to work.
For me request.json seems empty (hence this does not work)
{"email": "test#example.com", "password": "test123"}
Hopefully this helps you move forward a little.
I am trying to understand the new OWIN Bearer Token authentication process in the Single Page App template in MVC 5. Please correct me if I'm wrong, for the OAuth password client authentication flow, Bearer Token authentication works by checking the http authorization request header for the Bearer access token code to see if a request is authenticated, it doesn't rely on cookie to check if a particular request is authenticated.
According to this post:
OWIN Bearer Token Authentication with Web API Sample
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
using (IdentityManager identityManager = _identityManagerFactory.CreateStoreManager())
{
if (!await identityManager.Passwords.CheckPasswordAsync(context.UserName, context.Password))
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
string userId = await identityManager.Logins.GetUserIdForLocalLoginAsync(context.UserName);
IEnumerable<Claim> claims = await GetClaimsAsync(identityManager, userId);
ClaimsIdentity oAuthIdentity = CreateIdentity(identityManager, claims,
context.Options.AuthenticationType);
ClaimsIdentity cookiesIdentity = CreateIdentity(identityManager, claims,
_cookieOptions.AuthenticationType);
AuthenticationProperties properties = await CreatePropertiesAsync(identityManager, userId);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);
context.Request.Context.Authentication.SignIn(cookiesIdentity);
}
}
The GrantReourceOwnerCredentials function not only compose the ticket with this line: context.Validated(ticket); but it also compose a cookie identity and set it to the cookie with this line: context.Request.Context.Authentication.SignIn(cookiesIdentity);
So my questions are, what is the exact purpose of the cookie in this function? Shouldn't the AuthenticationTicket be good enough for authentication purpose?
In the SPA template there are actually two separate authentication mechanisms enabled- cookie authentication and token authentication. This enables authentication of both MVC and Web API controller actions, but requires some additional setup.
If you look in the WebApiConfig.Register method you'll see this line of code:
config.SuppressDefaultHostAuthentication();
That tells Web API to ignore cookie authentication, which avoids a host of problems which are explained in the link you posted in your question:
"...the SPA template enables application cookie middleware as active mode as well in order to enable other scenarios like MVC authentication. So Web API will still be authenticated if the request has session cookie but without a bearer token. That’s probably not what you want as you would be venerable to CSRF attacks for your APIs. Another negative impact is that if request is unauthorized, both middleware components will apply challenges to it. The cookie middleware will alter the 401 response to a 302 to redirect to the login page. That is also not what you want in a Web API request."
So now with the call to config.SuppressDefaultHostAuthentication() Web API calls that require authorization will ignore the cookie that is automatically sent along with the request and look for an Authorization header that begins with "Bearer". MVC controllers will continue to use cookie authentication and are ignorant of the token authentication mechanism as it's not a very good fit for web page authentication to begin with.
The existence of the cookie also left me puzzled, since it clearly is not necessary in a bearer token authentication scenario... In this post the author dissects the individual accounts template, and has the following to say about the cookie:
The method also sets an application cookie. I don’t see a good reason for that.
My guess is that the authors of the template wanted to show examples of different kinds of authentication logic, and in this particular case they wanted to show how the authentication information could be stored in both the bearer token authentication JSON payload, as well as in a standard authentication cookie.
The fact that the JSON authentication payload is set to also include an additional (unnecessary) unencrypted property (the user id), in addition to the encrypted ticket, seems to support this theory:
var properties = CreateProperties(user.UserName);
var ticket = new AuthenticationTicket(oAuthIdentity, properties);
It seems that the authors of the template wanted to provide some useful examples, rather than the bare minimum needed to achieve bearer token authentication. This is also mentioned in the linked post above.
The cookie has one important purpose. Its value contains the bearer token which can be extracted by client-side javascript on your pages. This means that if the user hits F5 or refreshes the page, the cookie will typically persist. Your client-side javascript can then grab the bearer token from the cookie when the page reloads.