AWS APIGateway Lambda Custom Authrozier principalId - ios

I am looking at these blueprints: https://github.com/awslabs/aws-apigateway-lambda-authorizer-blueprints/blob/master/blueprints/nodejs/index.js
What is the principalId for and how is it generated?
I see the code like this:
// this could be accomplished in a number of ways:
// 1. Call out to OAuth provider
// 2. Decode a JWT token inline
// 3. Lookup in a self-managed DB
var principalId = 'user|a1b2c3d4'
The questions I have are:
Is it unique per user? I have a dynamodb where the users table has a unique user Id.
How do I use it in lambda as an environment variable in the AWS lambda console?
What is the main purpose of it in the autnorizer?
Thanks for reading and responding.

Yes, please see: https://forums.aws.amazon.com/thread.jspa?messageID=703105
Based on the answers to the other 2 questions you probably don't want this to be an environment variable, unless I'm misinterpreting what you're asking.
See above forum post
The principalId is intended to represent the long term identifier for whatever entity is being authorized to make the API call.

Related

Migrating U2F to WebAuthn gem in Ruby, where to get the parameters for AuthenticatorAttestationResponse

I have a couple of questions about the WebAuthn gem and the use of U2fMigrator.
I hope someone can point me in the right direction about it.
I am in the step just after converting my old U2F credentials using U2fMigrator.
migrated_credential = WebAuthn::U2fMigrator.new(
app_id: my_domain,
certificate: u2f_registration.certificate,
key_handle: u2f_registration.key_handle,
public_key: u2f_registration.binary_public_key,
counter: u2f_registration.counter
)
The documentation says: ā€œU2fMigrator class quacks like WebAuthn::AuthenticatorAttestationResponseā€ but without verify implementation.
Does that mean I need to create an instance of this AuthenticatorAttestationResponse for authentication?
If so. Where I should get this data from?
assertion_response = WebAuthn::AuthenticatorAssertionResponse.new(
credential_id: '',
authenticator_data: '',
client_data_json: '',
signature: '',
)
I am guessing that will allow me to authenticate the new migrated credentials like this:
assertion_response.verify(
WebAuthn::Credential.options_for_get(:extensions => { appid: my_domain }).challenge,
allowed_creadentials: migrated_credential.credential,
rp_id: my_domain
)
And also, I am guessing I don't need to re-register these credentials yet.
I am following this documentation:
https://github.com/cedarcode/webauthn-ruby/blob/master/docs/u2f_migration.md
https://github.com/castle/ruby-u2f
https://github.com/cedarcode/webauthn-ruby/blob/master/README.md#authentication
UPDATE 1
I've found this cool explanation in this guide
I will dig into it and I'll post the solution if I can find it.
UPDATE 2
I've spent the whole week trying to get the authenticatorAssertionResponse
from
Unfortunately, I only get a message saying I don't have a key registered:
I'm passing through the extension and appid where the U2F credential was registered originally. I wonder if it stoped working now the deprecation is complete.
U2fMigrator is instantiated with data that's already stored in your database. Instances of it respond to the same methods as AuthenticatorAttestationResponse, except it misses a verify method since the data was already verified in the past. In other words: the migrator behaves nearly the same as a freshly WebAuthn registered authenticator and it is meant to be used as such.
Does that mean I need to create an instance of this
AuthenticatorAttestationResponse for authentication?
Yes. The AuthenticatorAttestationResponse is instantiated with browser data from the WebAuthn navigator.credentials.get call. This in itself is unrelated to the U2F migration question, except for the part where the data comes from for its verify method. This comes either from a migrator instance (in the "real time conversion" approach) or is retrieved from the database.
Hope that makes sense, PRs welcome to improve the docs!

How to model resource level permissions in JWT OAuth2 tokens?

What is the canonical way to encode resource level permissions into a JWT access_token? Or in other words, how do you best encode access to other people's resources?
Is it something like this:
{
scopes: {
me: ['user', 'repo'], // My user
repo123: ['repo'], // Someone else's repo
org541: ['admin', 'repo'], // My org
org206: ['repo:read'] // Someone else's org
}
}
Or like this, with namespaced scope tags (in this case <resource>|<scope>:
{
scopes: ['me|user', 'me|repo', 'repo123|repo', 'org541|admin'... etc]
}
Or something else again?
This applies equally to "roles" or "memberships" or similar tags (and I realise I've mixed the examples above a bit) - the core question remains is how (best) do you distinguish these tags per resource in a single JWT access_token?
I don't know the exact use case you need to implement, but I would probably try to keep the scopes just for API operations. Such as "get a list of repositories". Then a client using the access token can list the repositories it can work with and the resource server verifies the access rights by the username or user groups.
If you wanted to limit the resources available to the client, you could have a scope that would grant access to just a subset (for example just the user's own repositories).
Having resources and their permissions encoded in scopes would make them hard to use (when composing an authentication request, the client would have know resource identifiers) and the permissions may change over the life of the access token.

Does self as identifier can represent the resource on restful api?

I'm working on REST API, and I trying to understand whether this looks legit in terms of REST.
I've players which using some mobile app with a login mechanism,
So the question is, if the player needs to update some attribute on his resource,
How the URL & PARAMS should looks like:
Option #1:
PUT /api/players/59/
PARAMS { some_attribute: "some_value" }
Option #2:
PUT /api/players/self
PARAMS { some_attribute: "some_value" }
The thing is, that the player doing the call with authentication, so it looks odd that he needs to send his id, it feels like he can send update on some other id, so when he sends 'self' it looks more suitable but uglier.
What's the REST point of view here?
Or maybe another option?
You should use first option
But in first option, request additional parameter like authentication_token
to verify the user and user is updating his information only.
This gist will help you in authenticating user
https://gist.github.com/josevalim/fb706b1e933ef01e4fb6
It shows 2 method for authenticating user while communicating with API

sfGuardAuth across multiple apps

I've got 3 apps: Backend, Frontend and Members.
And I've got 2 credentials: Administrators and Members.
Administrators are imported by default but Members are created in the Backend.
When a Member is created, an event handler also inserts this Member as a sf_guard_user and of course, the proper relations in sf_guard_user_group and sf_guard_user_permission.
That's the boring part, now the fun:
Frontend is not secured, but Members is and using these credentials: [administrator, member].
According to all this, Members created in the Backend that also get inserted (correctly as far as I can tell) should be able to login to the Members secured app, since they get the member group/permission/credential.
This is not happenning, the only ones that can login to the Members app are the administrators, which is not wrong, but either is the fact that correctly created Member users can't login to it.
The error thrown by the guard is the classic: The username and/or password is invalid.
Now that I edit the error, the salt comes to mind: How would one emulate the inserting of the salt as the guard does it? Maybe that's what I'm not inserting correctly (or inserting at all) and thus the password invalid error (and in fact everythine else I've described is ok! omg)
And that's my problem.
Thanks in advance :)
[administrator, member] means both are required, I believe.
I think you want [[administrator, member]] for the credential requirement.
Also, yes, you will want to make sure you use a salt, and set the algo.
parent::_set('password', call_user_func_array($algorithm, array($salt.$password)));
Salt before password, as well.

How to deal with authentication for a Ruby API wrapper?

I'm working on an API wrapper for Viddler, which will eventually be made public, and I'm trying to figure out the best way to deal with authentication/API keys, specifically with usage within Rails applications in mind.
The easiest way to write the wrapper would be to just have the code create a new client each time, and the developer could store the API key in a constant for future use:
#client = Viddler::Client.new(VIDDLER_API_KEY)
The problem with this is, it's kind of clunky to have to keep creating client objects and passing in the API key. This gets even more complicated when you throw user authentication into the mix.
I'm thinking some sort of solution where I all the the API key to be set in the environment file and then the authentication would be done in a before_filter.
Viddler::Client.api_key = 'abc123'
Viddler::Client.authenticate! 'username', 'password'
Viddler::Client would then store this in a class variable, and you could call Viddler::Client.new without any parameters and make authenticated calls. One thing I'd be concerned about is that this means the developer would have to be sure to clear out the authentication before or after each request, since the class variables would persist between requests.
Any thoughts?
Storing the API key globally would for sure be pretty useful and certainly is the way to go for that kind of information. User authentication on the other hand I think shouldn't be stored globally, never ever, especially for a high level API, because telling your users to "ensure to add an after_filter :reset_viddler_auth" might lead to some unexpected security risks.
# in a config/initializer/*.rb file or something
Viddler::Client.api_key = "abc123"
# in the controller/action/model/wherever
#client = Viddler::Client.new # anonymous
#client.authenticate!("username", "password") # authenticate anon client
#client_auth = Viddler::Client.new("username", "password") # authenticated client
Guess like that you've best of both worlds :) Maybe even provide a way to create a new client with another API key like,
#client_other = Viddler::Client.new("username", "password", :api_key => "xyz890")
So... just my 2 cents.
PS: not sure how up-to-date it is, but there's already a ruby viddler wrapper, just FYI, http://viddler.rubyforge.org/rdoc/

Resources