Xamarin Forms, ADAL No Refresh Token - authentication

I have followed the great example on integrating ADAL and Xamarin Forms by Vittorio. I am still struggling though on how to best implement authentication in mobile applications based on Xamarin Forms.
What is the best way to authenticate a user in a mobile application base on Xamarin (forma) knowing that the user is registered in an Active Directory on premise which is synced to an Azure Active Directory? Currently I am using ADAL for that but would it perhaps be better to use Azure Mobile Services? I need a token so that I can authenticate a user in a webapi running in Azure Websites.
When I follow the example of Vittorio, I run into a problem that I don't get a refresh token from the AAD authentication call. I should not that my AAD redirects the real authentication call to an on premise ADFS server. I am not sure if that could be the problem?

for #1 you can use the ADAL sample exactly as is - the only difference is that you need to configure your app to request access to your web API and pass the API resource is when you acquire a token. See setup instructions in https://github.com/AzureADSamples/NativeClient-DotNet.
For the refresh token: ADAL used it automatically from its cache, but people often did not know/understand that and used the returned refresh token manually, doing a lot of extra work... So we are no longer returning the token in the result, but we do use it automatically whenever you call acquiretoken and the token needs renewing.

Related

Using Microsoft.Identity.Web to authenticate users for WebApp+API, and how to manage lifecycle

I'm trying to create a webapp that uses multi-tenant Azure AD for authentication & authorization. I'm trying to follow the docs, using Microsoft.Identity.Web, and the pieces aren't clicking for me.
I've been able to successfully create a web app where users are able to login, get redirected back to my site, and get an id_token saved to their browser cookies so the web app is able to tell who they are. However, my web app also contains APIs itself, and it isn't clear to me how we're supposed to obtain an access_token, as well as manage the lifecycle by way of refresh_tokens, for calling APIs on the web app itself. In fact, refresh doesn't seem to be covered at all in the docs for Microsoft.Identity.Web.
Instead of the dedicated SDK, I've also tried using AddCookie()+AddOpenIdConnect() (the more generic solution). Using these middleware options I've successfully been able to obtain an id_token, access_token, and refresh_token. (Which seems to connect all the pieces of access, and refresh/lifecycle.) However, all of those tokens take up a fair amount of cookie space, and cause 431 Request Header Fields Too Large errors from Kestrel without customization.
It's clear that the intention is for access/refresh tokens to be stored server-side on some sort of in-memory or distributed cache. However, the documentation doesn't seem to outline how to deal with "web apps" that ALSO contain API controllers, and furthermore doesn't seem to outline how to deal with token refreshes in general.
Does anyone have any better in-code examples of how to configure a WebApp that authenticates users with Azure AD, and also properly handles refreshing the id/access tokens using the refresh_token?
Refresh tokens are automatically handled by MSAL.NET, which is used by Microsoft.Identity.Web.
We suggest you have a look at the following sample: https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/4-WebApp-your-API/4-3-AnyOrg but you would have the same clientID (and app) for your web app and web API.
Please also look at https://github.com/AzureAD/microsoft-identity-web/wiki/Mixing-web-app-and-web-api-in-the-same-ASP.NET-core-app

How is it possible to authenticate an application using Azure AD

I'm trying to setup an application to validate identity using Azure AD and acquire a token to allow access to a secure api. The front end application is written in angular and allows anonymous access. What can I use to access AAD authenticate and return an access token?
This will be an angular 6+ UI that is communicating to a secure .Net api using Azure AD for authentication. I have done a couple days research and everything points to a user logging in to authenticate using the login page. I need it to be by app and open the login page. I tried a couple examples where it utilized authentication/authorization and that didn't work because the app needs to authorization the user to talk to the api. I have seen where people were using Microsoft graph but once again it was user based and they were redirected to an azure login. I am looking for a solution that will allow me to setup an account in azure ad and authenticate the app on start to get an access token to allow communication to my secure api. If I have missed something somewhere in my research and test attempts let me know. This is my first Azure AD auth attempt and I feel like I am missing something for application authorization.
The problem is an Angular app is what we call a public client.
It cannot hold secrets and thus cannot prove its identity.
So, only user-based authentication flows should be used by public clients.
Confidential clients on the other hand can hold secrets as they run on servers that you control.
So for example, a back-end Web application or API would be a confidential client.
Those can use the client credentials flow to acquire access tokens and call APIs as themselves without a user being involved.
There is a bit of a fundamental issue in your question.
Your API requires authentication, but you want functionality to be available to anonymous users.
So you want to bypass authentication.
If you really want to bypass authentication for parts of the API, you could just make those endpoints available anonymously without a token.

Validate external token asp net core

I'm doing a mobile app in Xamarin Forms, which should be able to connect to an ASP.NET core web service (API). I also want the information on the web service to be secured by limiting it to Microsoft account signed-in users. The idea I had was to send the user's credentials and retrieve back the security token from the Microsoft graph within the mobile app. Afterwards, the user would send that same bearer token to the web service, which checks its validity, and grants the requested information only if the validation is successful.
I am new to web development, so first of all, I want to ask if I am using a good approach for my project (if not, what do you recommend?).
If it is, how should I set up the ConfigureServices function in my Startup class? When I include the [Authorize] tag in the controllers, the service crashes, telling me I should define an authentication scheme. I don't need authentication, only authorization (since authentication is done from the mobile app), Since these two are handled independently in asp.net core, I added a dummy jwt authentication scheme as a placeholder. However, when I send an http request with the security token from my mobile app, it gives me a 401 unauthorized error, telling me I'm sending an "invalid token" (this token works fine when connecting to the Microsoft graph).
I've searched in countless documentations, but all of them only consider scenarios in which the authentication is done within the web service, and not externally, like me.
Any help is appreciated

Browser and Webserver api authentication tokens

I am currently working on a solution that includes a multi tenant webApi which will be accessed by multiple clients, some of which i will be creating, some of which others will be creating.
Access to the api will be available via an ApiKey & Secret (enough for some resources) as well as username & password (for owner resources).
At the moment, the clients i have created (.Net MVC Web apps) have their own membership systems so what happens is the user of the client logs into the client system and the client system passes the login information to the Api to retrieve an authentication token.
The client membership system is really an unneeded abstraction. What i really want to do is have the user log directly into the api and the api pass back an authentication token that can be used from the browser as well as the .Net MVC client app.
My question is, what it the best way to achieve this. In my mind i seem to be struggling with 2 solutions.
1) Have a browser based login (ajax/AngularJS for instance) solution that calls the api to retrieve a token which then passes that token onto the MVC client where it will be stored (session variable maybe). Any future calls to the api that come from the .Net MVC client can pass the token on. This seems wrong to me though. I'm not even sure this is possible.
2) Utilise one of the OAuth flows so that the browser based login can call the API and retrieve a token, and the OAuth flow redirects to the MVC client which then stores the token for that user (again, in a session variable).
The Api was generated using the VS2013 WebApi template using Owin local accounts and is generating tokens via the ValidateClientCredentials and ValidateResourceOwnerCredentials flows, but i think i need to use one of the other OAuth flows for this scenario.
I understand that another solution would be to bypass the .Net MVC client code and create a completely browser based solution using knockout or AngluarJS but it's quite a complex system and i don't really have time to do this at the moment so i'm looking for a solution that would allow me to retrieve a token from the api that can be used from my .Net MVC client and ajax calls from the browser.
Any ideas, advice would be much appreciated.
thanks in advance. Justin
If you'd rely on Azure AD as your credentials store and authentication system, you'd be able to leverage a ready to use JS library that handles authentication, AJAX calls and session management concerns automatically: see http://www.cloudidentity.com/blog/2014/10/28/adal-javascript-and-angularjs-deep-dive/.
If you can't rely on Azure AD, the code of the library and samples mentioned above can still have value as a reference to build your own system - provided that the authenticaiton system you decide to use offers similar capabilities.
HTH
V.

How to authorize mobile apps with a third party by oauth BUT connect to my service, not the 3rd party

My app is architected as follows: I have a web service (running on GAE, not very relevant to this question) and the data that this service contains is made available through a website and through mobile and desktop apps.
Currently, the user authenticates to the website via Google ClientLogin and the apps authenticate/get authorized via GAE's built-in oauth provider. (OAuth is being used here mostly for authentication, my app doesn't actually use any external data via OAuth other than the user's unique ID and email address.)
What I'd like to do is expand the number of services that users can use to login. Because of the complicating factor of the apps, it seems I need OAuth. But I can't really properly conceptualize how this flow should go.
Lets take Facebook as an example. When a mobile app goes through the Facebook oauth flow and acquires an access token, this isn't enough - because its my service, not the app, that actually needs to talk to facebook to retrieve contact info and a unique user ID. This leads me to think that the OAuth process needs to happen in the context of my service, and not the mobile app. My service then becomes the consumer and Facebook the oauth providor, and the service holds on to the oauth access token, this happens when a user sets up their account for the first time.
If this is the correct approach, where does that leave authentication for the apps? What happens when the user already has an account and installs a fresh instance of a mobile app? I imagine also going through the oauth process, matching up credentials with the data already stored by my service, and then issuing my own "access token" to the app from the service, to authorize that instance of the app. This seems convoluted and hackish.
I'm sure I can't be the only person who is in effect "borrowing" the account system of a third party for a mobile app with a backend, but I really don't see what the proper way to do this is.
What am I not seeing and/or getting conceptually wrong?
A few colleagues and I once did a project quite similar in nature, back in university. We authenticated our users through either Facebook or Foursquare, using their respective OAuth APIs.
The native Android version of the app opened up a WebView with the OAuth provider's start page, which redirected back to our service after authentication. Then our service did a request for the OAuth token from the OAuth provider (Foursquare has some pretty simple instructions). When we got that token, we set up a session using cookies, which we could access from the app.
To validate sessions, we just checked whether the access token was still valid with the provider. We also used the respective providers' unique user IDs to distinguish users.
So yes, what worked for us is: Make the app authenticate & authorise your service, not the app itself.