Issue with Guardian - EnsureAuthenticated not working - authentication

I'm attempting to get Guardian auth work for my application. But I'm completely stuck and can't find any support for the problem I'm having.
As far as I know I've setup Guardian exactly how the documentation shows how, but when I test authentication in the browser it fails on EnsureAuthenticated plug that Guardian provides.
Here is what I'm working with:
CONFIG:
All values are filled correctly in the app.
config :statcasters, MyApp.Guardian,
allowed_algos: ["HS512"],
verify_module: Guardian.JWT,
issuer: "my_app",
ttl: {30, :days},
allowed_drift: 2000,
verify_issuer: true,
secret_key: "my_secret_key"
AUTHENTICATED CONTROLLER:
defmodule Statcasters.LeagueController do
use StatcastersWeb, :controller
alias Statcasters.{League, Repo}
plug Guardian.Plug.EnsureAuthenticated
def create(conn, %{"league" => league_params}) do
changeset = League.changeset(%League{}, league_params)
case Repo.insert(changeset) do
{:ok, league} ->
conn
|> put_status(:created)
|> render("league.json", league: league)
{:error, changeset} ->
conn
|> put_status(:unprocessable_entity)
|> render(Statcasters.ChangesetView, "error.json", changeset: changeset)
end
end
end
In this controller is where it fails. When it goes to the EnsureAuthenticated plug it halts right there. but I have a valid JWT in the headers at this point.
Here our my params:
Parameters: %{"headers" => %{"Authorization" => "Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJTdGF0Y2FzdGVycyIsImV4cCI6MTUyNzUzMDA1OSwiaWF0IjoxNTI0OTM4MDU5LCJMiOiJTdGF0Y2FzdGVycyIsImp0aSI6IjJhNDg3MWQ4LTkwZGEtNDNlYS1hMGJlLWVjNjgwNjIzOTBkOCIsIm5iZiI6MTUyNDkzODA1OCwic3ViIjoiMSIsInR5cCI6InJlZnJlc2gifQ.EKeaHoQiW9tmtsabPIjj6069zD6Vcex9w3xfkXP5MIyiogWh400S6wMzaAsTQd20I5ai_y9jJTtgLzqYfbGTaQ"}
I've verified that the JWT is valid here.
REQUEST:
axios.post('/api/v1/leagues', {
league: {
name: this.$refs.league_name.value,
player_limit: this.$refs.player_limit.value,
},
headers: {
Authorization: "Bearer jwt(correct jwt)"
}
}).then(response => {
}).catch(error => {
})
Again, the problem is that my auth is failing in the Plug.EnsureAuthenticated hook. But I can't understand why because I seem to be setting everything up correctly and the JWT is in the auth header.

You're sending the header as a POST parameter, not an HTTP header. You need to put the headers in the third argument for axios.post:
axios.post('/api/v1/leagues', {
league: {
name: this.$refs.league_name.value,
player_limit: this.$refs.player_limit.value,
}
}, {
headers: {
Authorization: "Bearer jwt(correct jwt)"
}
})

Related

cy.session() with cy.request() does not log in user

I set up (in my cypress commands):
Cypress.Commands.add("loginByApi1", (username1, password1, TrackingId1) => {
cy.session([username1, password1, TrackingId1], () => {
cy.request({
method: 'POST',
url: 'https://someWebPage/api/challenge/credentials',
body: {
email: username1,
password: password1,
TrackingId: TrackingId1
}
}).then(({body}) => {
window.localStorage.setItem('authToken', body.token)
cy.log(body.token)
})
})
This is the endpoint with parameters used for login.
I call in my test
cy.loginByApi1(Cypress.env('mainInvestorUserEmail'), Cypress.env('mainInvestorUserPassword'), 'Cypress.env('trackingID')')
This is the session body (passes successfully it seems - see image) Notice that cy.log(body.token) is empty
When I try cy.visit('/') in order to visit my base page, URL is still redirected to login screen
In my local storage i have these keys
I tried replacing authToken with accessToken, since this is shown in local storage, but same result.
Not sure if I'm doing it correctly here, but this is on the official cypress site and other sites as well.
I can login using UI so my credentials and approach in that regard are correct.

POST Fetch request returns: grant_type was not specified

I had working code for fetching a access token with oauth, then I did a expo eject and now when I try to POST my auth code to get the access_token i receive response.
.then((auth_code) => {
let my_headers = new Headers()
my_headers.append('Authorization', `Basic ${base64_auth}`)
my_headers.append('Content-Type', 'application/x-www-form-urlencoded')
my_headers.append('Access-Control-Allow-Origin', '*')
my_headers.append('grant_type', 'authorization_code')
let urlencoded = new URLSearchParams()
urlencoded.append('code', auth_code)
urlencoded.append('grant_type', 'authorization_code') // <-- GRANT_TYPE HERE
let request_options = {
method: 'POST',
headers: my_headers,
body: urlencoded,
mode: 'cors'
}
console.log(request_options) // <--- OUTPUT BELOW
let url_with_params = `https://${url}/oauth/token/`
fetch(url_with_params, request_options)
.then((response) => response.json())
.then((json) => console.log(json)) // <--- OUTPUT BELOW
.then((json) => helpers.set_session_object('oauth_object', json))
.finally(() => set_loading(false))
.catch((error) => console.log('error', error))
})
.catch((error) => console.error(error))
console.log(request_options) outputs the following:
{method: "POST", headers: Headers, body: URLSearchParams, mode: "cors"}
body: URLSearchParams {_searchParams: Array(1)}
headers: Headers
map:
access-control-allow-origin: "*"
authorization: "Basic YXdheTprTkwpUmtWc2lWM2ppaCk3WDlmZXp3aSk="
content-type: "application/x-www-form-urlencoded"
grant_type: "authorization_code"
method: "POST"
mode: "cors"
and the json response outputs:
{"error": "invalid_request", "error_description": "The grant type was not specified in the request"}
Any idea why this is happening? I obviously have the grant_type declared right?
Looking at this I can see a couple of things that may not be quite right:
Remove the trailing backslash at the end of the OAuth token URL
Include a redirect_uri field, which is required in Authorization Code Grant messages
I suspect the first issue above is causing a redirect so that the POST to https://url/oauth/token/ becomes a GET to https://url/oauth/token.
Some similar issues are described in this post, and above all else I would aim to ensure that you can use an HTTP Proxy tool to view messages, which will make you much more productive at diagnosing this type of issue in future.
PROXY MOBILE SETUP
If it helps, my blog has some posts on proxy setup details:
Android HTTP Proxy Setup
iOS HTTP Proxy Setup

auth0-js: UnauthorizedError: No authorization token was found, though logged in

I created an app with Vue (including Vue-Router), Node and Express.
I'm trying to secure my App with SSO, using auth0-js.
I created an Auth0-Account and followed this tutorial.
My Login function looks as follows:
import auth0 from 'auth0-js'
var auth = new auth0.WebAuth({
clientID: <my-client-id>,
domain: '<my-auth0-domain>/'
})
export function ssoLogin () {
auth.authorize({
responseType: 'token id_token'
redirectUri: http://localhost:8000/callback,
audience: 'https://<my-auth0-domain>/userinfo',
scope: 'full_access'
})
}
While the login itself works fine, I can't seem to find out how to secure the secret routes of my app.
Following the above mentioned tutorial, I used express-jwt and jwks-rsa, like this:
var jwt = require('express-jwt')
var jwks = require('jwks-rsa')
var authCheck = jwt({
secret: jwks.expressJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: "https://<my-auth0-domain>/.well-known/jwks.json"
}),
audience: <my-client-id>,
issuer: "https://<my-auth0-domain>/",
algorithms: ['RS256']
})
app.post('/send-sensitive-data', authCheck, function (req, res) {
// this post requests sends some data, and should only do so, if a user is logged in
})
However, even if I'm logged in via SSO, when I try to access the sensitive data, I obtain
UnauthorizedError: No authorization token was found
I have no idea where I went wrong. This seems like a very stupid question, but: Can somebody tell me, where the authorization token must be, so it will be found?
I would really appreciate if someone helped me by this or gave me a hint.
Please feel free to ask for more code snippets, if that might help.
Okay, I found the answer on my own ... but in case anyone is making the same mistake as I'm doing: I forgot to set the header in the axios.post request, like that:
axios({
method: 'post',
url: '/send-sensitive-data',
data: somedata,
headers: {
Authorization: 'Bearer ' + getAccessToken()
}
})
.then(response => {
// do something with the response
})

Passing Phoenix.Token to and from browser

I’m trying to use Openmaize for user authentication, and having trouble getting phoenix pass a token when a user logs in. It appears that no token is assigned and passed to the client, and therefore Phoenix.Token.verify fails.
IO.inspect(socket) in UserSocket.connect returns this.
Phoenix.Socket{assigns: %{}, channel: nil, channel_pid: nil,
endpoint: SeatSaver.Endpoint, handler: SeatSaver.UserSocket, id: nil,
joined: false, pubsub_server: SeatSaver.PubSub, ref: nil,
serializer: Phoenix.Transports.WebSocketSerializer, topic: nil,
transport: Phoenix.Transports.WebSocket, transport_name: :websocket,
transport_pid: #PID<0.2098.0>}
I defined set_current_user(user, conn) function in authenticate.ex controller that looks like
defp set_current_user(user, conn) do
token = Phoenix.Token.sign(conn, "user socket", user.id)
conn
|> assign(:current_user, user)
|> assign(:user_token, token)
In the app.html.eex, the following has been added.
<script> window.userToken = “<%= assigns[:user_token] %>” </script>
<script src = “<%= static_path(#conn, “/js/app.js”) %>”></script>
in the app.js,
let socket = new Socket(”/socket”, {
params: {token: window.userToken},
…
})
and finally, user_socket.ex has
def connect(%{"token" => token}, socket) do
case Phoenix.Token.verify(socket, "user socket",
token, max_age: #max_age) do
{:ok, user_id} ->
IO.inspect(user_id)
{:ok, assign(socket, :user_id, user_id)}
{:error, _reason} ->
:error # this errors out because token is nil
end
end
First you need to add secret_key_base in config/config.exs.
secret_key_base: xxxxx

Invalid signature Open Bank Project Oauth1.0a

I'm developing a React-Native App with Open Bank Project and I can't use suggested SDKs, not even the nodeJS one as Oauth1.0 is not available in RN.
And I'm stuck with a Bad Signature error on Access Token request '/oauth/token' after passed '/oauth/initiate' and '/oauth/authorize' without any problem.
As specified in docs here before accessing to a Protected Resource we need an Access Token via a POST Request, which gives me the Bad Signature answer.
Here is my code for the request:
getAccessToken(verifier){
let request = {
url: 'https://api.openbankproject.com/oauth/token',
method: 'POST',
data: {
oauth_verifier: verifier,
oauth_token: this.auth.oauth_token,
oauth_token_secret: this.auth.oauth_token_secret
}
}
return fetch(this.url_login, {
method: request.method, //POST
form: request.data,
headers: this.oauth.toHeader(this.oauth.authorize(request))
})
.then((res) => {return res.text()})
.then((txt) => {
console.log('setUID', txt, this.url_login, {
method: request.method,
form: request.data,
headers: this.oauth.toHeader(this.oauth.authorize(request))
})
})
Here is the signed request:
Object {method: "POST", form: Object, headers: Object}
form:
oauth_token:"..."
oauth_token_secret:"..."
oauth_verifier:"71531"
headers:
Authorization:
"OAuth oauth_consumer_key="...", oauth_nonce="3UlQ5dx958tibf6lSg0RUGPQFZeV7b8V", oauth_signature="weyE1lFkoIjAErYLKdSi9SDlCZsNBi7%2BuAkLV2PWePo%3D", oauth_signature_method="HMAC-SHA256", oauth_timestamp="1464248944", oauth_token="...", oauth_token_secret="...", oauth_verifier="71531", oauth_version="1.0""
I've tried with and without Oauth_token_secret, also moving oauth_verifier from body to query but with the same Bad Signature result.
Any idea? thx
You can use oauth module https://github.com/ciaranj/node-oauth
var oauth=require('oauth');
var consumer = new oauth.OAuth(
"https://twitter.com/oauth/request_token", "https://twitter.com/oauth/access_token",
_twitterConsumerKey, _twitterConsumerSecret, "1.0A", "http://127.0.0.1:8080/sessions/callback", "HMAC-SHA1");
then generating signature like this :
var parameters = consumer._prepareParameters("user_access_token", "user_access_token_secret", "http_method", "request_url");
var headers = consumer._buildAuthorizationHeaders(parameters);
parameters array contains signature, also you can build authorization headers if needed. Hope it helps :)