mirror of
https://github.com/0rangebananaspy/authelia.git
synced 2024-09-14 22:47:21 +07:00
Fix failing second factor when no default redirection url set.
When no default redirection url was set, Duo push second factor was shown as failing even if authentication was successful.
This commit is contained in:
parent
e3b6410e79
commit
81207b49ad
|
@ -5,14 +5,11 @@ import { triggerDuoPushAuth, triggerDuoPushAuthSuccess, triggerDuoPushAuthFailur
|
|||
export default async function(dispatch: Dispatch, redirectionUrl: string | null) {
|
||||
dispatch(triggerDuoPushAuth());
|
||||
try {
|
||||
const res = await AutheliaService.triggerDuoPush(redirectionUrl);
|
||||
const body = await res.json();
|
||||
if ('error' in body) {
|
||||
throw new Error(body['error']);
|
||||
}
|
||||
const body = await AutheliaService.triggerDuoPush(redirectionUrl);
|
||||
dispatch(triggerDuoPushAuthSuccess());
|
||||
return body;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
dispatch(triggerDuoPushAuthFailure(err.message))
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import { Dispatch } from 'redux';
|
|||
import SecondFactorDuoPush, { StateProps, OwnProps, DispatchProps } from '../../../components/SecondFactorDuoPush/SecondFactorDuoPush';
|
||||
import FetchStateBehavior from '../../../behaviors/FetchStateBehavior';
|
||||
import TriggerDuoPushAuth from '../../../behaviors/TriggerDuoPushAuth';
|
||||
import RedirectionResponse from '../../../services/RedirectResponse';
|
||||
|
||||
|
||||
const mapStateToProps = (state: RootState): StateProps => ({
|
||||
|
@ -12,16 +13,16 @@ const mapStateToProps = (state: RootState): StateProps => ({
|
|||
});
|
||||
|
||||
async function redirectIfPossible(body: any) {
|
||||
if ('redirect' in body) {
|
||||
if (body && 'redirect' in body) {
|
||||
window.location.href = body['redirect'];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
async function handleSuccess(dispatch: Dispatch, res: Response, duration?: number) {
|
||||
async function handleSuccess(dispatch: Dispatch, body: RedirectionResponse | undefined, duration?: number) {
|
||||
async function handle() {
|
||||
const redirected = await redirectIfPossible(res);
|
||||
const redirected = await redirectIfPossible(body);
|
||||
if (!redirected) {
|
||||
await FetchStateBehavior(dispatch);
|
||||
}
|
||||
|
@ -35,9 +36,8 @@ async function handleSuccess(dispatch: Dispatch, res: Response, duration?: numbe
|
|||
}
|
||||
|
||||
async function triggerDuoPushAuth(dispatch: Dispatch, redirectionUrl: string | null) {
|
||||
const res = await TriggerDuoPushAuth(dispatch, redirectionUrl);
|
||||
if (!res) return;
|
||||
await handleSuccess(dispatch, res, 2000);
|
||||
const body = await TriggerDuoPushAuth(dispatch, redirectionUrl);
|
||||
await handleSuccess(dispatch, body, 1000);
|
||||
}
|
||||
|
||||
const mapDispatchToProps = (dispatch: Dispatch, ownProps: OwnProps): DispatchProps => {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import RemoteState from "../views/AuthenticationView/RemoteState";
|
||||
import u2fApi, { SignRequest } from "u2f-api";
|
||||
import Method2FA from "../types/Method2FA";
|
||||
import RedirectResponse from "./RedirectResponse";
|
||||
|
||||
class AutheliaService {
|
||||
static async fetchSafe(url: string, options?: RequestInit): Promise<Response> {
|
||||
|
@ -113,19 +114,28 @@ class AutheliaService {
|
|||
})
|
||||
}
|
||||
|
||||
static async triggerDuoPush(redirectionUrl: string | null): Promise<any> {
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
static async triggerDuoPush(redirectionUrl: string | null): Promise<RedirectResponse | undefined> {
|
||||
const headers: Record<string, string> = {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
if (redirectionUrl) {
|
||||
headers['X-Target-Url'] = redirectionUrl;
|
||||
}
|
||||
return this.fetchSafe('/api/duo-push', {
|
||||
const res = await this.fetchSafe('/api/duo-push', {
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
})
|
||||
});
|
||||
|
||||
if (res.status === 204) {
|
||||
return;
|
||||
}
|
||||
|
||||
const body = await res.json();
|
||||
if ('error' in body) {
|
||||
throw new Error(body['error']);
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
static async initiatePasswordResetIdentityValidation(username: string) {
|
||||
|
|
6
client/src/services/RedirectResponse.ts
Normal file
6
client/src/services/RedirectResponse.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
|
||||
export default interface RedirectResponse {
|
||||
redirect?: string;
|
||||
error?: string;
|
||||
}
|
|
@ -15,7 +15,8 @@ class AutheliaServerFromDist implements AutheliaServerInterface {
|
|||
|
||||
async start() {
|
||||
this.serverProcess = ChildProcess.spawn('./scripts/authelia-scripts serve ' + this.configPath, {
|
||||
shell: true
|
||||
shell: true,
|
||||
env: process.env,
|
||||
} as any);
|
||||
if (this.logInFile) {
|
||||
var logStream = fs.createWriteStream('/tmp/authelia-server.log', {flags: 'a'});
|
||||
|
|
|
@ -20,11 +20,19 @@ storage:
|
|||
local:
|
||||
path: /tmp/authelia/db
|
||||
|
||||
# The Duo Push Notification API configuration
|
||||
duo_api:
|
||||
hostname: duo.example.com
|
||||
integration_key: ABCDEFGHIJKL
|
||||
secret_key: abcdefghijklmnopqrstuvwxyz123456789
|
||||
|
||||
access_control:
|
||||
default_policy: bypass
|
||||
rules:
|
||||
- domain: 'public.example.com'
|
||||
policy: bypass
|
||||
- domain: 'secure.example.com'
|
||||
policy: two_factor
|
||||
|
||||
notifier:
|
||||
smtp:
|
|
@ -3,12 +3,16 @@ import { exec } from "../../helpers/utils/exec";
|
|||
import AutheliaServer from "../../helpers/context/AutheliaServer";
|
||||
import DockerEnvironment from "../../helpers/context/DockerEnvironment";
|
||||
|
||||
// required to query duo-api over https
|
||||
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0 as any;
|
||||
|
||||
const autheliaServer = new AutheliaServer(__dirname + '/config.yml');
|
||||
const dockerEnv = new DockerEnvironment([
|
||||
'docker-compose.yml',
|
||||
'example/compose/nginx/backend/docker-compose.yml',
|
||||
'example/compose/nginx/portal/docker-compose.yml',
|
||||
'example/compose/smtp/docker-compose.yml',
|
||||
'example/compose/duo-api/docker-compose.yml',
|
||||
])
|
||||
|
||||
async function setup() {
|
|
@ -0,0 +1,33 @@
|
|||
import { StartDriver, StopDriver } from "../../../helpers/context/WithDriver";
|
||||
import LoginAs from "../../../helpers/LoginAs";
|
||||
import VerifyIsSecondFactorStage from "../../../helpers/assertions/VerifyIsSecondFactorStage";
|
||||
import ClickOnLink from "../../../helpers/ClickOnLink";
|
||||
import VerifyIsUseAnotherMethodView from "../../../helpers/assertions/VerifyIsUseAnotherMethodView";
|
||||
import ClickOnButton from "../../../helpers/behaviors/ClickOnButton";
|
||||
import Request from 'request-promise';
|
||||
import VerifyIsAlreadyAuthenticatedStage from "../../../helpers/assertions/VerifyIsAlreadyAuthenticatedStage";
|
||||
|
||||
export default function() {
|
||||
before(async function() {
|
||||
this.driver = await StartDriver();
|
||||
|
||||
// Configure the fake API to return allowing response.
|
||||
await Request('https://duo.example.com/allow', {method: 'POST'});
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
await StopDriver(this.driver);
|
||||
});
|
||||
|
||||
it('should send user to already authenticated page', async function() {
|
||||
await LoginAs(this.driver, "john", "password");
|
||||
await VerifyIsSecondFactorStage(this.driver);
|
||||
|
||||
await ClickOnLink(this.driver, 'Use another method');
|
||||
await VerifyIsUseAnotherMethodView(this.driver);
|
||||
await ClickOnButton(this.driver, 'Duo Push Notification');
|
||||
await VerifyIsAlreadyAuthenticatedStage(this.driver, 10000);
|
||||
|
||||
await ClickOnButton(this.driver, "Logout");
|
||||
});
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import AutheliaSuite from "../../helpers/context/AutheliaSuite";
|
||||
import { exec } from '../../helpers/utils/exec';
|
||||
import BypassPolicy from "./scenarii/BypassPolicy";
|
||||
import NoDefaultRedirectionUrl from "./scenarii/NoDefaultRedirectionUrl";
|
||||
|
||||
AutheliaSuite(__dirname, function() {
|
||||
this.timeout(10000);
|
||||
|
@ -10,4 +11,5 @@ AutheliaSuite(__dirname, function() {
|
|||
});
|
||||
|
||||
describe('Bypass policy', BypassPolicy);
|
||||
describe("No default redirection", NoDefaultRedirectionUrl);
|
||||
});
|
|
@ -87,18 +87,6 @@ regulation:
|
|||
ban_time: 900
|
||||
|
||||
notifier:
|
||||
# For testing purpose, notifications can be sent in a file
|
||||
# filesystem:
|
||||
# filename: /tmp/authelia/notification.txt
|
||||
|
||||
# Use your email account to send the notifications. You can use an app password.
|
||||
# List of valid services can be found here: https://nodemailer.com/smtp/well-known/
|
||||
## email:
|
||||
## username: user@example.com
|
||||
## password: yourpassword
|
||||
## sender: admin@example.com
|
||||
## service: gmail
|
||||
|
||||
# Use a SMTP server for sending notifications
|
||||
smtp:
|
||||
username: test
|
||||
|
|
|
@ -6,8 +6,6 @@ port: 9091
|
|||
|
||||
logs_level: debug
|
||||
|
||||
default_redirection_url: https://home.example.com:8080/
|
||||
|
||||
authentication_backend:
|
||||
file:
|
||||
path: ./test/suites/basic/users_database.test.yml
|
||||
|
@ -93,18 +91,6 @@ regulation:
|
|||
ban_time: 900
|
||||
|
||||
notifier:
|
||||
# For testing purpose, notifications can be sent in a file
|
||||
# filesystem:
|
||||
# filename: /tmp/authelia/notification.txt
|
||||
|
||||
# Use your email account to send the notifications. You can use an app password.
|
||||
# List of valid services can be found here: https://nodemailer.com/smtp/well-known/
|
||||
## email:
|
||||
## username: user@example.com
|
||||
## password: yourpassword
|
||||
## sender: admin@example.com
|
||||
## service: gmail
|
||||
|
||||
# Use a SMTP server for sending notifications
|
||||
smtp:
|
||||
username: test
|
||||
|
|
Loading…
Reference in New Issue
Block a user