Refreshing id token using 'prompt=none' does not support redirect URL with custom scheme in Azure - xamarin

We are creating a Xamarin Forms app, only Android for now, which connects to a web API also created by us (ASP.Net Core). I have managed to get OpenId Connect authentication working by:
Using Azure as the identity provider.
Using Android custom tabs to show the Microsoft's login page.
Detect when the custom tab is redirected to our redirect URL.
Get the id token and use it as the authentication bearer token sent to our web API.
Using JwtBearer authentication in the web API.
The problem appears when the id token expires. We want to get a new one without asking the user any question.
To do that, we repeat the authentication process by adding the prompt=none, id_token_hint=THE_TOKEN and login_hint=THE_USER parameters in the authentication request, as defined in the OpenId Connect specification, and supported by Azure.
During that request, we have an issue with the redirect URL:
If the redirect URL has a custom scheme (like myapp://...) Azure responds with an interaction_required error.
If the redirect URL has an HTTPS scheme, then Azure responds successfully (including the necessary parameters to continue the process), but I am not able to detect the redirect URL in the Android custom tab. So my app gets stuck in the custom tab trying to load my invalid redirect URL.
The explanation for #2 is that HTTPS URLs are handled by the browser (Chrome in this case), so it does not trigger any action that I can detect from my app. This seems reasonable.
I also tried to detect custom tab navigation events from Xamarin, trying to detect the event "manually", but failed. Such events are never triggered.
Now, as for #1, I do not have any reasonable explanation. So my question is:
Is there any way to make Azure accept a redirect URL with a custom scheme when trying to refresh an id token by using the standard prompt=none OpenId Connect parameter?

Related

Read browser URL from Xamarin form android for custom OAuth code sent from the IDP in redirect URL

I am trying to implement custom OAuth login into my Xamarin application.
I am hitting the OAuth API from browser when a Login button is clicked.
It is redirecting to my custom OAuth authentication page and after initial authentication it sends an auth code in the URL of the auth.html from my domain page. I need to read that URL and process further.
My code in the button click :
var apiEndpoint = "https://auth.example.com/oauth2/authorize?response_type=code&client_id=myclientid&redirect_uri=https://example.com/apps/auth.html&state=STATE";
await Browser.OpenAsync("apiEndpoint", BrowserLaunchMode.SystemPreferred);
I need to read the code from the URL when is is returned from my domain redirect uri as below:
https://orion.lexmark.com/winapps/auth.html?code=12358123-2200-4ga6-a806-8f60f5636ac8&state=STATE
I am very new to the xamarin world, any help on this will be appriciated.
The most common way to do mobile OAuth is to use a Private URI Schene URL such as this, which will then invoke the app with the login response when it is returned to the browser:
com.mycompany. myapp:/callback
It is standard to also open the URL via an integrated form of the system browser - a Chrome Custom Tab on Android.
Developers usually also plug in the open source AppAuth libraries to do the tricky work of using OAuth messages correctly. This will be harder in Xamarin though, due to the extra layers.
I would recommend having a look at AppAuth and at least borrowing some ideas from it. My Android AppAuth Blog Post explaims a fast working setup.

How do I secure a Web API with Azure AD B2C

I have a Angular application and a separate Web API solution built with .NET Core. I have successfully setup authentication with Azure AD B2C. I am able to login to the angular application. However I would like to secure one of my Web API calls. i.e. http://localhost/Profile/GetProfile. The trouble is that I'm able to query this url successfully even when not logged in.
I used code from the sample application in github and strangely I get 401 not authorized when trying to make my api call from my ClientApp. However, I am able to open that url successfully in a new tab (outside of my application). I am trying to achieve the opposite of this. i.e. it should 401 from a browser but 200 from my ClientApp. What am I doing wrong?
BTW the sample application throws a unhandled exception when trying to navigate to the todo menu item.
The trouble is that I'm able to query this url successfully even when
not logged in.
This is because the cache is still there after you successfully log in. Once you've used browser privacy mode, you'll need to log in again.
And is these screenshots below what you want to achieve? You can decode token in this.Whether the requested token is successful does not match the api endpoint.If so,please check your client app (API perssions) & server app(Expose an API).
401 from a browser
2.200 from my ClientApp.(Here's a microsoft graph me/endpoint demo.)

How to provide login authentication for Web API in Xamarin App?

I am working on Xamarin Forms application and new to providing login authentication of the application. I have completed the design part of the application with using Entries for user id and password and button for Submit. Also, i am having web API and for authentication. Now how to connect that Web API in xamarin forms application for login.
Please guide or provide some use full samples...
Thanks in advance...!
I assume you've built out your authentication API already, and that you can make Fiddler or Postman calls directly to your controller, pass in a set of credentials, and return back a JWT / bearer token that you can then use for authenticated calls?
At this point, it's relatively simple then as you'll want to use build a proxy layer / API layer to make calls out to your API. These calls will simply mirror the ones you've made in Fiddler/Postman/your proxy of choice.
I used Refit to achieve this:
https://github.com/reactiveui/refit
Specifically, you can see on the "Setting request headers" section how they easily encapsulate it for you to pass your token.
Of course, your initial call should be to login, and then once logged in, take the JWT response back from your controller, set the token in your Keychain, and then pull it out of Keychain to set in the header.
Let me know specific questions you have? For example, which of the following do you need more info on?
Sending and parsing a response (serializing the response) from your Login action to set/assign a token in keychain?
Saving the token, and setting it in a header for subsequent calls?
Building a proxy layer using a framework like Refit to make generic outbound calls?

Working with SSO: Ajax request

I have a web application and API Server, the web application consumes API always via AJAX except in a couple of scenarios.
When I enable SSO for both, I face the well known problem - how to handle redirect in AJAX.
(A bit more details: Azure mandates that the user should login to AD only via its login page - so ideally when a webpage or an api endpoint is accessed, they should get redirected to the azure login page. Since HTTP302 redirect doesn't work well with XmlHTTP, user will not get redirected to the authentication page when API is accessed via AJAX)
I have a few options to solve this issue:
When the web application is authenticated redirect to a predefined api endpoint (eg: 'api/login') and that will take care of api authentication and once that is done, redirect it back to the web app. So the user will be redirected this way:
web -> azure login -> web -> api -> azure login (auto login) -> api ->
web
Load the api endpoint in an iframe (or an image) and wait for the load complete event
Authenticate only web application - Remove api from sso context and find some other of way to identify and validate the web request at API side (tokens, cookies)
Please help me to choose a right pattern.
AJAX follows redirects automatically:
How to prevent ajax requests to follow redirects using jQuery
Detecting a redirect in jQuery $.ajax?
You need to distinguish between the reply from the service and the login page, which you get after AJAX follows the redirect (but not with safari+cors!). For example, detection could be done by checking for a string inside of response body. When detected, just redirect user to the login page by document.location=<login-page-url>.
Another option would be to use a token inside of "Authorization" HTTP header instead of SSO for backend-service protection:
https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/

How to detect in a SPA application (client-side) if a Windows ACS session expires

We are building a SPA application using Durandal and we are authenticating the users via Windows ACS in Windows Azure.
We currently have a problem with users who leaves their applications open for a long time. When they come back, the ACS token is expired and the application won't redirect to the ACS login (since it is a SPA application).
Is there a good way to detect on the client side when the Windows ACS session times out?
I don't know Durandal, but I know all Ajax calls feature (optional) error handlers in which you can test whether the server status code is 401 or 403.
(that's usually the case when the user tries to access a secure resource when he is not authenticated).
All you have to do is redirect the user to ACS with the correct parameters when this happens.

Resources