Angular 12 with .NET and Windows Domain Authentication - asp.net

So I've trying to setup Angular login with Windows Domain Authentication and the backend is hosted with .NET.
Every resource about that on the internet suggest adding interceptor on Angular side:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
req = req.clone({ withCredentials: true });
return next.handle(req);
}
and registering it in app.module
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: CredentialsInterceptor, multi: true}
],
then a sample http request in a service
this.http.get(this.baseUrl + 'user')
But making a request
returns 500 with cors policy error:
No 'Access-Control-Allow-Origin' header is present on the requested
resource.
And what is strange, necessary cors headers have been already added on backend. Since I'm working on frontend only, is there anything that could be added on Angular side?
What I'm expecting is a Windows Domain login window showing after making an http request.
Any help will be appreciated

Related

How to allow access to a NextJS api route from a different domain?

I have a NextJs with an /api/revalidate route for on-demand cache revalidation.
But I need to call this endpoint from a different domain and I'm getting the following error:
Access to XMLHttpRequest at 'DOMAIN_1/api/revalidate' from origin 'DOMAIN_2' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
How can I set up CORS on an API endpoint for a NextJS app?
Just found out that NextJS has an example about setting up CORS in an API route:
https://github.com/vercel/next.js/tree/canary/examples/api-routes-cors
And also you can use nextjs-cors, which is a wrapper on top of cors:
https://www.npmjs.com/package/nextjs-cors
The code will look something like this:
import NextCors from 'nextjs-cors';
async function handler(req, res) {
// Run the cors middleware
// nextjs-cors uses the cors package, so we invite you to check the documentation https://github.com/expressjs/cors
await NextCors(req, res, {
// Options
methods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE'],
origin: '*',
optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
});
// Rest of the API logic
res.json({ message: 'Hello NextJs Cors!' });
}

Blazor WASM standalone to ASP.NET Core 6 Web API with AAD B2C Authorization

I am building a Blazor WASM standalone UI that will use an existing ASP.NET Core 6 Web API for its backend. I have both the Blazor app and the Web API authenticating successfully to AAD B2C individually, but I can't get the UI to successfully pass the token to the API and always get a 401 from the API.
I'm referencing an NSWAG generated API Client from the Blazor app.
Web API
appsettings.js:
Program.cs:
Blazor WASM Standalone
appsettings.js:
Program.cs:
Page.cs:
Service.cs:
Even I got the Http 500 Error Initially. If the controller class has RequiredScope mentioned, remove that attribute.
In client appsettings.json it has to be Authority and in Server appsettingsjson it has to be Instance.
My WeatherForecastController.cs
[RequiredScope(RequiredScopesConfigurationKey = "AzureAdB2C:Scopes")]
My appsettings.json from Client App
appsettings.json file will be available under wwwroot folder
{
"AzureAdB2C": {
"Authority": "https://DomainInitialName.b2clogin.com/DomainInitialName.onmicrosoft.com/B2C_1_Sign_In",
"ClientId": "ClientID from Client AppRegistration",
"ValidateAuthority": false
}
}
Client Program.cs file
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using MySOBlazorApp.Client;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.Services.AddHttpClient("MySOBlazorApp.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("MySOBlazorApp.ServerAPI"));
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication);
options.ProviderOptions.DefaultAccessTokenScopes.Add("https://DomainInitial.onmicrosoft.com/Client Id of Client App Registration from Azure Portal/User Flow from the tenant");
});
await builder.Build().RunAsync();
My appsettings.json from Server App
{
"AzureAdB2C": {
"Instance": "https://DomainInitial.b2clogin.com",
"ClientId": "ClientID from Server AppRegistration",
"Domain": "DomainInitial.onmicrosoft.com",
"SignUpSignInPolicyId": "UserFlow Name"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
OutPut
References taken from MSDoc 1 and 2
I ended up resolving my issues with the help of this example: https://github.com/bryanknox/BlazorApiAadB2c/tree/main/BlazorSample
When newing up the HttpClient, I needed to add a custom AuthorizationMessageHandler and then configure the authorizedUrls and scopes since the UI is talking to an existing API with a different Base URL via a generated NSWAG client. I did this via an extension class.
From within Program.cs, I call the extension class like so: builder.Services.AddApiClient(builder.Configuration);
I also was using the GUID in the .ConfigureHandler(scopes... param URL, but actually needed to use it as it was defined within the B2C portal, which was with the actual API AAD B2C App Registration name.

Access to fetch has been blocked by CORS policy at Firebase Functions API

I'm working on my project which includes Angular 9 application using firebase functions. I deployed some function, which should update some values on the Firebase Realtime Database. Unfortunately, I encountered a problem with CORS policy if I use my API.
After adding middleware to my express server, where I added these code, the problem still occurs.
app.post('/changeQuantity', permit(), (request: any, response: any) => {
response.status(200).send({ data: { Message: 'Changing order quantity - success.' } });
})
export default function permit() {
return (req: any, _res: any, next: any) => {
_res.setHeader('Access-Control-Allow-Origin', '*');
_res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
next();
};
}
I noticed, that I get this error when frequently requesting API.
Here is the error which server returns:
Access to fetch at [here is a link to my API endpoint] from origin [my origin] has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Did anybody have the same issues with the firebase functions API? Could it be related to frequent requests of my API endpoints from the development environment? Thanks in advance.
Try using response.header to set the CORS properties, like this
app.use((request, response, next) => {
response.header("Access-Control-Allow-Origin", "*");
response.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
next();
});

http post request to api nativescript vue

Hello I need help with http post request to my server and get response with authentication.
Look on the screens on 1 I use insomnia REST API application. Using this app I got success response with premium days and id.
In second image I got response just from my nativescript vue.js app where I got false response.
There is something wrong with my code. please tell me what.
You are sending a JSON object in your request body from {N} app, on the other hand you are using FormData with your REST client for testing.
You must either change your API to support JSON data on request body which is generally the standard way. In case if you can't do that, then you must use the nativescript-background-http plugin to send FormData. It will be something like,
var params = [
{ name: "username", value: "test" },
{ name: "password", value: "test123" },
{ name: "uuid", value: "xxxx" }
];
var task = session.multipartUpload(params, request);

Access token request results in 302 in Angular HttpClient

I'm trying to authenticate requests for WordPress rest-api using grant type password. OAuth2 authentication in WordPress is provided by WP OAuth Server plugin.
When I request access token using Postman Chrome app the server responds with expected access token object but the similar request doesn't work in Angular. It gives status 302 and due to xhr redirect to login page, I'm not able to get access token object. I'm using Angular 5.
Here's how I request access token in Angular:
/* Example token url
AuthProvider.TOKEN_URL:
https://www.example-wordpress.com/oauth/token
*/
const body = {
grant_type: 'password',
username: username,
password: password,
};
const headers = new HttpHeaders()
.set('Authorization', 'Basic ' + btoa(AuthProvider.CLIENT_ID + ':' + AuthProvider.CLIENT_SECRET));
this.http.post(AuthProvider.TOKEN_URL, body, { headers: headers });
The above request produces 302 with location header set to:
https://www.example-wordpress.com/login/?redirect_to=https%3A%2F%2Fwww.example-wordpress.com%2Foauth%2Ftoken
And then a xhr GET request is made to above location which responds with HTML of login page and hence no access token is obtained.
The similar POST request for access token in Postman works fine and results in expected access token object but I can't get it to work in Angular.
EDIT
While debugging I generated JavaScript code for access token request from Postman and pasted in console of Chrome after importing jQuery.
The request works as expected in console as well and no redirection occurs. The response is JSON with access token.
Here's the code Postman generated for the POST request:
var settings = {
"async": true,
"crossDomain": true,
"url": "https://example-wordpress.com/oauth/token",
"method": "POST",
"headers": {
"content-type": "application/x-www-form-urlencoded",
"authorization": "Basic M0wzakE3d080VmxxbXB0UUF1dUI5RkxicWxmeE8yR25Zdk4xQmxvbTp4TktTYnJ1Mno5cEp2VDFMbTNGNFhEQm10eDZzUGsya1FqZDg3VmQ2",
"cache-control": "no-cache",
"postman-token": "46339abe-2d1a-1032-f5d8-36e3193d9a81"
},
"data": {
"grant_type": "password",
"username": "my-username",
"password": "my-password",
"client_id": "3L3jA7wO4VlqmptQAuuB9FLbqlfxO2GnYvN1Blom",
"client_secret": "xNKSbru2z9pJvT1Lm3F4XDBmtx6sPk2kQjd87Vd6"
}
}
$.ajax(settings).done(function (response) {
console.log(response);
});
And here's the response logged from above code:
{
access_token: "rksen3p351fj0povsrpfv2eeuahrciglc3ilphhy",
expires_in: 3600,
token_type: "Bearer",
scope: "basic",
refresh_token: "fudju8tecbnwly2e1xgfv92tykvpsniwkfpvrd7d"
}
I'm unable to figure out why redirection occurs when we request through Angular and not responds with access token JSON.
Any help is appreciated.
access_token (which I imagine is what you expect to have) isn't part of the few headers that Angular is able to read without setting up your server.
Angular only read "basic" headers such as Content-type. This is because of the default CORS configuration that only reads Cache-Control, Content-Language, Content-Type, Expires, Last-Modified and Pragma. When it comes to custom headers, you have to tell your server to expose the headers.
This is done through the Access-Control-Expose-Headers header.
There was no problem at all. It was a very very silly mistake. I apologize.
I was testing with two websites simultaneously and both had similar configuration. The only difference was that one had OAuth plugin installed and other not. So when I tried to authorize the request from Angular with the website which hadn't had OAuth2 plugin installed and so redirected to the login page. The constant set for the AuthProvider.TOKEN_URL was incorrectly set, while when I was testing with other tools I was using correct url.
Anyway, this was all my mistake. It happens sometimes, when you don't take break. :)

Resources