angular-oauth2-oidc CORS ADFS - adfs

I am using angular-oauth2-oidc library to connect to ADFS but I get the following error:
I am using the following code:
app.component.ts:
config.issuer = 'https://myserver/adfs';
config.clientId = 'https://myapp/';
config.redirectUri = window.location.origin;
config.scope = 'openid profile';
this.oauthService.configure(config);
this.oauthService.loadDiscoveryDocument();

The error is telling you that the browser was instructed by ADFS (through the absence of- or specific settings for its CORS headers) not to allow loading the openid-configuration when your SPA requests it from some other domain (like localhost:4200 or otherwise).
If possible, you should reconfigure ADFS to send CORS headers that allow it being called from specific or possibly even all domains.
If that is not possible, your only option is to not use any loadDiscoveryDocument... features from the library, and instead configure all relevant settings that would be auto-detected yourself, manually.

Related

Specify custom redirect_uri in a web app that uses Azure AD authentication with oidc and a middleware

I am trying to authenticate an app with Azure AD. It's all good in localhost, it redirects to Azure AD where I enter details to authenticate, and it sends back the token that allows to view the resource.
Everything managed behind the scenes with the Microsoft.AspNetCore.Authentication.AzureAD.UI 3.1.10 in an aspnetcore 3.1 application.
My app runs on http://localhost:5000 and I can configure the redirectUri/replyUri at Azure AD for that application to support this url. All good.
The problem is in a different environment when my app runs in a service fabric cluster.
I can see the problem
AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application
When I inspect the url I can see that the redirect_uri has some url like this http://12.12.12.12/signin-oidc
The problem is double here. First of all I don't know which IP the cluster is gonna assign. Second, it is http, not https, and that's not supported by Azure AD.
Luckily my app has an external Url with a reverse proxy I can use to access. Something like https://myservicefabriccluster.com/MyApp
That Url I could configure as my redirect_uri in both my application and Azure AD, but I don't know how to do so.
My code has something like this:
services
.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
where I bind my settings.
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "76245c66-354e-4a94-b34d-...",
"TenantId": "59c56bd4-ce18-466a-b515-..."
},
I can see the AzureADOptions supports some other parameters such as Domain (not needed) or CallbackPath (which by default is ok being /signin-oidc) but there is nothing similar to ReplyUrl or RedirectUri where I can specify an absolute URL as the callback.
I have found a few similar issues without an answer. Others suggest some kind of tricks like a middleware that rewrites that parameter just before redirecting to Azure AD.
Certainly there must be an easier way to deal with this problem that I expect is not so strange. Any help please?
The solution to overwrite redirect_uri parameter with a custom value is to use the Events available in OpenIdConnect library. This library should be available as it's a dependency for Microsoft.AspNetCore.Authentication.AzureAD.UI, so this is my solution that, in addition to the standard properties for AzureADOptions it adds a flag to determine whether the redirect uri must be overwritten and a value to do so. I hope it's self explanatory
services
.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => configuration.Bind("AzureAd", options));
var isCustomRedirectUriRequired = configuration.GetValue<bool>("AzureAd:IsCustomRedirectUriRequired");
if (isCustomRedirectUriRequired)
{
services
.Configure<OpenIdConnectOptions>(
AzureADDefaults.OpenIdScheme,
options =>
{
options.Events =
new OpenIdConnectEvents
{
OnRedirectToIdentityProvider = async ctx =>
{
ctx.ProtocolMessage.RedirectUri =
configuration.GetValue<string>("AzureAd:CustomRedirectUri");
await Task.Yield();
}
};
});
}
services
.AddAuthorization(
options =>
{
options.AddPolicy(
PolicyConstants.DashboardPolicy,
builder =>
{
builder
.AddAuthenticationSchemes(AzureADDefaults.AuthenticationScheme)
.RequireAuthenticatedUser();
});
});
And the appsettings.json would have something like this:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "76245c66-354e-4a94-b34d-...",
"TenantId": "59c56bd4-ce18-466a-b515-..."
"IsCustomRedirectUriRequired": true,
"CustomRedirectUri": "https://platform-cluster-development01.cubictelecom.com:19008/Scheduler/WebApi/signin-oidc"
},
Notice the IsCustomRedirectUriRequired and CustomRedirectUri are my custom properties that I read explicitly in order to overwrite (or not) the redirect uri query parameter when being redirected to the identity provider (i.e: Azure AD)
Looking at this, you should be configuring the public URL as the redirect URI, which is a value such as this:
https://myservicefabriccluster.com/MyApp
It looks like that the above library does not easily support this, and forces the redirect URI to be based on the HTTP listening URL of the code. As part of resolving this it is worth considering how you are writing your code:
This line of code indicates that your app is limited to only ever working with Azure AD:
- services.AddAzureAD
This line of code would ensure that your code works with both AzureAD and any other Authorization Server that meets the Open Id Connect standard:
- services.AddOpenIdConnect
The latter option also has an Events class with a commonly used OnRedirectToIdentityProvider operation that you can use to override the CallbackPath and provide a full RedirectUri.
Azure AD endpoints are standards based so you do not strictly have to use AzureAD specific libraries. Out of interest, I have a Single Page App Azure code sample that uses a neutral library like this, so I know this technique works.

BizTalk 2016: How to use HTTP Send adapter with API token

I need to make calls to a rest API service via BizTalk Send adapter. The API simply uses a token in the header for authentication/authorization. I have tested this in a C# console app using httpclient and it works fine:
string apiUrl = "https://api.site.com/endpoint/<method>?";
string dateFormat = "dateFormat = 2017-05-01T00:00:00";
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("token", "<token>");
client.DefaultRequestHeaders.Add("Accept", "application/json");
string finalurl = apiUrl + dateFormat;
HttpResponseMessage resp = await client.GetAsync(finalurl);
if (resp.IsSuccessStatusCode)
{
string result = await resp.Content.ReadAsStringAsync();
var rootresult = JsonConvert.DeserializeObject<jobList>(result);
return rootresult;
}
else
{
return null;
}
}
however I want to use BizTalk to make the call and handle the response.
I have tried using the wcf-http adapter, selecting 'Transport' for security (it is an https site so security is required(?)) with no credential type specified and placed the header with the token in the 'messages' tab of the adapter configuration. This fails though with the exception: System.IO.IOException: Authentication failed because the remote party has closed the transport stream.
I have tried googling for this specific scenario and cannot find a solution. I did find this article with suggestions for OAUth handling but I'm surprised that even with BizTalk 2016 I still have to create a custom assembly for something so simple.
Does anyone know how this might be done in the wcf-http send adapter?
Yes, you have to write a custom Endpoint Behaviour and add it to the send port. In fact with the WCF-WebHttp adapter even Basic Auth doesn't work so I'm currently writing an Endpoint Behaviour to address this.
One of the issues with OAuth, is that there isn't one standard that everyone follows, so far I've had to write 2 different OAuth behaviours as they have implemented things differently. One using a secret and time stamp hashed to has to get a token, and the other using Basic Auth to get a token. Also one of them you could get multiple tokens using the same creds, whereas the other would expire the old token straight away.
Another thing I've had to write a custom behaviour for is which version of TLS the end points expects as by default BizTalk 2013 R2 tries TLS 1.0, and then will fail if the web site does not allow it.
You can feedback to Microsoft that you wish to have this feature by voting on Add support for OAuth 2.0 / OpenID Connect authentication
Maybe someone will open source their solution. See Announcement: BizTalk Server embrace open source!
Figured it out. I should have used the 'Certificate' for client credential type.
I just had to:
Add token in the Outbound HTTP Headers box in the Messages tab and select 'Transport' security and 'Certificate' for Transport client credential type.
Downloaded the certificate from the API's website via the browser (manually) and installed it on the local servers certificate store.
I then selected that certificate and thumbprint in the corresponding fields in the adapter via the 'browse' buttons (had to scroll through the available certificates and select the API/website certificate I was trying to connect to).
I discovered this on accident when I had Fiddler running and set the adapter proxy setting to the local Fiddler address (http://localhost:8888). I realized that since Fiddler negotiates the TLS connection/certificate (I enabled tls1.2 in fiddler) to the remote server, messages were able to get through but not directly between the adapter and the remote API server (when Fiddler WASN'T running).

Nginx authentication using JWT and an external authentication server in a multi-tenant system

I am building a multi-tenant system fronted by Nginx.
I want all requests hitting Nginx to first be 'filtered' on whether they have a valid JWT. If not, there should be a 'call out' to an external authentication server which will do SAML/SSO and return a JWT or 'false'. If false, then a 401 is returned.
If there is a valid JWT, it needs to be interpreted and the tenant name extracted. Then, depending on the request path, the url/POST body will need to be modified to include the correct tenant (we are hitting an Elasticsearch and need to make sure that a tenant is only allowed to query their own indexes)
The Authentication server will be built in php, so what we need is just the 'filter' part and a valid way of calling the Auth server. Is there any off-the-shelf nginx module which will solve this requirement? Or is Lua my best bet here? I'm a relatively novice Nginx-er.
There is much better and simpler JWT based authentication module for nginx.
Highly configurable.
https://github.com/tarachandverma/nginx-openidc
You can configure multiple relying parties.
https://github.com/tarachandverma/nginx-openidc/blob/master/test-conf/oidc-config.xml#L12
<!-- relying parties configuration -->
<relyingParties default="282412598309-545pvmsh9r23f4k1o7267744s59sod6v.apps.googleusercontent.com">
<relyingParty clientID="282412598309-545pvmsh9r23f4k1o7267744s59sod6v.apps.googleusercontent.com" clientSecret="xxxxx" domain=".com" validateNonce="true">
<description>nginx oidc demo</description>
<redirectUri>http://ngx-oidc-demo.com/oauth2/callback</redirectUri>
</relyingParty>
</relyingParties>
Use https://github.com/auth0/nginx-jwt, for me it was easier to install Openresty, since I didn't have that much time to install manually lua module on nginx, and all it's dependencies.
At https://github.com/auth0/nginx-jwt/blob/master/nginx-jwt.lua at the line 114 the library adds the sub to the header which should be an Id, you may change this if you need anything alse.
ngx.header["X-Auth-UserId"] = jwt_obj.payload.sub

How to specify Logout Service in the PingFederateSLOURL in mod_pf configuration

We are using PingFederate as Service Provider and are using Opentokenadapter.
We are also using mod_pf apache library provided by PingFederate.
Is there any way we can configure "Logout Service (present in OpenToken Adapter )" in the mod_pf configuration? Is there any query parameter for it just like we have for PartnerIdpId, TargetResource etc?
The Apache Integration Kit's mod_pf.conf refers to the /sp/startSLO.ping application endpoint. In that configuration file is where you will configure various bits for the integration... You can review the /sp/startSLO.ping options as listed here:
https://documentation.pingidentity.com/pingfederate/pf81/index.shtml#concept_spServices.html#concept_spServices
The "Logout Service", as defined in the adapter, is where the browser will be sent to for an SLO that will destroy any current session within the SP Application. By spec, that application must return BACK to PingFederate, so that PingFederate can respond back to the IdP with a success/fail. If you plan to support SLO, then this "service" must exist. It's "goal" will be close the session, and redirect back to PingFederate with a success.

AWS API Gateway as Serivce proxy for S3 upload

I have been reading about creating an API which can be used to upload objects directly to S3. I have followed the guides from Amazon with little success.
I am currently getting the following error:
{"message":"Missing Authentication Token"}
My API call configuration:
The role ARN assigned is not in the image, but has been set up and assigned.
The "Missing Authentication Token" error can be interpreted as either
Enabling AWS_IAM authentication for your method and making a request to it without signing it with SigV4, or
Hitting a non-existent path in your API.
For 1, if you use the generated SDK the signing is done for you.
For 2, if you're making raw http requests make sure you're making requests to /<stage>/s3/{key}
BTW, the path override for s3 puts needs to be {bucket}/{key}, not just {key}. You may need to create a two-level hierarchy with bucket as the parent, or just hardcode the bucket name in the path override if it will always be the same. See: http://docs.aws.amazon.com/apigateway/latest/developerguide/integrating-api-with-aws-services-s3.html

Resources