How to validate oauth token in my application using load balancer? - c#

I have an api project configured with oauth for authentication. since the application uses load balancer to manage multiple requests, let's assume (server-1 ad server-2).
first request with valid credentials => server 1 (here token was generated)
second request with token included in header => server 2
now second request getting "Authorization Denied". How to handle this scenario?

Guess you are looking for something like vouch-proxy.
Here some useful links:
Article: https://medium.com/lasso/use-nginx-and-lasso-to-add-google-authentication-to-any-application-d3a8a7f073dd
Project: https://github.com/vouch/vouch-proxy

Related

Token access blocked when posting request from published Azure function

I am struggling to get a token from "https://login.microsoftonline.com/common/oauth2/token" with an Azure function by a post-request. The token will give permissions to access SharePoint though CSOM. Here is my code snippet with the post request:
var clientId = defaultAADAppId;
var body = $"resource={resource}&client_id={clientId}&grant_type=password&username={HttpUtility.UrlEncode(username)}&password={HttpUtility.UrlEncode(password)}";
using (var stringContent = new StringContent(body, Encoding.UTF8, "application/x-www-form-urlencoded"))
{
var result = await httpClient.PostAsync(tokenEndpoint, stringContent);
var tokenResult = JsonSerializer.Deserialize<JsonElement>(result);
var token = tokenResult.GetProperty("access_token").GetString();
}
When testing locally, both when running the function in Visual studio and when I try with Postman, I am able to achieve an access token. However, as soon as I publish the function to my Function app in Azure I receive the following error message:
"AADSTS53003: Access has been blocked by Conditional Access policies. The access policy does not allow token issuance"
I have enabled an app registration in the portal and as mentioned, it all works fine until I publish everything to Azure.
Any ideas on how to solve this?
I got it to work now. First of all I reviewed the CA policies as #CaseyCrookston suggested. What I found out was that our CA policies blocked calls outside the country we operate from. However, the calls from the App registration/Azure function were registered from the Azure data centre location and thus, blocked by our CA policies. When running them locally the calls where registered in my country and therefore no errors were showing while debugging.
My first step was trying to add my Client app to the CA policy, which was not possible. The client/secret authentication that I used based on the suggestions in this CSOM guide by Microsoft prevented the App registration to be whitelisted from the CA policies (Github issue).
Based on this I had to change the authentication to a Certificate-based authentication as suggested here: Access token request with a certificate and here: SO answer. With this I was able to whitelist the App registration in the CA policies and successfully authenticate to the Sharepoint CSOM.
As the error message says, your app is blocked by CA policy. Possible causes can be unknown client app, blocking external IP addresses, etc.
You can perform one of the below workarounds:
Add your Client app to your CA policy.
I wouldn’t recommend this because this affects your security - if you take the risk you could exclude the “Microsoft Azure Management” from your CA policy which blocks unknown clients / requires device state and still protect the sign-in with MFA.
A better approach is to use another OAuth 2.0 and OpenID connect flow like the delegated flow where you sign-in directly within the app, if possible.

How can I validate MSAL token on API Management?

I have a desktop app which uses ADAL for authentication, this app make requests to an API on the API Management azure service. After migrating the code to use MSAL, the API Management returns 401 saying that my token is invalid. The only difference that I see spying the requests is that ADAL makes a request to this endpoint /tenantID/oauth2/token and MSAL /tenantID/oauth2/v2.0/token.
In my API Management I have this policy:
<validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized. Access token is missing or invalid. AAD" require-expiration-time="false">
<openid-config url="https://login.microsoftonline.com/tenantID/.well-known/openid-configuration" />
</validate-jwt>
I tried to change the well known url to v2.0 endpoint but get the same error. How can I validate the token using MSAL?
From the Note in the doc, when changing the well known url to v2.0, you may need to use common instead of tenantID.
<openid-config url="https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration" />
Also, make sure you have done the step 10 in this link correctly:
If you use v2 endpoints, use the scope you created for the backend-app
in the Default scope field. Also, make sure to set the value for
the accessTokenAcceptedVersion property to 2 in your
application manifest.

Visual studio Web Performance tests - OAuth 2.0

I am trying to create the Web Performance tests for an app that is using Identity Server 3. I can't figure out how to simulate login and get token.
For example, I am using myapp.com and identity server is hosted on identity.com. All my endpoints in myapp.com/api are secured and require Bearer token.
identity.com can provide me token in exchange for a username and password. identity.com will redirect me to a myapp.com/tokenRedirect?token=***. How can I catch the token and use it as an Authorization header for API requests?
There are some solutions for JMeter but could not find any for VS 2017 tests.
Redirections are handled automatically, by default, in a test recorded by Visual Studio and hence the redirection response containing the token is not accessible. Setting the FollowRedirects property of the request to False allows the response containing the redirection to be accessed by the usual extraction rules and/or plugins etc. One of them can be used to find the token value and save it to a context parameter (CP). Having turned off the automatic redirection handling, a new request should be added (use the Insert request command, do not use Add dependent request) and it should have the request that the redirection wants. Hence its url should be of the form myapp.com/tokenRedirect?token={{TheCPWithTheToken}}.
In later requests the CP with the token can be added via the Add header command, or an existing header field can be modified to use the CP.

How to serve multiple web sites by the one ADFS server?

I have two servers: one of them serves UI (it is called webUI) and another works with data (it is called webAPI).
I try to implement an authentication across the ADFS server. It has Relying Party Trusts for both servers: [urn=webui,identifier=address/webui],[urn=webapi,identifier=address/webapi].
I adjused the HttpConfiguration for webUI and user can be authenticated and use website, which the webUI serves (it's good).
var wsFedMetAdd = ConfigurationManager.AppSettings["wsFedMetAdd"];
if (string.IsNullOrWhiteSpace(wsFedMetAdd))
throw new ConfigurationErrorsException(Properties.Resources.InvalidMetadataAddress);
var wsFedWtrealm = ConfigurationManager.AppSettings["wsFedWtrealm"];
if (string.IsNullOrWhiteSpace(wsFedWtrealm))
throw new ConfigurationErrorsException(Properties.Resources.InvalidWtrealm);
appBuilder.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType
});
var options = new WsFederationAuthenticationOptions
{
MetadataAddress = wsFedMetAdd,
Wtrealm = wsFedWtrealm,
SignInAsAuthenticationType = "Federation"
};
appBuilder.UseWsFederationAuthentication(options);
config.Filters.Add(new AuthorizeAttribute() { Roles = "Admin" });
Once client gets RequestSecurityTokenResponse (SAML Token). Also responses from ADFS set cookies for further requests (MSISAuth, MSISAuthenticated and so on).
The webAPI has the same implemention of HttpConfiguration (only one difference - wsFedWtrealm is urn:webapi instead urn:webui). Then I try send a request to the webAPI from client and the ADFS Server asks to authenticate one more.
I can't understand what should I do to use the same credentials for webAPI which I entered for webUI. Or maybe I should use SAML Token?
UPDATE
Wow. It is worked without SAML token, just using cookies.
When the user tries to be authenticated for webUI, diverse cookies are set on client (.AspNet.Federation, MSISAuth, MSISAuthenticated...). Then I substitute the webUI link with the webAPI link in the address bar and then webAPI doesn't ask to enter login and password. Hence data is displayed in browser. Authentication is picked up for webUI and for webAPI too.
But now problem is I get the error when javascript tries to send a request to webAPI:
XMLHttpRequest cannot load
https://my_address/adfs/ls/?wtrealm=urn%3awebapi&wctx=_ No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'https://my_address:9001' is therefore not allowed
access.
What version of ADFS?
You are mixing two protocols - Web API generally uses OAuth.
Use OpenID Connect for the UI and then that will naturally flow into the WebAPI as per this : Securing a Web API with ADFS on WS2012 R2 Got Even Easier.
Or for a somewhat more convoluted approach - what protocol to use with ADFS when security webapi for non-browser clients
This post help me to solve my problem.
I added to code of index.html new element iframe. Attribute src is the link to my webAPI.

Active Directory Authentication Exception (AADSTS90027) with Azure AD

I have a native client application which is obtaining an OAuth2 token for Active Directory authorization. It will then use that token to communicate with a secure Web API server where certain areas of the API are secured using the [Authorize] attribute. The server is also registered with Azure AD and can properly authorize requests through AD.
When I try to get the token, I get the following exception on Line 2 of the code below:
Additional information: invalid_request: AADSTS90027: The client '<Client GUID>' and resource 'https://abccompany.com/MyApplication.Server' identify the same application.
Here is my code which I am running in the native client (just on a button press as a test, for now). Obviously the GUID and company names have been obfuscated.
AuthenticationContext ac = new AuthenticationContext("https://login.windows.net/abccompany.com");
AuthenticationResult ar = ac.AcquireToken("https://abccompany.com/MyApplication.Server", "<Client GUID>", new Uri("https://localhost:44300/secure"), PromptBehavior.Auto);
I made sure the redirect existed in Azure in the application configuration (otherwise there would have been a redirect error instead). What does the error mean?
You seem to be using the clientId of the WebAPI where you need to supply the clientId of the client app. Please register a separate 'Native client application' in Azure AD representing the client app.
The following topic explains the protocol flow and how to register WebAPIs in Azure AD such that users from multiple AD tenants can use that API: http://msdn.microsoft.com/en-us/library/azure/dn499820.aspx#BKMK_Native
The following samples should see you through:
Single tenant WebAPI: https://github.com/AzureADSamples/NativeClient-WindowsStore
Multi-tenant WebAPI: https://github.com/AzureADSamples/NativeClient-WebAPI-MultiTenant-WindowsStore
Hope this helps.
ps: Azure AD doesn't issue a token when the client and resource are the same application. In your case they should indeed be different and resource clientid (issued to a confidential client) should not be used as a public client - however for service to service scenarios, it can be argued that issuing tokens to self should be allowed - this is something we are looking into.

Categories