diff --git a/ExpressAPI/src/controllers/Session.ts b/ExpressAPI/src/controllers/Session.ts
index 3abcc186dc9bc024fbebd6ad4f5ddcc3c896a619..b8f9f1893da43e97f82b92a54868fa5e0a5f65e2 100644
--- a/ExpressAPI/src/controllers/Session.ts
+++ b/ExpressAPI/src/controllers/Session.ts
@@ -5,7 +5,7 @@ import Config              from '../config/Config';
 import express             from 'express';
 import ApiRequest          from '../types/ApiRequest';
 import UserManager         from '../managers/UserManager';
-import DojoResponse        from '../shared/types/DojoResponse';
+import DojoResponse        from '../shared/types/Dojo/DojoResponse';
 import { User }            from '../types/DatabaseTypes';
 
 
@@ -26,21 +26,23 @@ class Session {
     async initSession(req: ApiRequest) {
         const authorization = req.headers.authorization;
         if ( authorization ) {
-            const jwtToken = authorization.replace('Bearer ', '');
-
-            try {
-                const jwtData = jwt.verify(jwtToken, Config.jwtConfig.secret) as JwtPayload;
-
-                if ( jwtData.profile ) {
-                    this.profile = jwtData.profile;
-                    this.profile = await UserManager.getById(this.profile.id);
-                }
-            } catch ( err ) { }
+            if ( authorization.startsWith('Bearer ') ) {
+                const jwtToken = authorization.replace('Bearer ', '');
+
+                try {
+                    const jwtData = jwt.verify(jwtToken, Config.jwtConfig.secret) as JwtPayload;
+
+                    if ( jwtData.profile ) {
+                        this.profile = jwtData.profile;
+                        this.profile = await UserManager.getById(this.profile.id);
+                    }
+                } catch ( err ) { }
+            }
         }
     }
 
     private static getToken(profileJson: any): string {
-        return profileJson.id === null ? null : jwt.sign({ profile: profileJson }, Config.jwtConfig.secret, Config.jwtConfig.expiresIn > 0 ? { expiresIn: Config.jwtConfig.expiresIn } : {});
+        return profileJson === null ? null : jwt.sign({ profile: profileJson }, Config.jwtConfig.secret, Config.jwtConfig.expiresIn > 0 ? { expiresIn: Config.jwtConfig.expiresIn } : {});
     }
 
     private async getResponse<T>(code: number, data: T, descriptionOverride?: string): Promise<DojoResponse<T>> {
diff --git a/ExpressAPI/src/managers/ExerciceManager.ts b/ExpressAPI/src/managers/ExerciceManager.ts
new file mode 100644
index 0000000000000000000000000000000000000000..489a6e6bb58efcae5dd0d4d24367b4c5401f2cc1
--- /dev/null
+++ b/ExpressAPI/src/managers/ExerciceManager.ts
@@ -0,0 +1,18 @@
+import { Prisma } from '@prisma/client';
+import { Enonce } from '../types/DatabaseTypes';
+import db         from '../helpers/DatabaseHelper';
+
+
+class ExerciceManager {
+    get(id: string, include: Prisma.ExerciceInclude | undefined = undefined): Promise<Enonce | undefined> {
+        return db.exercice.findUnique({
+                                          where  : {
+                                              id: id
+                                          },
+                                          include: include
+                                      });
+    }
+}
+
+
+export default new ExerciceManager();
diff --git a/ExpressAPI/src/middlewares/ParamsCallbackManager.ts b/ExpressAPI/src/middlewares/ParamsCallbackManager.ts
index c0ccb3919fe05658801ab0734a9f08685d4f6446..358da8a97cd1807a6509c077883bd8a054a3dfd7 100644
--- a/ExpressAPI/src/middlewares/ParamsCallbackManager.ts
+++ b/ExpressAPI/src/middlewares/ParamsCallbackManager.ts
@@ -3,6 +3,7 @@ import ApiRequest      from '../types/ApiRequest';
 import express         from 'express';
 import { StatusCodes } from 'http-status-codes';
 import EnonceManager   from '../managers/EnonceManager';
+import ExerciceManager from '../managers/ExerciceManager';
 
 
 class ParamsCallbackManager {
@@ -24,7 +25,8 @@ class ParamsCallbackManager {
     initBoundParams(req: ApiRequest) {
         if ( !req.boundParams ) {
             req.boundParams = {
-                enonce: null
+                enonce  : null,
+                exercice: null
             };
         }
     }
@@ -34,6 +36,12 @@ class ParamsCallbackManager {
             exercices: true,
             staff    : true
         } ], 'enonce');
+
+        this.listenParam('exerciceId', backend, ExerciceManager.get.bind(ExerciceManager), [ {
+            enonce : true,
+            members: true,
+            results: true
+        } ], 'exercice');
     }
 }
 
diff --git a/ExpressAPI/src/middlewares/SecurityMiddleware.ts b/ExpressAPI/src/middlewares/SecurityMiddleware.ts
index 85a60561c690c4be012c9444d0e01251ddc150bc..97a2299be28a358cbba948564a577b52e364e378 100644
--- a/ExpressAPI/src/middlewares/SecurityMiddleware.ts
+++ b/ExpressAPI/src/middlewares/SecurityMiddleware.ts
@@ -11,7 +11,7 @@ class SecurityMiddleware {
     check(checkIfConnected: boolean, ...checkTypes: Array<SecurityCheckType>): (req: ApiRequest, res: express.Response, next: express.NextFunction) => void {
         return async (req: ApiRequest, res: express.Response, next: express.NextFunction) => {
             if ( checkIfConnected ) {
-                if ( req.session.profile.id === null ) {
+                if ( req.session.profile === null ) {
                     return req.session.sendResponse(res, StatusCodes.UNAUTHORIZED);
                 }
             }
@@ -19,9 +19,9 @@ class SecurityMiddleware {
             let isAllowed = checkTypes.length === 0;
 
             if ( !isAllowed ) {
-                for ( let checkType of checkTypes ) {
+                for ( const checkType of checkTypes ) {
                     try {
-                        switch ( checkType ) {
+                        switch ( String(checkType) ) {
                             case SecurityCheckType.TEACHING_STAFF:
                                 isAllowed = isAllowed || req.session.profile.isTeachingStaff;
                                 break;
@@ -31,8 +31,10 @@ class SecurityMiddleware {
                             case SecurityCheckType.ENONCE_IS_PUBLISHED:
                                 isAllowed = isAllowed || req.boundParams.enonce.published;
                                 break;
+                            case SecurityCheckType.EXERCICE_SECRET:
+                                isAllowed = isAllowed || (req.headers.authorization && req.headers.authorization && req.headers.authorization.replace('ExerciceSecret ', '') === req.boundParams.exercice.secret);
+                                break;
                             default:
-                                isAllowed = isAllowed || false;
                                 break;
                         }
                     } catch ( e ) {
diff --git a/ExpressAPI/src/types/ApiRequest.ts b/ExpressAPI/src/types/ApiRequest.ts
index 6d1549c0b6494bf5405778102feb7acf812ca1a1..9a6c06d0016e1017e757ac9796bad4522eccac0a 100644
--- a/ExpressAPI/src/types/ApiRequest.ts
+++ b/ExpressAPI/src/types/ApiRequest.ts
@@ -1,11 +1,11 @@
-import express    from 'express';
-import Session    from '../controllers/Session';
-import { Enonce } from './DatabaseTypes';
+import express              from 'express';
+import Session              from '../controllers/Session';
+import { Enonce, Exercice } from './DatabaseTypes';
 
 
 type ApiRequest = express.Request & {
     session: Session, boundParams: {
-        enonce: Enonce
+        enonce: Enonce, exercice: Exercice
     }
 }
 
diff --git a/ExpressAPI/src/types/SecurityCheckType.ts b/ExpressAPI/src/types/SecurityCheckType.ts
index fcb3a6d0c86ca6aed44dfaa0df6f05201e770b62..b063ff961c724ecef22de1e92718d0b7e3dc1a31 100644
--- a/ExpressAPI/src/types/SecurityCheckType.ts
+++ b/ExpressAPI/src/types/SecurityCheckType.ts
@@ -2,6 +2,7 @@ enum SecurityCheckType {
     TEACHING_STAFF      = 'teachingStaff',
     ENONCE_STAFF        = 'enonceStaff',
     ENONCE_IS_PUBLISHED = 'enonceIsPublished',
+    EXERCICE_SECRET     = 'exerciceSecret',
 }