I have managed to get my IS4 to work with Google authentication for web application.
services.AddAuthentication()
.AddGoogle("Google", o =>
{
o.SignInScheme = IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme;
o.ClientId = "11111.apps.googleusercontent.com";
o.ClientSecret = "1231231";
});
Now, how do I add for mobile application?
I have tried changing the ClientId to use the new one that I got from Google console. Removed the ClientSecret (because for mobile application there is no secret given). Used the same ExternalCookieAuthScheme. And I got an error because "ClientSecret" must be provided. So how do I get this to work?
In this case you are trying to login from IdentityServer via google as external identity provider. From google point of view, the client is IdentityServer. And IdentityServer is a web application.
You should stick to the original client created on google.
For future reference: We need to set the application type to android or IOS when we are trying to login directly from mobile apps.
The client credentials here:
o.ClientId = "11111.apps.googleusercontent.com";
o.ClientSecret = "1231231";
Is only between the IdentityServer and Google and this should not be stored in the mobile client.
The clientid + secret that is used in the mobile application is found in the Client definition for the mobile application in IdentityServer.
Google in this case does not care if the user authenticates with a web application or client application. Google will only see that a user via IdentityServer tries to login. So google is completely shielded from what kind of application is using IdentityServer.
So, in IdentityServer, you can create one client entry for the web application and one client entry for your mobile application.
See the client type in the documentation here.
Related
Using authorization flow and passing the information to the back-channel for the token request we don't need to save the secret in the app.
Why then does Azure force us to use a public type?
Cannot choose for the app to be a 'web' type as the redirectUri is not allowed to be anything other than 'https://foo' which in our case is 'app://auth'
edit: More information
When adding a platform on Azure AD you currently have the option between
web
spa
ios/macOS
android
mobile and desktop application
All of these are public clients except 'web' which can be confidential as the back-end is able to securely store the secret. My question is why is there a difference between web and for example an android application? The android app will communicate the exact same way a front-end application would. But choosing the android app is the only way I can configure the redirectURL for my application
An SPA being public is understandable, but forcing every mobile app to be public is something I do not understand
MOBILE FLOW
This has some differences to a web client. You are meant to use Authorization Code Flow (PKCE) without a client secret, and sign in via a Chrome Custom Tab. See this Curity tutorial for how that looks. Avoid using a web flow for a mobile client though.
MOBILE CLIENT SECRETS
Routing requests via an API that attaches a client secret is not considered standard since an attacker with your client ID and redirect URI could still trigger a flow on app:/auth.
If mobile client secrets are needed then the recommendation is to ensure a different client secret per device. This can be done using Mobile DCR. I don't think Azure supports this however.
HTTPS REDIRECT URIs
In case you're not aware, Android App Links are needed in order for mobile apps to receive authorization responses on HTTPS redirect URIs. I'm pretty sure Azure will support this, and it is a best practice since an attacker cannot get the response. More about this in a blog post of mine.
An "OAuth client" is the application which talks to the Authorization Server. In your case, you don't have a mobile client, as it's in fact the backend which talks to the authorization server. A mobile client should never be configured as confidential. Azure can't assume that all developers will be as thoughtful as you and don't hard-code the secret in their apps.
As #Gary Archer pointed out you should configure your client as a web confidential client and use HTTPS redirect uris as an Android App Link to go back to your app.
Using authorization flow and passing the information to the back-channel for the token request we don't need to save the secret in the app.
It sounds like you relate to a newer Client-Initiated Backchannel Authentication Flow. Azure does probably not support this flow, yet.
Why then does Azure force us to use a public type?
The confidential client and public client terms stems from OAuth 2.
A confidential client is an application that is able to protect its client secret. E.g. a backend application in e.g. Java, Node.js or similar.
A public client is an application that is not able to protect a secret - or where many unique instances exists. E.g. JavaScript Single Page Applications or Mobile applications - this is places where a Secret could be extracted in any client. It is now common to use a Proof Key for Public Exchange when using a Public Client.
Also see What's the difference between Confidential and Public clients? - OAuth in Five Minutes.
I have an angular web app talking to a c# .net web api back end.
They are both hosted on azure app services.
Azure app services offers a suite of authentication services and I've chosen to use google auth.
I've got my google client id and secret setup in azure google auth and my web app correctly shows and prompts me for my google credentials.
My problem now, is that i need my web api back end to authenticate the web app google token. I couldn't find any articles or tutorials that demonstrates the following:
How to get and send the token to the web api? I've read that azure app service should automatically inject the necessary auth headers but any calls to my api do not include those headers. Should i manually call auth/me and add them to the request header?
How do i get my web api to authenticate the details from the request header with google auth? Do i need a separate client id for the web api or should i re-use the web app client id?
Cheers!
According to your description, I assumed that you are using the built-in Authentication / Authorization provided by Azure App Service.
AFAIK, App Service Authentication (Easy Auth) provides two flows: client-managed and server-managed flow. For the server-managed flow, the server code manages the sign-in process for you, and your backend would directly receive the token from the relevant identity provider (e.g. Google, AAD,etc.), then both generate a authenticationToken for browser-less apps and AppServiceAuthSession cookie for browser apps. Details you could follow Authentication flow.
For your angular web app, you could just use server-managed flow, after user successfully logged, you need to call https://<your-angular-app-name>.azurewebsites.net/.auth/me to retrieve the google access_token, then send the following request against your web api endpoint for retrieving the authenticationToken as follows:
POST https://<your-webapi-app-name>.azurewebsites.net/.auth/login/google
Body {"access_token":"<the-google-access-token>"}
After successfully retrieved the authenticationToken from your Web API endpoint, you could send the following subsequent requests for accessing your APIs:
GET https://<your-webapi-app-name>.azurewebsites.net/api/values
Header x-zumo-auth:"<authenticationToken-generated-by-your-webapi>"
Moreover, you could also use client-managed flow in your angular web app, you may need to directly contact with your identity provider (Google) to retrieve the access_token in your client via Auth0 or google-signin or other third-party libraries. Then you may need to both send request to your angular web app and Web API web app for retrieving the authenticationToken as the above request sample.
Do i need a separate client id for the web api or should i re-use the web app client id?
Per my understanding, you must use the same google application. For AAD authentication, you could configure a AAD app with the access permissions to another AAD app.
I currently have two app services
Web App (Asp.net core 2 w/ front end in react)
Web Api (Asp.net core 2)
Note: Both are configured with different Azure active directory app id.
user signs into Web App and retrieves a token for it's own appId/ClientId/ClientSecret stored in tokencache.
from the WebApp, the user wants to talk to a WebAPI but needs to get a token since it's protected with AAD as well but it's a different app id/client id/client secret.
Problem:
When I try to do a AcquireTokenSilentAsync() for the web api, I get an error throwing that I the token is not in the cache?
It also seems that with depending if your using AAD v2.0 or v1.0 will determine if the web app and web api can have different app ids. So it seems like i would have to use AAD v1.0. With Asp.net core 2, it's not clear to me what OpenIdConnect is using or configured to use under the covers.
Question:
It's not clear to me why the acquire token silent async didn't work and failed. Does that only look for the token in the cache; otherwise it fails?
Is it possible to configure the token from web app to have permission to access web api resources. I notice that in the azure portal, you can selected resources like microsoft graph, but I don't know how you would associate a custom API. In my case, I want to get it running on my local machine before I move it all to azure.
If the web app token does not have permission to access the web api, do i need to do another login authentication with the user even thou both are within the same tenant?
Any Advice appreciated,
Derek
Yes, AcquireTokenSilentAsync will look into the cache, and see if it can find tokens. If it does, it will check to see if the access token is still valid and return that back. If the token is expired, it will use the refresh token to fetch a new access token and return that back. When this call fails, it's an indicator you need to perform an AcquireTokenAsync (which will likely show UI in the case silent already failed).
Yes, you can associate a web app to get tokens for your own custom web API. I'd recommend using Azure AD v1.0 (register the app in the Azure portal, ADAL library). You'll need to register the two apps (web app and the api), both will be type web app/api. In the API, you can register an App ID URI which will act as the resource identifier for this API. In your web app, you'll want to go into the Required Permissions, and add the Web API you have registered as a permission. Then in your web app, you'll need to use the ADAL library (alongside an OpenID OWIN middleware) to acquire a token for the resource as specified by the App ID URI field. Here's a code sample that implements the exact scenario you're describing (Web App/API in ASP.NET Core).
I am developing an app to be hosted on Google App Engine. Users will be able to use their Google IDs to login to the app. The app also has a client counterpart in the form of a Blackberry Application.
My question is - is there a suggested way for my app to collect the user's Google credentials so that I can authenticate it against Google using OpenID semantics? In Android, for example, I can use the Accounts API so that I don't need to explicitly ask the user to enter credentials. What's the way to do this in Blackberry?
I see 2 ways, neither of which is ideal:
Write my own form in my native Blackberry app where the user enters Google ID and password, which I then use to obtain the authenticator token and perform the rest of the authentication behind the scenes. But the point is - it is inappropriate to ask a user to trust my app with their Google credentials.
Use standard Google Open ID Authentication mechanism - which opens up the web browser and displays Google's Open ID login page. Although this is a one-time thing (after which I can save the authentication token so that future requests to GAE do not require any prompting for credentials), the user experience is still disruptive since it involves opening the browser in addition to my native BB app.
So, what's the suggested way forward?
Using the browser to authenticate is pretty much the only standard way to do this. A number of Android apps do this for OAuth or OpenID endpoints too. Depending on how the Blackberry's protocol handlers work, you should be able to set a continue URL that results in your app being called back by the browser when authentication completes.
Discovered a problem with connecting all together - Facebook, GWT and App Engine.
I need to authenticate user on my web site hosted on App Engine (Java) that uses GWT. After authentication, some information should be passed to server from facebook - like profile information, user list, etc.
Currently am trying to use facebook4gwt and authentication works fine, and I can obtain all needed information on client side, but can not transfer facebook session to server, particularly, obtain Facebook cookies for session verification.
Could anyone suggest any good solution for this? Probably, it would make sense to get rid of facebook4gwt and do everything on server side.
I have been using the gwt-facebook library for one year to authenticate users of my application on App Engine. When a user is already logged into Facebook, and has already authorized my application, I can automatically get the access_token in GWT and send it to the server which can then do the hard work (data syncing) with facebook-java-api library.