We have an Angular 2 application making http requests to a .net Web API rest service. Both the angular 2 app and the API are hosted within IIS.
The client makes use of webpack for hot module replacement, bundling etc and also uses webpack's server side prerending with NodeJS
I'm having an issue with http requests that are made as part of the server side prerendering. The API requires windows authentication for all requests and the server side requests fail because the requests are not authenticated. It would seem that node isn't providing the relevant headers/user tokens.
For info, this is my webpack config:
const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
module.exports = (env) => {
// Configuration in common to both client-side and server-side bundles
const isDevBuild = !(env && env.prod);
const sharedConfig = {
stats: { modules: false },
context: __dirname,
resolve: { extensions: [ '.js', '.ts' ] },
output: {
filename: '[name].js',
publicPath: '/dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
},
module: {
rules: [
{ test: /\.ts$/, include: /ClientApp/, use: ['awesome-typescript-loader?silent=true', 'angular2-template-loader'] },
{ test: /\.html$/, use: 'html-loader?minimize=false' },
{ test: /\.css$/, use: [ 'to-string-loader', isDevBuild ? 'css-loader' : 'css-loader?minimize' ] },
{ test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' }
]
},
plugins: [new CheckerPlugin()]
};
// Configuration for client-side bundle suitable for running in browsers
const clientBundleOutputDir = './wwwroot/dist';
const clientBundleConfig = merge(sharedConfig, {
module: {
loaders: [
{
test: /config.js$/,
loader: "file?name=[config.js]&context=./dist/"
}
]
},
entry: { 'main-client': './ClientApp/boot-client.ts' },
output: { path: path.join(__dirname, clientBundleOutputDir) },
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./wwwroot/dist/vendor-manifest.json')
})
].concat(isDevBuild ? [
// Plugins that apply in development builds only
new webpack.SourceMapDevToolPlugin({
filename: '[file].map', // Remove this line if you prefer inline source maps
moduleFilenameTemplate: path.relative(clientBundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
})
] : [
// Plugins that apply in production builds only
new webpack.optimize.UglifyJsPlugin()
])
});
// Configuration for server-side (prerendering) bundle suitable for running in Node
const serverBundleConfig = merge(sharedConfig, {
resolve: { mainFields: ['main'] },
entry: { 'main-server': './ClientApp/boot-server.ts' },
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./ClientApp/dist/vendor-manifest.json'),
sourceType: 'commonjs2',
name: './vendor'
})
],
output: {
libraryTarget: 'commonjs',
path: path.join(__dirname, './ClientApp/dist')
},
target: 'node',
devtool: 'inline-source-map'
});
return [clientBundleConfig, serverBundleConfig];
};
This is the typescript code that makes the http request (done within a route guard):
public resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<CallDetails> {
let id = route.paramMap.get('id');
let url: string = this.settings.apiUrl + `/api/call/get?id=${id}`;
let options = { withCredentials: true };
return this.http.get(url, options)
.takeUntil(this.ngUnsubscribe)
.map((res: Response) => {
return res.json() || {};
})
.map(data => {
return new CallDetails(data);
})
.catch((res: Response) => {
return this.loadError(res, id);
})
.toPromise<CallDetails>()
.then(callDetails => {
return callDetails
})
}
How can I configure webpack/nodejs to use windows authentication for http requests? Also, how can I ensure that the requests are issued under the context of the current user?
Everything works fine when running in the browser.