I'm evaluating whether to use Ionic's cloud Auth service and it seems like it's relatively easy to implement client-side, where you can check this.auth.isAuthenticated. You can also set the user info from the client side as well.
However, if I want to do check their identity server-side, such as check that a user is authenticated when they call my custom api to post a comment - how can I get some sort of token (preferably a JWT token) that I can use to validate their identity server-side? Assuming we are using email/password authentication.
Also - using their send notification on a user's birthday example, how can I query the user data in ionic cloud's database to say find all users who have a birthday today. Can I export out the user data in any way if I want to migrate away in the future?
You should implement a JWT authentication service server side.
In other words when the user is authenticated, the app can send a JWT token to the server which should be evaluated to trust the remote user.
For more info reads: https://docs.ionic.io/services/auth/custom-auth.html
A php example here: https://github.com/driftyco/custom-auth-examples/tree/master/php
Regards from Italy
Related
I'm building an application where I want to be able to create and authenticate users using Discord and OAuth2. The reasons are:
The application can be considered a "companion" app to a Discord community I am running, and
I don't want the users or myself to have to deal with usernames and passwords
The application consists of a client desktop application and backend services. I have a fairly basic understanding on how I authorize the user with Discord:
Client application goes to backend endpoint /oauth/login and the user is redirected to the Discord app approval page
The user confirms and is redirected to the backend callback /oauth/callback with a code that can be used to fetch a pair of access and refresh tokens.
Frankly, from this point I am kind of stumped on how the rest of the authentication should work. I assume at least the following:
I need to create a user entry in my database with at least an UID (for simplicity the same as the one for the user in Discord), the access and refresh token pair. If user is already created, update the database with the new tokens.
Whenever the application needs user information from Discord it should use the access token. If it has expired, exchange the refresh token with Discord to get a new token pair.
But now what? This only authenticates the user against Discord. I want to leverage the fact that the user is authenticated with Discord to be authenticated to my application. Here are some general questions I have:
Do I make a new token for the user to use for subsequent requests to my backend endpoints? Or do I return the Discord access token to the desktop client?
What do I do when the token expires? Do I also need a "exchange" endpoint for the desktop client to refresh the token (possibly that just forwards to Discord to get a new token, depending on the answer to my previous question).
This all feels like it should be very basic, but I am out of my comfort zone here and need some help to be unblocked.
Thanks for reading!
Your own application should effectively have its own session system.
The easiest is likely to just use HttpOnly cookie-based sessions, which something like a Redis store (or Memory store if this is a toy project).
The session data on the server should contain information on which user is currently logged in. You should probably store the discord access and refresh token in a database.
The simplest way to deal with refreshing, is to simply call their refresh token endpoint as soon as you get a 401 response. If discord provides information on how long access tokens are valid, you could also preemptively refresh instead of only doing this when you get the 401. Your server does the refreshing, you don't need an endpoint for this.
Generally I can recommend that your server handles all interactions with the discord API, and never your client. (aside from the initial authorization step).
I'm done setting up the server by following steps given here.
OAuth does work with google but only for web-client
On iOS client, I've followed steps to integrate google sign-in by following steps given here
Let's say there is a get route localhost:8080/api/v1/movies should be accessed by users who are logged in, how do I achieve that?
User has already logged in, on iOS client.
How do I pass iOS client's google authorisation information to server?
I believe that once your client has completed sign-in, you will have a GIDGoogleUser that provides access to an ID token (JWT) that you can supply to your server. Your server can then validate the token (that it was issued by Google) and extract the user's identity.
See: https://developers.google.com/identity/sign-in/ios/backend-auth
You may be able to use the Kitura-CredentialsJWT middleware to decode the token. Note that as of writing, the plugin only supports Codable routes, but there is an open pull request that adds support for 'raw' routing (using the Kitura-Credentials plugin mechanism).
Update: Kitura-CredentialsJWT support has now been released in tag 1.0.0.
I'm googling since long and i'm bit confused now should i create Custom iDP or Authentication provider in Keycloak.
Below is my requirements.
I have multiple clients and each client having login API which also returns JWT token on successful login so what business needs is that when user try to login i want keycloack to consume client API to Authenticate User and once user successfully authenticated by Client API Keycloack should generate token for further operations.
One more problem is can i use same token return from client as Keycloack token because there are some apis on client side which decode token and use some info from token.
Please suggest and i'm bit stressed to looking for different solution and couldn't help. I will be grateful if you can share sample code with it.
What do you mean by "I have multiple clients and each client having login API" (does that mean different endpoints secured by different realms?? I supose that's not what you want).
What you mention here:
"what business needs is that when user try to login i want keycloack to consume client API to Authenticate User and once user successfully authenticated by Client API Keycloack should generate token for further operations."
that is indeed the standard behaviour of Keycloak, why do you need a custom Authentication (user federated Authentication/ identity Provider)? You haven't made clear from the description of your problem, why do you need a custom Identity Provider SPI /custom Authentication federation? If you really need an Authentication SPI, please read chapter 8 from here:
https://www.keycloak.org/docs/latest/server_development/index.html#_auth_spi
that's the best documentation on that topic. Are you authenticating against a custom Auth service of your company that doesn't support openid connect? If not, then you don't need a custom Authentication SPI.
regarding:
"can i use same token return from client as Keycloack token because there are some apis on client side which decode token and use some info from token."
I don't know exactly what you mean there, but depending on your client adapter there are slight variations on the way you get/extract a bearer token & secure your endpoints in general. Plase read chapter 3.1 from here: https://www.keycloak.org/docs/latest/securing_apps/index.html#_client_registration
There you'll find base implementations/suggestions for the different client adapters, or at least should move you forward in your search.
Hope it helps.
TL;DR When using google oauth on desktop app, what to save on disk to avoid repeated sign in? Save the google user id? or the token? or an session id?
I'm creating an little desktop app, whitch must authenticate to my REST API server. I'm using google oauth2 for that.
The idea is, that when the desktop app will be authentivated, it generates some data that will be send to my server. The server will store the data with the google user id received from https://www.googleapis.com/userinfo/v2/me.
On the first run of the desktop app, it will open the default browser, with and url for my server and start an local http server. then:
my server will redirect the browser to google (with the clientid, secret, etc.)
user logs in and it will be redirected back to the server with the oauth code
server uses the code to get the token, and then the user profile and stores the token and the profile in db, then redirects the browser to localhost with an paramerer
the desktop app catches the parameter and stores it in an file on the disk
next time the desktop app will start it only reads the file for the parameter to send the generated data with it to my server
my question is: what the parameter should be? the google user id? the oauth token? an generated session id for this desktop app? or something else?
when it will be the google user id, it can conveniently sent the data with the user id and the rest server will just store it in db as is. but I don't think it's safe
when it will be the token, the rest server has to with every request also get the user profile from google with the token. and imho sending the token with every request isn't safe either
generating an session id means to store it with the user and the token on the server and the desktop app will just store it and send it with every request. but I don't know if it's safe to do that
As it's normally the case in software development you have a couple of options depending on requirements.
The mandatory requirement is that your client (desktop) application needs to send something to your REST API so that the API can perform up to two decisions:
Decide who the user is.
Decide if the user is authorized to perform the currently requested action.
The second step may not be applicable if all authenticated users have access to exactly the same set of actions so I'll cover both scenarios.
Also note that, for the first step, sending the Google user ID is not a valid option as that information can be obtained by other parties and does not ensure that the user did authenticate to use your application.
Option 1 - Authentication without fine-grained authorization
Either always sending the id_token or exchanging that token with your custom session identifier both meet the previous requirement, because the id_token contains an audience that clearly indicates the user authenticated to use your application and the session identifier is generated by your application so it can also ensure that. The requests to your API need to use HTTPS, otherwise it will be too easy for the token or session ID to be captured by an attacker.
If you go with the id_token alternative you need to take in consideration that the token will expire; for this, a few options again:
repeat the authentication process another time; if the user still has a session it will indeed be quicker, but you still have to open a browser, local server and repeat the whole steps.
request offline_access when doing the first authentication.
With the last option you should get a refresh token that would allow for your application to have a way to identify the user even after the first id_token expires. I say should, because Google seems to do things a bit different than the specification, for example, the way to obtain the refresh token is by providing access_type=offline instead of the offline_access from OpenID Connect.
Personally, I would go with the session identifier as you'll have more control over lifetime and it may also be simpler.
Option 2 - Authentication + fine-grained authorization
If you need a fine-grained authorization system for your REST API then the best approach would be to authenticate your users with Google, but then have an OAuth 2.0 compliant authorization server that would issue access tokens specific for your API.
For the authorization server implementation, you could either:
Implement it yourself or leverage open source components
⤷ may be time consuming, complex and mitigation of security risks would all fall on you
Use a third-party OAuth 2.0 as a servive authorization provider like Auth0
⤷ easy to get started, depending on amount of usage (the free plan on Auth0 goes up to 7000 users) it will cost you money instead of time
Disclosure: I work at Auth0.
There should be no problem sending the access_token with every request since they are created for that purpose and are thus short lived. You can use the Google Authorization Server endpoint to verify a token instead of using it to do a request for a users profile.
If you're only relying on Google for authentication, here's how your workflow can look:
the client (desktop application, in your case) retrieves the
Google id_token following the user's log in, and then sends it to
the server
the server validates the integrity of said token and extracts the user's profile data; this could mean a simple GET on Google's endpoint to verify this token: https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={0}
On subsequent requests, nothing should change really, except that the user's login process will be automated (since he's given permissions & all), and thus much faster. #danielx is right, there's no problem with sending the token each and every time.
We have a regular web application with cookie based auth and now we want to split frontend and backend (api) in order to have third-party public API. So our backend will be on one domain and frontend on another one.
For authorization we would like to switch for OAuth 2 with JWT. In this case our frontend app will have to use access_token instead of cookie session and it brings a big old question:
How To Remain Logged In - The Infamous "Remember Me" Checkbox (part II from Form based authentication for websites)
From OAuth2 point of view our frontend application going to use something between Resource Owner Password Credentials Grant and Implicit Grant. It is closer to Password Credentials Grant since we still going to use usual login form and won't redirect user to another domain in order to sign in. At the same time it is closer to Implicit Grant since it's all going to be browser-only & JavaScript based when access_token will be saved in browser.
The RFC says the authorization server MUST NOT issue a refresh token if you use Implicit Grant and my question is if it's still valid in this use case when you don't really use a 3-d party OAuth but your own api? Instinctively I feel that having refresh_token in browser is a security hole and would like to confirm it with you guys, but that refresh_token seems to be the only way to have persistent login working the same way as we had with cookies.
**UPD** after #FlorentMorselli comment:
The OpenID specs still do not answer my question if I can use refresh_token with browser only application
Google says they provide refresh_token only for access_type=offline
OpenID Connect Core says you cannot use Refresh Token with Implicit Flow
OpenID Connect Core says nothing about using refresh_token with Hybrid Flow
There's only one place where it says something promising about refresh_token with Hybrid Flow, but nothing precise
UPD2 thanks to #reallifelolcat
It looks like OpenID Connect does not explicitly support Resource Owner Password Credentials Grant, meaning you have to redirect user to OpenID Connect server to perform login. Do you know if there is another way to authenticate with user credentials over OAuth 2.0?
I believe splitting api and frontend is getting more common these days and I'd appreciate it if you share how you solve this Persistent Login issue and if you drop it completely and force user to re-login every X weeks.
Thanks!
Access tokens and refresh tokens have nothing to do with login with OpenID Connect. These are only for authorizing access to user profile information and for perhaps authenticated service calls to your public API after the fact of login. Refer to the spec for the difference between the ID Token and the Access Token.
If you are going to use OpenID Connect for login, then from what you've wrote so far, it sounds like you need to host your own OpenID Provider (OP) since you want to avoid going to another domain to sign in:
we still going to use usual login form and won't redirect user to another domain in order to sign in.
If you want to be your own Identity Provider, then more power to you. This means that you going to have to deploy your own working instance of an OpenID Connect server, complete with authorization and token endpoints.
Now this is the part where your persistent login comes in. Your browser webapp will be a relying party to the OP server you now have. When a user tries to login to your browser app using OpenID Connect, they will need to authenticate themselves to your OP server. Going through the OIDC flow, your browser app will get an ID token containing an issuer/subject pair identifying the user.
It's up to you to determine how the user stays logged into your OP server, but as long as the user at least authorizes the browser app once:
http://openid.net/specs/openid-connect-core-1_0.html#Consent
then you can save that consent for all future requests by this browser app to login, and therefore maintain a persistent login.
You're going to have to consider how you're going to handle sessions management, but it sounds like you have some cookie thing going already so you might be able to use that (see this answer: OpenID sign in mechanism - Stay signed in ). Otherwise, you're going to end up with a situation where your browser webapp has to get a new id token all the time.
Also as Florent mentioned, there are security considerations you should consider when doing a public client thing that your browser based webapp would be. Example:
https://www.rfc-editor.org/rfc/rfc6749#section-10.16