Skip to content

Commit e600174

Browse files
author
Benoit Ngo
committed
minors fix, explicite Saml2 return url
1 parent e4d21e5 commit e600174

File tree

12 files changed

+65
-30
lines changed

12 files changed

+65
-30
lines changed

.env.dist

+3-3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,6 @@ APP_SSO_SERVICEPROVIDER_X509CERT=MIICkDCCAfmgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBlMQs
3636
APP_SSO_SERVICEPROVIDER_PRIVATEKEY=MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMKCd0hnMKX40MYR+fZNRqMJjSiDpTPTkV9A0bfQKESZ9esPjNt8Janq+2MGLrm6cRcMXRx8yo/x7pfoCmdiu9D7VNhk69nFsNKH0PQp/jf2+vLPHXgKvlcCFvlaOB/Cvg9UnK9mq83H88LPwvrpaNRl4qDrLS5TTByEIohjFUJrAgMBAAECgYEAgLUgBTLzCABa9ZXTl12PDjc1xsdFu8OVgDg+DamZ27sc9Qv3Iw1FRuiMq/vdU1zBlITD4CPbTeDDBpWuvLainACpk4JJK22JozwLpaqnyrrhPNxphBe3XUREe6Tw53q9cM1j9RlD+PwbM2KbudfBmsi+sPvNK0pEAHFJZhogjfECQQDtwqhYQhLUCmgzMMFNU1PYvPJ6+5cdrgxK5JJhQxKJnclUdnjw3zUwdN3XpJk9ggq/GTCAjd/vE8ILV2DXgD6nAkEA0W5pvJx5EG9hekJ3/LaqcIKNH38uqhm4LPrXaLbUOToVyjBsJhlfRVVQojhOT9mAkTs4RhSP0IZy+Xkvh3s6nQJBALPzOnriN2HpJohoBEXEJZfLGjNerDc4ffFJIkke/K7Pj4uvx0V3ishMC4Ok/p6BCCUuqXkC6FQIvjrbPV6dn80CQQDRAZvMe2vmlwF0/fi436Ng/SjRkh+D6n7/hKaM/kj1g55TVdfYfeGyU95QxliBH9NLHQqgBc0wkb0Uc3iXgMeRAkAm30yjx2YPHjXZydKsJFgNtfI0PvoFS8tv1Ljb3FfflzrKEFFBtwfC/kxJXY+oKIKMSW0YxT0EuOkq3K5uIeGd
3737
# THE SSO APP
3838
APP_SSO_IDENTITYPROVIDER_X509CERT=MIIDXTCCAkWgAwIBAgIJALmVVuDWu4NYMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTYxMjMxMTQzNDQ3WhcNNDgwNjI1MTQzNDQ3WjBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzUCFozgNb1h1M0jzNRSCjhOBnR+uVbVpaWfXYIR+AhWDdEe5ryY+CgavOg8bfLybyzFdehlYdDRgkedEB/GjG8aJw06l0qF4jDOAw0kEygWCu2mcH7XOxRt+YAH3TVHa/Hu1W3WjzkobqqqLQ8gkKWWM27fOgAZ6GieaJBN6VBSMMcPey3HWLBmc+TYJmv1dbaO2jHhKh8pfKw0W12VM8P1PIO8gv4Phu/uuJYieBWKixBEyy0lHjyixYFCR12xdh4CA47q958ZRGnnDUGFVE1QhgRacJCOZ9bd5t9mr8KLaVBYTCJo5ERE8jymab5dPqe5qKfJsCZiqWglbjUo9twIDAQABo1AwTjAdBgNVHQ4EFgQUxpuwcs/CYQOyui+r1G+3KxBNhxkwHwYDVR0jBBgwFoAUxpuwcs/CYQOyui+r1G+3KxBNhxkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAAiWUKs/2x/viNCKi3Y6blEuCtAGhzOOZ9EjrvJ8+COH3Rag3tVBWrcBZ3/uhhPq5gy9lqw4OkvEws99/5jFsX1FJ6MKBgqfuy7yh5s1YfM0ANHYczMmYpZeAcQf2CGAaVfwTTfSlzNLsF2lW/ly7yapFzlYSJLGoVE+OHEu8g5SlNACUEfkXw+5Eghh+KzlIN7R6Q7r2ixWNFBC/jWf7NKUfJyX8qIG5md1YUeT6GBW9Bm2/1/RiO24JTaYlfLdKK9TYb8sG5B+OLab2DImG99CJ25RkAcSobWNF5zD0O6lgOo3cEdB/ksCq3hmtlC/DlLZ/D8CJ+7VuZnS1rR2naQ==
39-
APP_SSO_IDENTITYPROVIDER_ENTITYID=http://samltest.${BASE_DOMAIN}/simplesaml/saml2/idp/metadata.php
40-
APP_SSO_IDENTITYPROVIDER_LOGINURL=http://samltest.${BASE_DOMAIN}/simplesaml/saml2/idp/SSOService.php
41-
APP_SSO_IDENTITYPROVIDER_LOGOUTURL=http://samltest.${BASE_DOMAIN}/simplesaml/saml2/idp/SSOService.php
39+
APP_SSO_IDENTITYPROVIDER_ENTITYID=${PROTOCOL}://samltest.${BASE_DOMAIN}/simplesaml/saml2/idp/metadata.php
40+
APP_SSO_IDENTITYPROVIDER_LOGINURL=${PROTOCOL}://samltest.${BASE_DOMAIN}/simplesaml/saml2/idp/SSOService.php
41+
APP_SSO_IDENTITYPROVIDER_LOGOUTURL=${PROTOCOL}://samltest.${BASE_DOMAIN}/simplesaml/saml2/idp/SSOService.php

Makefile

+5
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ restart: down up
8989
.PHONY: frestart
9090
frestart: fdown fup
9191

92+
93+
.PHONY: fbuild
94+
fbuild: ;\
95+
docker compose build --no-cache
96+
9297
.PHONY: stop-front
9398
stop-front: ;\
9499
DOCKER_BUILDKIT=1 docker compose stop front

apps/back/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# syntax=docker.io/docker/dockerfile:1.4
2-
ARG IMAGE_VERSION=php:8.1-v4
2+
ARG IMAGE_VERSION=php:8.2-v4
33
ARG APP_ENV=prod
44
ARG APP_SOURCE_FILE='./'
55
ARG PHP_EXTENSIONS="apcu mysqli pdo_mysql intl gd xdebug"

apps/back/config/services.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ services:
6060
class: App\Authenticator\Saml2Authenticator
6161
arguments:
6262
$checkPath: 'api_login_saml2'
63+
$returnTo: "%app.url.base%/api/1.0/auth/sso/saml2/login"
6364

6465

6566
OneLogin\Saml2\Auth:

apps/back/src/Authenticator/Saml2Authenticator.php

+5-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace App\Authenticator;
66

7-
use App\Exception\SsoConsumerAuthNException;
87
use App\Exception\SsoConsumerException;
98
use OneLogin\Saml2\Auth;
109
use Symfony\Component\HttpFoundation\JsonResponse;
@@ -27,6 +26,8 @@ public function __construct(
2726
private readonly HttpUtils $httpUtils,
2827
private readonly string $checkPath,
2928
private readonly Auth $auth,
29+
private readonly string $returnTo,
30+
private readonly \Psr\Log\LoggerInterface $logger,
3031
) {
3132
}
3233

@@ -44,10 +45,6 @@ public function authenticate(Request $request): Passport
4445
{
4546
$session = $request->getSession();
4647
$authNRequestId = $session->get('AuthNRequestID', null);
47-
if (! \is_string($authNRequestId)) {
48-
throw new SsoConsumerAuthNException();
49-
}
50-
5148
$auth = $this->auth;
5249
$auth->setStrict(false);
5350
$auth->processResponse($authNRequestId);
@@ -99,10 +96,12 @@ public function onAuthenticationFailure(Request $request, AuthenticationExceptio
9996
public function start(Request $request, AuthenticationException|null $authException = null)
10097
{
10198
$session = $request->getSession();
99+
$this->logger->error('Starting auth');
102100
$auth = $this->auth;
103-
$url = $auth->login(null, [], false, false, true);
101+
$url = $auth->login($this->returnTo, [], false, false, true);
104102
$authNRequestId = $auth->getLastRequestID();
105103
$session->set('AuthNRequestID', $authNRequestId);
104+
$this->logger->error("Need redirect to $url");
106105

107106
return new JsonResponse(['url' => $url], Response::HTTP_UNAUTHORIZED);
108107
}

apps/front/nuxt.config.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export default defineNuxtConfig({
1010
// @see https://getbootstrap.com/docs/5.0/getting-started/introduction/#starter-template
1111
charset: "utf-8",
1212
viewport: "width=device-width, initial-scale=1",
13-
title: "KB Backbone",
13+
title: "Boilerplate SF - Nuxt",
1414
meta: [
1515
// <meta name="description" content="My amazing site">
1616
// { name: 'description', content: 'My amazing site.' }

apps/front/src/app.vue

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<div>
33
<NuxtErrorBoundary @error="mHandleError">
4-
<NuxtLayout>
4+
<NuxtLayout v-if="shouldRender">
55
<NuxtPage />
66
</NuxtLayout>
77
</NuxtErrorBoundary>
@@ -15,19 +15,28 @@ const authStore = useAuthUser();
1515
1616
const route = useRoute();
1717
18-
const mHandleError = (e: unknown) => {
18+
const mHandleError = (e: any) => {
1919
logger.error("Primary error boundary", e);
2020
};
21-
const isPendingValue = computed(() => authStore.isPending);
21+
const shouldRender = computed(
22+
() => authStore.isPending
23+
);
2224
// Doing this here instead than in the middleware allow reactivity on the auth user
2325
watchEffect(async () => {
24-
if (isPendingValue.value) {
26+
logger.info("pending");
27+
if (authStore.isPending) {
2528
return;
2629
}
30+
logger.info("resolved pending");
2731
const shouldRedirectToLogin =
2832
!authStore.isAuthenticated &&
2933
authStore.authUrl &&
3034
route.name !== "auth-login";
35+
logger.info("shouldRedirectToLogin");
36+
logger.info(authStore.isAuthenticated);
37+
logger.info(authStore.authUrl);
38+
logger.info(route.name);
39+
logger.info(shouldRedirectToLogin);
3140
if (shouldRedirectToLogin) {
3241
await navigateTo(authStore.authUrl, { external: true });
3342
}
@@ -38,3 +47,4 @@ watchEffect(async () => {
3847
}
3948
});
4049
</script>
50+
cd

apps/front/src/middleware/auth.global.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export default defineNuxtRouteMiddleware(async () => {
55
// We refresh the data information
66
// If the syncMe result in a 401, the component RedirectToLogin will be triggered,
77
// so no need to wait the sync
8+
logger.info("------ in middleware");
89
const mePromise = authStore.syncMe();
910
/**
1011
* We still wait if the user is not authenticated because that may mean

apps/front/src/plugins/appFetch.ts

+16-7
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,28 @@ export default defineNuxtPlugin(() => {
88
const event = useRequestEvent();
99
const headers: {
1010
[key: string]: string;
11-
} = useRequestHeaders(["cookie"]) as {
12-
[key: string]: string;
11+
} = {
12+
...(useRequestHeaders(["cookie"]) as {
13+
[key: string]: string;
14+
}),
15+
...{
16+
accept: "application/json",
17+
},
1318
};
14-
1519
const handleException = (e: any) => {
20+
logger.info("in catch");
1621
// Check if 401 so remove auth info
1722
if (e && e.response && e.response.status === 401 && store.isAuthenticated) {
1823
logger.error("401 error, removing authentication informations");
1924
store.resetAuth();
2025
}
21-
26+
if (!e?.response?.headers) {
27+
throw e;
28+
}
2229
const cookies = (e.response.headers.get("set-cookie") || "").split(",");
30+
logger.info("setting header");
2331
if (process.server && cookies) {
24-
event.res.setHeader("set-cookie", cookies);
32+
event.node.res.setHeader("set-cookie", cookies);
2533
}
2634
throw e;
2735
};
@@ -36,7 +44,7 @@ export default defineNuxtPlugin(() => {
3644

3745
const cookies = (res.headers.get("set-cookie") || "").split(",");
3846
if (process.server && cookies) {
39-
event.res.setHeader("set-cookie", cookies);
47+
event.node.res.setHeader("set-cookie", cookies);
4048
}
4149
return res;
4250
};
@@ -47,12 +55,13 @@ export default defineNuxtPlugin(() => {
4755
) => {
4856
const res = await $fetch.raw<T>(request, {
4957
headers,
58+
5059
...opts,
5160
});
5261

5362
const cookies = (res.headers.get("set-cookie") || "").split(",");
5463
if (process.server && cookies) {
55-
event.res.setHeader("set-cookie", cookies);
64+
event.node.res.setHeader("set-cookie", cookies);
5665
}
5766
return res._data;
5867
};

apps/front/src/server/api/[...].ts

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ export default defineEventHandler(async (event: H3Event) => {
3333
headers: {
3434
host: target.host,
3535
},
36+
fetchOptions: {
37+
redirect: "manual",
38+
},
3639
});
3740
return ret;
3841
});

apps/front/src/store/auth.ts

+14-7
Original file line numberDiff line numberDiff line change
@@ -51,28 +51,35 @@ export const useAuthUser = defineStore({
5151
if (this.isPending) {
5252
return { data: null, error: null, isPending: this.isPending };
5353
}
54+
this.startPending();
5455
// Our session is based on the PHPSESSID cookie
5556
const me = useMe();
5657
try {
57-
this.startPending();
5858
const authUser = await me();
5959
this.setAuthUser(authUser);
6060
this.endPending();
6161
return { data: authUser, error: null, isPending: this.isPending };
62-
} catch (exception: any) {
62+
} catch (e: any) {
63+
const is401 = e?.response?.status === HTTP_UNAUTHORIZED;
64+
// eslint-disable-next-line no-underscore-dangle
65+
const ret = e.response._data;
6366
this.endPending();
64-
const is401 = exception?.response?.status === HTTP_UNAUTHORIZED;
67+
logger.info("in catch syncMe");
68+
this.authUrl = ret?.url || "";
6569
if (!is401) {
6670
// TODO error store in appFetch
67-
throw exception;
71+
return {
72+
data: this.authUser,
73+
error: e,
74+
isPending: this.isPending,
75+
errorData: ret,
76+
};
6877
}
69-
70-
const ret = await exception.response._data;
71-
this.authUrl = ret?.url || "";
7278
return {
7379
data: null,
7480
error: ret,
7581
isPending: this.isPending,
82+
errorData: ret,
7683
};
7784
}
7885
},

docker-compose.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ services:
4242
working_dir: /home/node/app
4343
environment:
4444
# This is used only per the proxy
45-
- NUXT_API_URL=http://${API_DOMAIN}/
45+
- NUXT_API_URL=${PROTOCOL}://${API_DOMAIN}/
4646
proxy:
4747
image: traefik:3.0
4848
container_name: tcm_proxy

0 commit comments

Comments
 (0)