What is the correct way to add a Custom Authentication strategy to a Feathers application? - feathersjs

My Feathers application needs to be able to have two JWT authentication strategies. For the users service, I need to have, for example, all: [authenticate('carrier')] instead of all: [authenticate('jwt')] in my hooks. For the rest of the services, authenticate['jwt'] is needed.
For this, I have registered a custom strategy in authentication.js called CarrierStrategy as following:
module.exports = function auth(app) {
const authentication = new AuthenticationService(app)
// register all of the strategies with authentication service
authentication.register('carrier', new CarrierStrategy())
authentication.register('jwt', new JWTStrategy())
// register the authentication service with your app
app.use('/api/authentication', authentication)
}
In config/default.json, I have also registered this strategy as following:
authStrategies: ["carrier", "jwt"]
The CarrierStrategy needs to handle the incoming Authorization header a little differently with some custom logic.
When I use Postman to send requests for this service, i.e., localhost:3030/users with a JWT token in the header, I get the following error.
Invalid authentication information (strategy not allowed in authStrategies)'
Please guide me if this is the right way to add a custom strategy to the application.

I had a similar problem to this. I wanted both Stateful and Stateless JWT authentication. The problem being that if you just do this in authentication.js
authentication.register('jwt', new JWTStrategy());
authentication.register('jwt-stateless', new JWTStrategy());
Then when you submit a request with a JWT token it will match on either one and you'll end up with a problem in one of your services somewhere.
I ended up creating a custom strategy like this in authentication.js:
class StatelessJWTStrategy extends JWTStrategy {
get configuration () {
const authConfig = this.authentication.configuration;
const config = super.configuration;
return {
...config,
entity: authConfig.entity,
service: authConfig.service,
header: 'Authorization',
schemes: [ 'STATELESS' ]
};
}
}
which is basically a slightly modified JWTStrategy that uses STATELESS in the Authorization header instead of Bearer or JWT. It's not a great solution, but it works.
Then I did this also in authentication.js
authentication.register('jwt', new JWTStrategy());
authentication.register('jwt-stateless', new StatelessJWTStrategy());
Then you need to modify your config.json file. In the authentication section add this:
"jwt-stateless": {
"entity": null
},
"jwt": {
"entity": "user",
"service": "users"
},
"entity": "user",
"service": "users",
"authStrategies": [
"jwt-stateless",
"jwt",
"local"
],
Now you should be able to use the jwt-stateless auth mechanism in your hooks like this:
authenticate('jwt-stateless')
Head over to here to create your stateless JWT. Fill in iss with the issuer and aud with audience details from your config.json, and add a user ID to the sub field. Pop your secret from config.json in the bottom signature verification field and the token on the left should authenticate.

Related

how to pass object in post api to create account in flutter

I have created a login form with email, password a login button. I am new to flutter, dart and web.
How do I integrate the JSON Restfull API for Login and Signup, by using JSON as an object.
Assuming you're completely new at Flutter and dart, there are a few steps to complete a RESTful API call.
At first, you'll need to provide a dependency from pub.dev named http.
After adding the dependency in pubspec.yaml file, go to the terminal, and run the command pub get.
Now, in your login form, I'm assuming you're trying to post a username and a password to a certain endpoint.
Let's create a separate file named networking_helper.dart just to keep everything of RESTful API in a well-mannered structure. You can keep your API implementation in your FORM screen, but I will strongly recommend not mixing UI code with backend code.
Now, create a class in the networking_helper.dart file to bind all API methods. Create a method that will contain all your API-related code with the login endpoint. For example:
class NetworkingHelper{
Future<bool> login(String email, String password) async {
//api implementation will be here
}
}
Now, look closely here, here I've created a class named NetworkingHelper to encapsulate my API methods. Inside the NetworkingHelper class there is a method named login. The login method requires some parameters based on its need. The login method is declared as async, to execute the job in the background.
Let's prepare some data that will be provided to complete the API call.
Assuming you will be using a POST method to execute your login FORM's data, let's declare a Map of the String key and dynamic value like this:
final Map<String, String> bodyParams = {
"username": username,
"password": password,
"grant_type": "password",
};
Don't panic yet about why I choose to use "username", "password" and "grant_type" keys. My login endpoints require these values. Communicate with your API developer about their needs and replace your required keys with the above-mentioned keys.
To establish an HTTP connection with your required data and to wait for a response, follow this step:
final Response response = await post(Uri.parse(<url>), body: bodyParams);
Typically asynchronous method returns a value with delay, so we have to wait until it finishes the job. So we used the await key to indicate the waiting period.
After that, it's fairly simple. Just implement few if/else based on your needs to ensure your data is valid and HTTP call was successful. Example:
if (response.statusCode == 200) {
return true;
} else {
return false;
}
Remember the method's return type declared above? What was it?
It was Future<bool?>. Let's break it down too. Let's start with the impression. Our return type is a boolean value that will be provided in the future because our method was declared as async. Make sense!!!
This is why we are returning true or false after we finished our API call waiting phase.
To give the complete structure of the API call, here is the complete code:
class NetworkingHelper{
Future<bool> login(String email, String password) async {
final Map<String, String> bodyParams = {
"username": username,
"password": password,
"grant_type": "password",
};
final Response response = await post(Uri.parse(<url>), body: bodyParams);
if (response.statusCode == 200) {
return true;
} else {
return false;
}
}
}
Hope that will help you a bit. Happy coding :D
This is Very Easy Example.
I was created already in my github account.
Please try it: https://github.com/JayswalViraj/Flutter-Login-With-Rest-API
Note: Login and registration both are working process same. Only you need change api url for registration process. Login api url to registration api url.

LoginRadius Validating access token .net core

I am trying to validate my access token (not JWT) with LoginRadius, I can do the login but after when I call my API I always get unauthorized or different errors according to my Authentication configuration, I am using like this. I believe the authority url is not correct but I couldn't find any other
services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect("login-radius", options => {
// Set the authority to your Auth0 domain
options.Authority = $"https://api.loginradius.com/identity/v2/auth/";
// Configure the Auth0 Client ID and Client Secret
options.ClientId = Configuration["ClientId"];
options.ClientSecret = Configuration["ClientSecret"];
// Set response type to code
options.ResponseType = OpenIdConnectResponseType.Code;
options.Scope.Clear();
options.Scope.Add("openid");
options.CallbackPath = new PathString("/callback");
options.ClaimsIssuer = "loginradius";
// Saves tokens to the AuthenticationProperties
options.SaveTokens = true;
});
I believe you are trying to setup OIDC, and to configure it, please refer to the LoginRadius docs on OIDC, as it needs few things that need to be configured in the Admin Console and the correct authority URL: https://www.loginradius.com/docs/single-sign-on/tutorial/federated-sso/openid-connect/openid-connect-overview/#otheropenidfunctionality6
Please refer to the OIDC discovery endpoint, which provides a client with configuration details about the OpenID Connect metadata of the Loginradius App.
URL Format: https://cloud-api.loginradius.com/sso/oidc/v2/{sitename}/{oidcappname}/.well-known/openid-configuration
My account didn't have access to few features

How to build custom Zapier integration for Xero

I am attempting to build my own integration in zapier that will allow me to create quotes in Xero (a feature not currently supported natively). I've been using this this post and this reference to help me.
I've gotten to the point where I'm creating the action and testing it with test data. Unfortunately, the response I get is "Got 400 calling POST https://identity.xero.com/connect/token, expected 2xx." Perhaps I'm sending the json data incorrectly. I've tried using the 'pretty' and 'raw' ways of sending data:
Could a zapier "expert" help me with this? Perhaps by creating their own xero integration?
EDIT
Not sure if necessary, but blocked out the IDs. Although I now see that I didn't do that for the contactID in the first post lol...
Here is how to get it done, but remember that you will need to have a search action to find information for the required ID's. Given your error I think the problem is that you did not have the tenantId that should be defined in your header like so: 'xero-tenant-id': 'YOURNUMBERHERE'. See step 8 below to compare it to yours.
In case you can't find it, these are the steps I took:
XERO
Create Account
Create Xero App and add the Zapier OAuth Redirect URL to the Xero redirect section(from your 'Zapier Dev' app on 'step 2').
ZAPIER
In your dev app, add the CLient ID & Secret from xero to the appropriate sections in 'Zapier Dev step 3'
Add the POST endpoint (requested in 'Zapier Dev step 4') https://login.xero.com/identity/connect/authorize
with the HTTP headers:
response_type: code
client_id: {{process.env.CLIENT_ID}}
redirect_uri: {{bundle.inputData.redirect_uri}}
state: {{bundle.inputData.state}}
Add the scope: openid profile email accounting.transactions
Refresh token ('Zapier Dev step 4: Access Token') can be obtained using this:
REFRESH TOKEN: POST https://identity.xero.com/connect/token
TEST CALL: GET https://api.xero.com/connections
-Keep the returned tenantId for later use
-Test the authentication. Does it work? If yes, move on to step 7.
-If test fails: review for typos, check for correct url's and make sure your Headers match what xero requires (see link at bottom).
Add Action called createQuote
-Add input contactID
-Add input lineitem with label of description
-Add input tenantId
Add POST to API Config at url https://api.xero.com/api.xro/2.0/Quotes
Example POST:
const options = {
url: 'https://api.xero.com/api.xro/2.0/Quotes/',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${bundle.authData.access_token}`,
'xero-tenant-id': bundle.inputData.tenantID
},
params: {
},
body: {
"Contact": {
"ContactID": bundle.inputData.ContactID
},
"Date": "2019-11-29",
"LineItems": [
{
"Description": bundle.inputData.LineItems
}
]
}
}
return z.request(options)
.then((response) => {
response.throwForStatus();
const results = z.JSON.parse(response.content);
return results;
});
Plug in the test contactID, tenantID, lineitems and test it out
After completing this you will need to create a search action to grab the contactID and tenantID if you want it all automated. If you have problems I found the start-up doc to be useful.

Accessing user token in IBM Cloud Functions serverless app secured with OAuth user authentication

I am creating a serverless app using IBM Cloud Functions. My Cloud Functions API is secured with OAuth user authentication using an IBM Cloud App ID service. When a user logs into my app, an access token is generated by this service. I want to extract user data from that access token so that I can customize the user experience.
How do I access that token from within a Cloud Functions action that is coded for Node.js 10?
Example
The openwhisk webaction doc
https://github.com/apache/openwhisk/blob/master/docs/webactions.md
states that the following code
function main(params) {
return { response: params };
}
generates the following response
{
"response": {
"__ow_method": "get",
"__ow_headers": {
"accept": "*/*",
"connection": "close",
"host": "172.17.0.1",
"user-agent": "curl/7.43.0"
},
"__ow_path": ""
}
}
From that data I should be able to get HTTP request details. Specifically, I should be able to get the Authorization header value off the "__ow_headers" property of the action argument (params).
However, the same code inside an IBM Cloud Functions web action generates nothing. Nothing exists on the params object.

Is it possible to integrate Amazon QuickSight dashboard graphs to a web application?

I need to display live interactive graphs based on customer data present in MySQL,for generating the graphs, I am planning to use Amazon Quick Sight but i would like to know whether the generated graphs can be integrated with my web application UI ?
Datasource MYSQL is hosted in AWS.
Any other better design solution is also most welcome :)
I don't think so. Even if you want to share the dashboard to
someone, you need to create a user in QuickSight. Any more than 1
user will be charged by AWS.
The dashboard cannot be public and you need to login to view the
dashboard. If it was public, you could have embedded it in your
webpage as an iframe. But you cannot.
So, I think you are having limited options here, when it comes to
QuickSight.
You can always using D3 or Google Charts to display the data by
exposing REST services for your data in MySQL.
If you have a huge database, you may want to consider indexing the
data to Elasticsearch and perform queries on it.
Check if Kibana + Elasticsearch works out of the box for you.
Good luck!
Update: Dec 28 2018
Amazon announced in Nov 2018, that Amazon QuickSight dashboards can now be embedded in applications. Read more here at this AWS QuickSight Update.
AWS has enabled the embedding of the Dashboards into web apps. The feature was released on 27th Nov 2018. Here are a few helpful links:
1. https://aws.amazon.com/blogs/big-data/embed-interactive-dashboards-in-your-application-with-amazon-quicksight/
2. https://docs.aws.amazon.com/quicksight/latest/user/embedded-dashboards-setup.html
Note: This answer is applicable only if you are using AWS Cognito
In order to generate Quicksight secure dashboard URL, follow the below steps:
Step 1: Create a new Identity Pool. Go to https://console.aws.amazon.com/cognito/home?region=u-east-1 , click ‘Create new Identity Pool’
Give an appropriate name.
Go to the Authentication Providers section, select Cognito.
Give the User Pool ID(your User pool ID) and App Client ID (go to App
Clients in user pool and copy id).
Click ‘Create Pool’. Then click ‘Allow’ to create roles of the
identity pool in IAM.
Step 2: Assign Custom policy to the Identity Pool Role
Create a custom policy with the below JSON.
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "quicksight:RegisterUser",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "quicksight:GetDashboardEmbedUrl",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": "*",
"Effect": "Allow"
}
]
}
Note: if you want to restrict the user to only one dashboard, replace the * with the dashboard ARN name in quicksight:GetDashboardEmbedUrl,
then goto the roles in IAM.
select the IAM role of the Identity pool and assign the custom policy
to the role.
Step 3: Configuration for generating the temporary IAM(STS) user
Login to your application with the user credentials.
For creating temporary IAM user, we use Cognito credentials.
When user logs in, Cognito generates 3 token IDs - IDToken,
AccessToken, RefreshToken. These tokens will be sent to your application server.
For creating a temporary IAM user, we use Cognito Access Token and credentials will look like below.
AWS.config.region = 'us-east-1';
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId:"Identity pool ID",
Logins: {
'cognito-idp.us-east-1.amazonaws.com/UserPoolID': AccessToken
}
});
For generating temporary IAM credentials, we call sts.assume role
method with the below parameters.
var params = {
RoleArn: "Cognito Identity role arn",
RoleSessionName: "Session name"
};
sts.assumeRole(params, function (err, data) {
if (err) console.log( err, err.stack); // an error occurred
else {
console.log(data);
})
You can add additional parameters like duration (in seconds) for the
user.
Now, we will get the AccessKeyId, SecretAccessKey and Session
Token of the temporary user.
Step 4: Register the User in Quicksight
With the help of same Cognito credentials used in Step 3, we will
register the user in quicksight by using the quicksight.registerUser
method with the below parameters
var params = {
AwsAccountId: “account id”,
Email: 'email',
IdentityType: 'IAM' ,
Namespace: 'default',
UserRole: ADMIN | AUTHOR | READER | RESTRICTED_AUTHOR | RESTRICTED_READER,
IamArn: 'Cognito Identity role arn',
SessionName: 'session name given in the assume role creation',
};
quicksight.registerUser(params, function (err, data1) {
if (err) console.log("err register user”); // an error occurred
else {
// console.log("Register User1”);
}
});
Now the user will be registered in quicksight.
Step5: Update AWS configuration with New credentials.
Below code shows how to configure the AWS.config() with new
credentials generated Step 3.
AWS.config.update({
accessKeyId: AccessToken,
secretAccessKey: SecretAccessKey ,
sessionToken: SessionToken,
"region": Region
});
Step6: Generate the EmbedURL for Dashboards:
By using the credentials generated in Step 3, we will call the
quicksight.getDashboardEmbedUrl with the below parameters
var params = {
AwsAccountId: "account ID",
DashboardId: "dashboard Id",
IdentityType: "IAM",
ResetDisabled: true,
SessionLifetimeInMinutes: between 15 to 600 minutes,
UndoRedoDisabled: True | False
}
quicksight.getDashboardEmbedUrl(params,
function (err, data) {
if (!err) {
console.log( data);
} else {
console.log(err);
}
}
);
Now, we will get the embed url for the dashboard.
Call the QuickSightEmbedding.embedDashboard from front end with the
help of the above generated url.
The result will be the dashboard embedded in your application with
filter controls.
I know this is a very late reply, but just in case someone else stumbles across this question... We use periscopedata.com to embed BI dashboards in our SaaS app. All that's needed is knowledge of SQL (to create the charts/dashboards) and enough dev knowledge to call their API endpoint to display the dash in your own app.