Merge pull request #344 from nightah/duo-additions
Capture IP address and Target URL in Duo 2FA requestpull/343/head
commit
e3b6410e79
|
@ -24,11 +24,11 @@ describe("routes/secondfactor/duo-push/Post", function() {
|
||||||
hostname: 'abc',
|
hostname: 'abc',
|
||||||
integration_key: 'xyz',
|
integration_key: 'xyz',
|
||||||
secret_key: 'secret',
|
secret_key: 'secret',
|
||||||
}
|
};
|
||||||
|
|
||||||
req = ExpressMock.RequestMock();
|
req = ExpressMock.RequestMock();
|
||||||
res = ExpressMock.ResponseMock();
|
res = ExpressMock.ResponseMock();
|
||||||
})
|
});
|
||||||
|
|
||||||
it("should raise authentication level of user", async function() {
|
it("should raise authentication level of user", async function() {
|
||||||
const mock = Sinon.stub(DuoApi, "Client");
|
const mock = Sinon.stub(DuoApi, "Client");
|
||||||
|
@ -37,7 +37,7 @@ describe("routes/secondfactor/duo-push/Post", function() {
|
||||||
});
|
});
|
||||||
req.session.auth = {
|
req.session.auth = {
|
||||||
userid: 'john'
|
userid: 'john'
|
||||||
}
|
};
|
||||||
|
|
||||||
Assert.equal(req.session.auth.authentication_level, undefined);
|
Assert.equal(req.session.auth.authentication_level, undefined);
|
||||||
await Post(vars)(req, res as any);
|
await Post(vars)(req, res as any);
|
||||||
|
@ -54,7 +54,7 @@ describe("routes/secondfactor/duo-push/Post", function() {
|
||||||
});
|
});
|
||||||
req.session.auth = {
|
req.session.auth = {
|
||||||
userid: 'john'
|
userid: 'john'
|
||||||
}
|
};
|
||||||
vars.config.duo_api = undefined;
|
vars.config.duo_api = undefined;
|
||||||
|
|
||||||
Assert.equal(req.session.auth.authentication_level, undefined);
|
Assert.equal(req.session.auth.authentication_level, undefined);
|
||||||
|
@ -72,7 +72,7 @@ describe("routes/secondfactor/duo-push/Post", function() {
|
||||||
});
|
});
|
||||||
req.session.auth = {
|
req.session.auth = {
|
||||||
userid: 'john'
|
userid: 'john'
|
||||||
}
|
};
|
||||||
|
|
||||||
Assert.equal(req.session.auth.authentication_level, undefined);
|
Assert.equal(req.session.auth.authentication_level, undefined);
|
||||||
await Post(vars)(req, res as any);
|
await Post(vars)(req, res as any);
|
||||||
|
@ -90,7 +90,7 @@ describe("routes/secondfactor/duo-push/Post", function() {
|
||||||
});
|
});
|
||||||
req.session.auth = {
|
req.session.auth = {
|
||||||
userid: 'john'
|
userid: 'john'
|
||||||
}
|
};
|
||||||
|
|
||||||
Assert.equal(req.session.auth.authentication_level, undefined);
|
Assert.equal(req.session.auth.authentication_level, undefined);
|
||||||
const promise = Post(vars)(req, res as any)
|
const promise = Post(vars)(req, res as any)
|
||||||
|
|
|
@ -6,6 +6,8 @@ import * as UserMessage from "../../../../../../shared/UserMessages";
|
||||||
import redirect from "../redirect";
|
import redirect from "../redirect";
|
||||||
import { Level } from "../../../authentication/Level";
|
import { Level } from "../../../authentication/Level";
|
||||||
import { DuoPushConfiguration } from "../../../configuration/schema/DuoPushConfiguration";
|
import { DuoPushConfiguration } from "../../../configuration/schema/DuoPushConfiguration";
|
||||||
|
import GetHeader from "../../../utils/GetHeader";
|
||||||
|
import { HEADER_X_TARGET_URL } from "../../../../../../shared/constants";
|
||||||
const DuoApi = require("@duosecurity/duo_api");
|
const DuoApi = require("@duosecurity/duo_api");
|
||||||
|
|
||||||
interface DuoResponse {
|
interface DuoResponse {
|
||||||
|
@ -17,11 +19,13 @@ interface DuoResponse {
|
||||||
stat: "OK" | "FAIL";
|
stat: "OK" | "FAIL";
|
||||||
}
|
}
|
||||||
|
|
||||||
function triggerAuth(username: string, config: DuoPushConfiguration): Promise<DuoResponse> {
|
function triggerAuth(username: string, config: DuoPushConfiguration, req: Express.Request): Promise<DuoResponse> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
const clientIP = req.ip;
|
||||||
|
const targetURL = GetHeader(req, HEADER_X_TARGET_URL);
|
||||||
const client = new DuoApi.Client(config.integration_key, config.secret_key, config.hostname);
|
const client = new DuoApi.Client(config.integration_key, config.secret_key, config.hostname);
|
||||||
const timer = setTimeout(() => reject(new Error("Call to duo push API timed out.")), 60000);
|
const timer = setTimeout(() => reject(new Error("Call to duo push API timed out.")), 60000);
|
||||||
client.jsonApiCall("POST", "/auth/v2/auth", { username, factor: "push", device: "auto" }, (data: DuoResponse) => {
|
client.jsonApiCall("POST", "/auth/v2/auth", { username, ipaddr: clientIP, factor: "push", device: "auto", pushinfo: `target%20url=${targetURL}`}, (data: DuoResponse) => {
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
resolve(data);
|
resolve(data);
|
||||||
});
|
});
|
||||||
|
@ -37,7 +41,7 @@ export default function(vars: ServerVariables) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const authSession = AuthenticationSessionHandler.get(req, vars.logger);
|
const authSession = AuthenticationSessionHandler.get(req, vars.logger);
|
||||||
const authRes = await triggerAuth(authSession.userid, vars.config.duo_api);
|
const authRes = await triggerAuth(authSession.userid, vars.config.duo_api, req);
|
||||||
if (authRes.response.result !== "allow") {
|
if (authRes.response.result !== "allow") {
|
||||||
throw new Error("User denied access.");
|
throw new Error("User denied access.");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue