Too many auth dialogs when using ADAL.JS on my portal page with cookie auth to call my WebAPI that uses JWT auth - ajax

I have the following setup:
1) WebAPI that accepts JWT Bearer tokens for auth.
2) Portal (WebApp) that puts a nice face on the json output from this WebAPI. It does OpenIdConnect authentication and uses Cookies to persist login information. It is an ASP.NET Core MVC app.
3) The WebAPI and WebApp are on different domains.
4) The WebAPI layer is designed to be called by any 3rd party who can present a valid token - either via App auth (client_credential flow, for eg) OR Delegated User auth (implicit flow, for eg). The WebAPI also does RBAC auth.
At this point, the problem I have is this:
1) I want to be able to make AJAX calls from the WebApp controller pages (cshtml) to my WebAPI so that the pages are responsive and there are no POSTs. So I integrated ADAL.JS into the page for that purpose. It works from a functionality pov.
2) HOWEVER, this results in multiple authentication dialogs (web page popups).
-- 1st auth popup. Upon navigation to the Portal homepage, I get challenged and have to enter my credentials on my company login page (federated AD auth).
-- 2nd auth popup. Then when I invoke anything on the Portal pages that involves ADAL.JS (namely the AJAX calls), it causes another login dialog because ADAL.JS cannot see the login cookie from ADAL.NET layer. This dialog comes up and goes away without any input needed tho (because the cookies from (1) are sent along to the server automatically by the browser). At this point, I have the ID_TOKEN and an ACCESSTOKEN for the PortalApp's client_id show up in the ADAL localStorage area.
-- 3rd auth popup. Then another dialog pops up; it uses a Hello pin login (I assume this is due to 2-factor auth requirement enforced by my tenant). At this point, I see the ACCESS TOKEN for the WebAPIApp's client_id show up in the ADAL LocalStorage area.
And now my AJAX calls start working.
Is there a better way to do this so that I can get the benefits of AJAX and not have to resort to serverside POSTs and have only 1 auth dialog instead of 3?
(I thought of may be switching ALL authentication to be done by ADAL.JS for the entire site, but I like the paradigm of using the [Authorize] flags and RBAC for the Controllers. OR is there a way to make my WebAPI accept both JWT and Cookie authentication?
Thanks!

Related

spring oauth2 authorize flow in single page app

I am implementing an oauth2 authorization server for providing access to our apis.
Our application is a single page application, with the a jwt token in the authentication header to provide access.
We want to setup an oauth2 Authorization Code flow like,
User is on external site and wants to get access to our apis
External site redirects to our site/spa with oauth2 params, client_id etc.
SPA checks authentication, users needs to login to continue
User sees page for confirming access
User confirms access, code is returned and redirected to external site
External site does backchannel call to obtain token from code
My problem is in 4 and 5, in standard Spring setup this is provided by
org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint,
on /oauth/authorize GET oauth params are stored in the session and the confirmation page is shown, and on post of that the code is returned in the redirect.
But I cannot find any guidance/examples on how to do this with a page hosted in a SPA.
You have to be authenticated in this endpoint and I cannot really use the top level page that /oauth/authorized provides because we use header based authentication on rest api calls only, all our top level calls are unauthenticated.
Is there some obvious way to make this work?
I think I do not want to put my authentication token in a cookie.
I was thinking of just then creating a controller that sort of does what the AuthorizationEndpoint does and returning a redirect to the redirect in Javascript. But I am not sure if I would be breaking some other security requirement.

Authenticate MVC clients with Web API Tokens

Currently I have created a WebAPI Project using identity framework and I have setup tokens to be returned when authenticating with the API.
So now I am looking at creating a standalone MVC application that will allow the user to make calls to the WebAPI to get back end data.
The goal is to separate functionality so that other applications can also start interacting with back end data through web calls.
So the confusion now is how do I setup my MVC project so that I can use the Authorize attributes on controllers with the token received from the WebAPI. I think I need to enable bearer tokens in the ConfigureAuth method in Startup.Auth.cs. However will that be sufficient enough? Or do I also need to enable the cookie authentication?
MVC and Web Api are fundamentally different when it comes to authentication. With Web Api, the bearer token has to be set in the header of the request, but this is not an issue as all API requests are done programmatically by the client, i.e. there's human-intervention involved in setting up the client to authenticate the request properly.
MVC is a different beast in that the actions are accessed generally via a web browser, which will not automatically affix a bearer token to the request header. What it will do is pass cookies set by the server back to the server. That's why cookie auth is used most typically for MVC web applications.
What you should do is enable cookie auth for the MVC site and then set up your sign in action to authenticate via the Web Api. When you get back a valid auth from the Web Api, then you can manually sign in the user via the Identity API:
await SignInManager.SignInAsync(user);

(Ajax) Authenticate MVC Website user using a WebAPI

Trying to search for this results many many results for securing a WebAPI and how to secure an MVC application, but i could not find a solution.
What i want to achieve:
i have an MVC website with a modal Login form,
When the user enters he's credentials to the the form, an Ajax request is sent to a WebAPI with the credentials.
The WebAPI should return (i guess a ticket, since that is what i found).
The ticket would be then saved into the sessionStorage of the browser (no cookies),
Each page request to the website will check for the token, and enable/disable the parts that need to be secured.
All the examples i have found are showing either MVC only authentication,
or WebAPI authentication, but i could not find anything that does the described above.
The sessionStorage is available only for client-side use. You can manipulate or retrieve values from the storage using Javascript, but you can't directly read data from the server. Since MVC typically renders HTML Views server side, you have no options to send the token stored in the sessionStorage on each request.
The situation you described is an hybrid solution which can't be achieved without the use of cookies.
A simple solution is to set the login data (specifically the token if you will use a token-based approach) in a cookie issued by the Web API endpoint during the login phase.

Using Facebook-SDK with OWIN/Katana

I want to use Facebook-SDK login popup at my SPA WEBAPI application with OWIN. VS 2013 already provides a great template for facebook login but it highly dependent on server side codes which i don't prefer.
By using Facebook-SDK, i can login to facebook and access the user_id, access_token etc., after this point, i send the access_token to /signin-facebook?code=[access_token], however, i get access_denied error. I guess it is because i intervene the owin workflow and don't send correlation cookie.
To sum up, is it possible to bypass first 3 steps in the login flow in this picture if I already have the access_token?

Authorise users using MVC identity using PhoneGap

I am using the standard MVC 5 identity membership so users can be authenticated to use features on my site. Apart from login and register, ALL actions require someone to be logged in.
I want to use PhoneGap to take my mobile ready html and turn it into a mobile application. I intend to use ajax to do all calls to my actions.
How do I do this with the html pages not residing on the same server? How can I log someone in, and then allow them to make calls?
Authenticating users from mobile devices is fairly simple with the new MVC 5 identity membership. Essentially, every HTTP request that is made to your server from a device will include a bearer token to authorize that request.
When your Web API method receives the request, it will identify the user making it via the bearer token. This allows you to use the standard Authorize attribute in your Web API controllers that I'm sure you're used to using in MVC controllers. Here is a basic example of this process, but essentially it goes like this:
Request containing username and password is made to your server.
Server verifies the username/password and sends back a bearer token
Make another request(s) to your server to access data or other functionality, and include the bearer token in each request
Assuming you're doing this from a mobile device, some options for storing the token are HTML5 local storage, SQLLite, etc. There is no "logging in" doing it this way - there is only authorization of requests to the server. Of course, the user doesn't know that so it's very easy to simulate a typical logged on experience. Here's a brief example expanding on the one one above:
Create a standard login screen with fields for username and password and a login button
User fills it out, and when they click login you make an AJAX call to your server requesting a bearer token with the user's entered credentials (should be over HTTPS)
Server authenticates the credentials and you get a bearer token back. From the user's perspective, he is now "logged in".
One way to handle the bearer token from here is to store it in SQLlite or local storage so that is readily accessible for you to grab and include in any more requests to the server that you make. You just have to take into account that the token has an expiration (set by you, see that link I posted), and design your app accordingly. You might want to tighten down your security by only keeping the bearer token on the mobile device only so long as the user is using the app. When they're finished, you remove it from the storage on the device and the user must go through the authentication process (i.e "log in") again when they open the app.
Additionally, this video Securing .Net Web APIs is definitely worth watching.

Resources