Getting logged in user from web api - authentication

I have a web app front end and web api back end both written in ASP .Net Core 1.1 MVC. I am using Auth0 as the authentication server, using the "authorization code grant flow".
So the user logs in - i.e. the user gets directed to Auth0's login screen, which, if the username and password were correct, sends the web app back an authorization code, which the web app then exchanges for an access token, which is then used for all web api calls.
Then, the user clicks on a link which makes the web app call upon a web api action. My question is, how can the web api know which user is making the request? Or maybe at the point the user successfully logs in, the web app should call upon a controller in the web api and tell it which user just logged in? Not sure what the best practice is...
Thank you

I will answer in terms of OAuth 2.0 specification.
Specification determines 4 roles:
Resource owner
Resource server
Client
Authorization Server
In your context:
Resource owner is end-user.
Resource server is your Web API.
Client is your web application.
Authorization Server is Auth0.
Follow steps:
Your Web API should be registered on Authorization Server
(https://auth0.com/docs/apis).
Your Web API should be responsible to validate access tokens that
are used for requesting API. This access tokens contains info about
end-user/client (https://auth0.com/docs/api-auth/tutorials/verify-access-token).
You should include Web API scope in authorization request.
You should get access token in your web application and include it in HTTP request to Web API.

Related

How to secure Web API with Auth0 without exposing ClientId & ClientSecret to client?

I am creating a new .Net Core Web API that is consumed by a new React client-side app. Both the client-side app and the Web API are on different hosts and protected by Auth0. I set up both the client-side app and the Web API in Auth0, and then I created a machine-to-machine app in Auth0 to be able to communicate with the Web API silently (without a user interface). The security flow works like this:
User tries to access client-side app.
User is re-directed to Auth0 to provide credentials.
Auth0 authenticates the credentials and returns user info (including user ID + access token) to client-side app.
Client-side app stores user info in local storage for future use until it expires.
Any calls to 3rd party APIs are routed through my own Web API, so 3rd party API keys are sitting in a safe place on the server, not on the client-side.
User accesses a page that requires a call to my Web API but we don't have an access token for my Web API yet.
Client-side app reads the ClientId & ClientSecret (hard-coded values) from .env file and makes a POST request to Auth0 to fetch an access token for my Web API (this is Auth0's recommended way of getting the access token for the Web API silently except they don't specify where the ClientId & ClientSecret would be stored).
Auth0 returns an access token for my Web API.
Client-side app stores the Web API access token in local storage for future use until it expires.
Client-side app invokes my Web API with newly acquired access token as the bearer token in the header.
Web API receives the access token, authenticates with Auth0 and fulfills the request.
All of the above is working for me but I am concerned about storing the Auth0 ClientSecret of my Web API in the client-side app. Although it is not visible on the screen or in a cookie anywhere, any capable user would be able to get at it by inspecting the network traffic.
Many people on the Internet seem to be fine with storing 3rd party API keys in .env files while others advise routing 3rd party API access through your own Web API ... and I am doing the latter. But I still need the Auth0 ClientSecret to get to my own Web API and I cannot figure out a better place way to get to it without storing them somewhere on the client-side.
One last-ditch solution I can think of is to not protect my Web API through Auth0 and instead every call from the client-side app to my Web API should include something unique (like the user ID from Auth0) that can be validated by the Web API. Thankfully, the user ID from Auth0 will be stored in our database when the user is set up initially, so this is actually possible.
Does Auth0 have any other way for me to get the Web API access token without providing the ClientSecret given that I already have the client-side app's access token? I am curious to know how others have secured both their client-side app and their Web API through Auth0.
You are correct, you should not include the client secret in your client-side app. Do not use a client credentials flow, instead use a auth code + PKCE or implicit flow.
With that being said, Auth0 should handle most of that if you are using a library or SDK.
You have two options for getting the token:
When requesting the initial access token and ID token add the Web API as an audience and request the related scopes.
Make a silent request using the checkSession function for Auth0.js or getTokenSilently for auth0-spa-js
Take a look at this:
https://auth0.com/docs/architecture-scenarios/spa-api/part-3

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

Web app ClaimsIdentity in Webapi

I've created a mvc web application that uses openid to authenticate with Azure Ad and get the claims along with the token. I'm interfacing with Web Api to do the business transactions. The web Api is configured to oauth bearer tokens.
I've created separate oauth clients in Azure Ad for the Web App and Web Api. I'm able to get a token for Web Api from the Mvc Controller using AuthenticationContext to send to request to Web Api. I need to know how I can send the current User Claims as well to the Web Api. The claims in the Web Api are not having the claims of the User from the Web App.
Let me provide a bit more context here. I've created a MVC Web Application and a Web Api layer. The MVC Web App is configured to use OpenID authentication using Azure AD and I've configured the Web Api layer to authorize using OAuth Bearer tokens. The actions in the Web Api layer will be called through ajax requests and the bearer token will be added to the header of each Ajax requests. When the User is authenticated in the Web App, additional claims are added to the User on top of the claims from Azure Ad. I'm able to create a token for the Web Api layer using AuthenticationContext.AcquireToken, but the token for Web Api does not have the User info from the Web App.
I'm taking a wild stab in the dark here, based on what I think is happening.
Claims are attached the user, so theoretically, any claim you add in one place should be available in the other, as long as both applications share the same user datastore. However, claims are loaded at the point of authentication and not dynamically updated. As a result, if you're already logged in to the web application and you add a claim with your Web Api, that claim will not be available on the web application side until the user is re-authenticated.

Implementing Azure Active Directory Authentication in a client OWIN Web Application

Hello I have read and implemented these Vittorio Bertocci tutorials:
"Secure ASP.NET Web API with Windows Azure AD and Microsoft OWIN Components"
"Protecting a Self-Hosted API with Microsoft.Owin.Security.ActiveDirectory"
However unlike the tutorials my web application is comprised of the following OWIN components: NancyFx & ASP.NET Web API (following the architecture pattern set forth here)As I attempt to implement AAD authentication (as Mr. Bertocci does in his tutorials) into my NancyFx module (to authenticate a user who hits a route requiring authentication):
I get the following error
Additional information: Loading an assembly required for interactive user authentication failed. Make sure assembly 'Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' exists.
clearly the AAD dialog that pops up asking a user to login has a dependency on WindowsForms and shouldn't be invoked from a web application.
What AAD credential prompt should I be using instead?
How to I implement AAD auth in a web app client?
My understanding of the scenario you are trying to implement is that you have the following actors:
Browser -> Web Application -> Web API
Where the browser is authenticates a user to the Web Application and then the Web Application attempts to obtain a token that will allow it to access a resource at the Web API on behalf of the user.
That being the case, your Web Application will need to redirect the browser to the AAD OAuth 2.0 authorization endpoint. There the user will enter their credentials and be redirected back to the Web Application with an authorization code. You can then use that authorization code to obtain a token via the Active Directory Authentication Library (ADAL). Specifically you will use the AuthenticationContext.AcquireTokenByAuthorizationCode method. The following blog entry by Vittorio gives more detail on the code you will need to implement in the Web Application in order to obtain the token. It is not an OWIN specific implementation, but should be easy to translate into your NancyFx app.
Using ADAL’s AcquireTokenByAuthorizationCode to Call a Web API From a Web App
You should not have to change your ASP.NET Web API that you implemented per "Protecting a Self-Hosted API with Microsoft.Owin.Security.ActiveDirectory"
The version of AuthenticationContext.AcquireToken that is used in the client app example in the Protecting a Hosted API... blog entry is intended for a different scenario where no browser is involved. Instead the user is interacting with a desktop application that is then calling a Web API on the users behalf. In that case, the AcquireToken call must show a browser based dialog in order to allow the user to sign in and obtain an appropriate token.

Proper way to setup cross-site authentication in Kohana 3.2

I am currently running two Kohana 3.2 applications:
Web Server
Rest API Server (handles web authentication and all database models)
We are using password granttype/2-legged oauth2 for authentication. When someone performs a login on the webserver, an API authentication request is sent to the API server, based on the response the Auth::instance is set on the web server. Everything works fine up to this point.
We have an automatic crud controller on the API server, but I want to make this available only to an "admin" account after logging in on the web server. I am trying to find a way to pass authentication from Auth::instance()->logged_in() on the web server back to the API server, so that the crud controller is only available if you had been logged in on the web server.
Any creative advice on how to achieve this? The major challenge is that the API server is running ouath2 and auth (ORM driver), but the web server is running a custom Auth driver based on a successful consumer API login.
Here is the flow:
User visits web server
User logs in
web server sends oath2 authentication request to API server
api server access client database validates request, returns
access_token
web server sets Auth::instance()->logged_in() if access_token is
present
CRUD link is displayed based on admin role
CRUD link is a controller on the API server
[need to validate the user was authenticated here]
CRUD controller is displayed (cross-url link, not HMVC included
controller)
Any help will be greatly appreciated.