I have a combination Web API and MVC application that is secured using Azure ACS, Windows Identity and passive redirects. This works well. Now I am adding a mobile application using PhoneGap that makes calls to the existing application's API. I having trouble figuring out how to implement authentication on the mobile client. I've got it mostly working, but I can't get the token to client due to the Return URL setting in ACS. The scenario is:
Mobile client sends get request to API
API responds with 401 if user is unauthorized
Client redirects to ACS login page and user authenticates
Token is sent to the Return URL which is the application running on a web server
For example, if I'm running the client app on localhost:63327, the token is sent to localhost:58392 because that's what is set as the return URL in the ACS configuration.
How do I get the token to my mobile client?
I see that people did not really understood your question.
This solution might work.
In a nutshell, is to add a new protocol to get the authentication token from the server to the app client.
PG App calls a web method registering a request to Auth:
POST BeginGethAuthToken
id = pickup Guid
pswd = pickup Password
BeginGetAuthToken can be a web method in your login page.
Server associates the pickup guid with the pickup password
PG Apps start the authentication flow by opening the log-in page using the InAppBroser
mywebapp.com/AppLogin.aspx?id={pickup guid}
The pickup guid is set as a cookie for your webapp domain.
User completes the authentication using the InAppBrowser.
AppLogin.aspx on successful authentication associates the pickup guid with the authentication tokens and ask the user to close the browser to go back to the app
the PG App picks up the authentication token by providing the pickup password.
note that for security the server needs to add expiration policies of pickup guids such that only one app can use a guid at a time and restart the process in case of collisions.
You effectively need to pre-authenticate your client. See http://blog.siliconvalve.com/2013/06/25/protect-your-asp-net-web-api-using-azure-acs-service-identities/
Related
Suppose that I have a mobile app with a frontend and a backend server.
My understanding is that -- when a user logs in the app with "Login with google", the frontend sends a request to the google auth server, and gets back an ID token. The documentation says that the frontend can then send the token to the backend server to establish a session. I imagine that means the token can be used in session-based authentication?
If I were to use token-based authentication (as opposed to session-based), do I just attach the ID token in every server request, and have the backend verifies it each time when processing a request? this page suggests the ID token should not be sent to the backend API. Which leaves me wonder what the correct procedure is for token-based authentication when using log in with Google.
So my question is: Does my server need to create an access token from the ID token from Google, and send it to the frontend, so the frontend can attach that access token in the API requests for authentication?
Thanks
Login with Google is an identity provider (IDP) operation. A full OAuth solution, including an authorization server (AS) looks like this:
Mobile app uses system browser to redirect to AS
AS returns a redirect response to the system browser, which routes to the IDP
User signs in at the IDP
IDP returns an authorization code to AS
AS swaps it for IDP tokens and carries out validations
AS issues a set of tokens to the app. This includes an access token (AT) with whatever scopes and claims are needed for business authorization to work.
Mobile app sends AT in API requests
API authorizes using scopes and claims from the access token
So ideally plug in an authorization server, to get this out-of-the-box behaviour. Another option is to implement your own token service, and issue your own tokens. That is less recommended though, since it requires more detailed understanding of the underlying security.
I have a requirement to authenticate ASP.NET Core App via Google Sign In, but a Web API between client app (i.e. ASP.NET Core app) and Google sign in... I know it sounds confusing, so let me explain it with diagrams.
Here is the typical way to include google sign-in button and get user authenticated via their google credentials, It works perfectly fine
Step 1: First, create a new app on google identity developer portal, generate ClientId, ClientSecret and specify redirect_url like : https://yoursite.com/signin-google.
Step 2: In the Startup.cs class of ASP.NET Core project, Use AddGoogle as authentication middleware and it works perfectly fine.
Including diagram below for your understanding:
And here is the proposed flow. With a REST API in between client and google sign in. Question is, how do I authenticate client ?
From what I understand, you want your Client Application to invoke the REST Service on behalf of the user. The REST service needs assurance that both the Client and the User are authenticated.
We have achieved this using the OpenID Connect Hybrid flow. The bad news is that we had to add another service to the solution to achieve this.
How this differs from your proposed solution is this:
You must have your own identity service, and this must know of the existence of the REST service, the Client Application, and the User Identity.
The Client Application redirects the user to authenticate with the Identity Service (which further on redirects the user to authenticate with Google)
Identity Server provides the client application with an ID token for the user, and also a code which can be exchange for an Access Token
The client application requests the Access Token. This Access Token will authenticate both the client and the user
The client application then authenticates using this access token when invoking the REST Service
The REST Service issues a one-off request to Identity Server for the signature keys, and uses these keys to validate the access token.
We happened to use IdentityServer4 when implementing the Identity Server, but the protocol exists independently of any one implementation.
I'm working on a personal project composed of an API and 4 clients (web, android, iOS, windows phone).
I'm using django-rest-framework and oauth2 toolkit on the API side and I wonder which grant_type would be more suitable in my situation.
I read somewhere that the implicit grant_type is appropriate for working with mobile clients.
I'm currently using the resource owner password credentials system.
My current workflow is:
The user creates an account on the API registration page (http://mysite/api/register) then gets redirected on the web client.
The user have to authenticate himself on the API from the web client (the secret and client ID are store in the web client). If the authentication is successful the access_token and refresh_token are both stored in the user session.
Each time the user want to access a page I verify if he is authenticated by requesting the API using his access_token. If the request fails, I retry with the refresh_token. If it's fails again I redirect the user on the auth page.
The user can use the API on a mobile client with the same account without extra manipulations (the secret and client ID are store in a secure location ex. share preferences or keychain)
I like this workflow, it's simple and convenient for the user: he registers once and can use all the clients and I get a perfect separation between the logic (API) and the UI (client). But I'm worried about the security of this system. I don't want to expose my users to threats. Do you guys have any thoughts, recommendations, suggestions?
You help in this matters would be very appreciated.
Thanks in advance!
I'm developing a private API for a mobile app. I plan on securing and authenticating logged in users using JSON Web Tokens.
When a user authenticates and logs in to the service, the server will return a signed JWT in the response. The device stores this securely and sends it back as an HTTP Authorization header in every subsequent request.
So far so good. However, where I'm a bit puzzled is this: the token is generated for a new user when their account is created (ie they registered). This API endpoint (POST to create) is open and there is no token verification (naturally since it's a new user).
How can I ensure that POST requests to create new users are only authorized from the mobile app? In other words, if a malicious user sends POSTs to create spam users, how do I recognize this?
The API is over https. Though, even if I were to require the app to use an API key as a query param, that would expose it on the wire. I suppose I could pass in a Basic Header with a hashed API key/Secret.
What is a way to do this securely?
Edit: How to protect the 'public' part of a REST service from spam?
The model for our product is like this:
Api backend (headless)
I already have oauth set up and ready to use with a resource owner credentials grant. Anyone who wants to use our api can do so using either an API key or their username/password. Of course they also need their client ID and secret.
SPA frontend that accesses the Api
I have built an SPA that will uses the api to provide a portal GUI for our clients. Given that this client-side app is owned and administrated by us (so it's a trusted app) how can I safely authenticate users using only username/password with oauth?
Originally it was using a JWT auth system that only required username/pass but now that we've implemented oauth I'd like to consolidate. It's unreasonable to make every user need to also have their client id and secret on hand to login, but I want users to have full access to the api from the GUI.
I've looking at using CSRF tokens but how would that work with my app when nothing is generated server-side?
I'm not sure how to proceed.
EDIT: very similar to the problem here.
I have decided to use the solution described here.
And here is a snippet of my implementation
The TL;DR version is
Create a proxy between the app and the api
Store the client ID and secret in the proxy
App logs in using password grant type -- proxy intercepts login request and inserts client id and secret
On login response proxy returns access token as an encrypted cookie
Client stores cookie and sends with api requests (to proxy)
Proxy decrypts cookie and inserts access token into Authorization header before forwarding to api endpoint
For me this has several advantages over implementing something custom on the api itself:
No need for custom grant on oauth server
ID/secret is hidden from app securely and can still use password grant
oauth server can identify client (no need for separate client ids for each user)
You should not use the resource owner credential grant from a JavaScript application. The fact that you own and administer the application does not make it a trusted application.
A trusted client is an application that can keep a secret. SPAs or any JavaScript app cannot keep a secret.
You should use the implicit grant for non-trusted clients.