Share file using URL by Web Application to Portal using OpenId Authentication - asp.net-web-api

I'm working on a web application that uses OpenId authentication. Let's assume that the application essentially serves to store metadata and its associated files (docx, pdf). The Web Application is for internal use and is not exposed to public network, only users of the organization have access.
Recently, a requirement has arisen to be able to share files with users external to the organization. External users will use a PORTAL (third-party application) which, through a URL generated by the Web Application that points to the PORTAL, will have access to the file. This PORTAL uses OpenId authentication and invokes a Web Application API to retrieve the file.
Initially, the proposed solution was:
Web Application - Send EMAIL to the external user and create a user in Keycloak with Email to authenticate later on the PORTAL (Is this really necessary?! Biggest doubt).
The external user accesses the PORTAL with the URL received and authenticates with the user created by the Web Application on Keycloak.
Once authenticated on PORTAL, a WebApplication API is invoked to obtain the file.
The main question is whether the Web Application should manage the creation/editing/deleting of external users on Keycloak. Does the Web Application need to create users in Keycloak? Is there another way to accomplish this without compromising security?
Thanks in advance.

To share a file with restricted access, there are two approaches:
Open access with signed links: Create a signed URL using a web API and share it with external users. The link can be a static URL with an encrypted key, or a JWT signed token in base64 form generated by the web API. When the portal receives a request, it checks the validity of the token, retrieves the file location from the token, and allows access.
Email-restricted access: If you want to guarantee access only to the person with email xxx#abc.com, you'll need to use a challenge, which is typically a login. You can either create users on the fly after login (if the external users come from a partner with OIDC capability), or pre-create the users if this is not the case.
Note: You cannot rely solely on a URL with an email claim as proof of access, as the link may have been forwarded to someone else.

Related

How to authenticate an API client using an OAuth token issued from another web app in ASP.net WebAPI?

I have two web applications that I've worked on in ASP.net Web API for a client. The two applications are hosted on the same domain, but in different virtual directories.
Each application has a data source with information about authorized users. I've been asked to set up a separate app that will allow a user to log in and issue an OAuth bearer token that can be used to access each web application.
I have the Owin stuff set up in one of my two apps with something of a boilerplate setup and it automagically makes the tokens work for me, but that's only within a single web application.
I have a general idea of how the OAuth tokens work: a user is authenticated and they receive a token that contains a user ID, a time stamp, and a cryptographic signature that says that the token came from my client's server and not somewhere else, and the Web API framework automatically checks that token for me when I decorate my API endpoints with the [Authorize] attribute.
I want to know how I can set this up so that the token is issued by one web app and consumed by another. I know that at a minimum, I need to make the two web apps work with the same key pair for the cryptographic signatures.
Can I please get some direction about how to make this happen?

How To Get User Email From Cloud Identity Aware Proxy

I want to build a web application in Go. I'm using Google App Engine for deployment combined with Identity Aware Proxy (IAP) to authenticate user access.
I want to know how to access the authentication to get the user email, which I can link to app data stored in a back end database. Essentially I want to avoid my users logging in and then having to authenticate again to get their profiles from the back end.
I have looked into the IAP documentation and I can see it uses JWT Headers and that is where my knowledge lacks. My guess would be a link to the incoming request which accesses those headers to get the email.

Azure AD exchange access_token with id_token v.1.0 endpoint

I will draw a scenario, and need some suggestions:
I'm using Azure AD (v1.0 endpoint), a single-page app (SPA) and a web API. The SPA establishes the user's identity using OpenID Connect, authenticates the user and receives an id_token and access_token for the back-end web API.
Now, we don't want the SPA to do access control decision based on the id_token received within the SPA app.
Instead, the SPA sends the access_token to the back-end web API to access it, and now we want back-end web API to make an access control decision based on the roles claim found in the id_token, but which the back-end does not receive from the SPA.
The question is, is it possible for the back-end web API to send received access_token to Azure AD token endpoint and receive the relevant id_token for the user so that the back-end web API receives an id_token containing the roles claims for the user, in order to make an access control decision?
There are a couple issues with the approach as you describe it:
The app roles would be defined on the native client application (the SPA). Though you can technically define app roles in the manifest, you'll notice the Azure portal won't let you assign users or groups to a native client app. (Which sort of makes sense, because, as you've rightly said, you don't want to do any access control in the native client app.)
You can't do what you've described (exchange an access_token intended for one audience, for an id_token intended for a different audience). There are some variants of token exchange which you can do, but none of them would help you in this situation.
Instead, what you should do is define the app roles on the web API. Then, assign the users to the corresponding app role for the web API. When these users sign in to the SPA, and the SPA gets an access token on their behalf to the web API, you'll notice the access token will contain the roles claim, populated with the appropriate values.
Summarizing:
Under App registrations for the web API, define your appRoles in the app manifest (or on the Application object directly, using (for example) Azure AD PowerShell).
Under Enterprise apps for the web API, assign users and/or groups to their corresponding app roles, and choose whether or not app role assignment is required or not*. (Or do so directly on the ServicePrincipal object.)
Under App registrations for the SPA (the Application object), add the web API as a required permission.
*If you choose to require app role assignment for the web API (under Enterprise apps > Properties), the SPA will not be able to get an access token for users who are not assigned to an app role for the web API. If you choose not to require app role assignment , users who are not assigned an app role will be able to sign in to SPA and the SPA will be able to get an access token on their behalf for the web API, but the access token will not contain a roles claim.

How can I change the client_email for the service account key credential to my own email?

I have 2 applications, the old application is using Oauth2 to access the Google Analytics API. All current users have granted access to an email from my domain.
The second application is using credentials with Service account authentication.
The problem is that the email for the Service account keys is using a different domain:
"client_email": "xxx-service#xxx.iam.gserviceaccount.com",
I need it to use my old email from my domain that already have permissions from clients.
How can I do that, I already downloaded the json file for the Service account keys.
There is a diffrence between Oauth2 and service accounts.
Lets start with the old app using Oauth2. When a user starts using the application they are displayed the authentication form which asks them to grant application X access to their data. Assuming they accept it application X can now read there data. Application X is given a Refresh token which can be used to access the data at a later date.
In the background the developer of Application X registered their application on Google Developer console and was given a client id and client secret. When the user authenticated to the application the Refresh token is created using the client id and client secret. You can not take a different client id and client secret and use it with the refresh token from another application they are not interchangeable.
Service accounts are different in that they are preauthorized. If you take that service account email address you have and add it as a user on the Google analytics website admin section. The service account will have access to read the information just like any other user.
Clarifications / answers.
You can not pick the service account email address these are generated by Google.
You can't use a service account to access data granted to an application though Oauth2. they are not interchangeable.
If you have access to the users data using Oauth2 you should be using your refresh tokens to access their data you do not need a service account.

Supporting both existing forms authentication login and Federated WebSSO

We are having a hosted web application and it uses forms authentication.
This webapplication is accessed by users belong to different partner organizations.
Currently users belong to the partner organizations are accessing the application using the credentials that we give it to them.
Now, some partner organizations wants their users to access the application using their active directory credentials.
We are planning to use ADFS for these partner organizations, so the users will be authenticated using Active Directory within their network and claims will be sent to the webapp via the Authentication token cookie set by the ADFS. From the claims, we map the users to the internal userIds of the web application.
My questions are , if we make the web application ADFS enabled,
1)Is it possible to still allow the other partner organization users(who don't want to use ADFS) to login to the web application using the existing login page(forms authentication)?
2) Should every page in the ADFS enabled webapp be accessed through https?
Any solutions or pointers would be much appreciated.
Thanks
-arul
Your app needs to require claims that describe the user, regardless of where they login from. It should not handle authentication in either case; this should be delegated to a trusted issuer, an STS. This will allow it to interact w/ users in a uniform way irrespective of where and how they authenticate. This means that you're going to need to use ADFS in two roles: that of an Identity Provider (IP) STS and of a Federation Provider (FP) STS. For users of partner companies that don't want to maintain users themselves, you'll be the IP-STS; for those that do, you'll be an FP-STS. In the latter case, ADFS will redirect users from your realm back to the partner's site where their IP-STS will authenticate them and send them to your FP-STS. It will map your partner's user ID and claims into ones that make sense in your realm. This and other information about the user will be included in the set of claims that are issued from your FP-STS. As a result, your app, only trusts your STS regardless of which scenario is appropriate for different users. Note that in this scenerio, there will be two STSs: your ADFS FP-STS and your partner's IP-STS, which may or may not be ADFS. In the other case, there will only be one STS: your IP-STS.
Not every page on your ADFS Web app needs to be accessed via HTTPS; however, everyone that's used in the authentication process should be.
This is really a non-trivial undertaking. If you want to talk about it more, please feel free to get in touch w/ me.

Resources