Страница ограничения для не авторизованных пользователей без PHP - PullRequest
0 голосов
/ 04 сентября 2018

В настоящее время я работаю над проектом, который позволяет пользователям аутентифицировать свои учетные записи с помощью наших учетных записей Microsoft для работы / школы. В настоящее время у меня есть страница, где пользователь вызывает API для входа в систему, например:

// Graph API endpoint to show user profile
var graphApiEndpoint = "https://graph.microsoft.com/v1.0/me";

// Graph API scope used to obtain the access token to read user profile
var graphAPIScopes = ["https://graph.microsoft.com/user.read"];

// Initialize application
var userAgentApplication = new Msal.UserAgentApplication(msalconfig.clientID, null, loginCallback, {
    redirectUri: msalconfig.redirectUri
});

//Previous version of msal uses redirect url via a property
if (userAgentApplication.redirectUri) {
    userAgentApplication.redirectUri = msalconfig.redirectUri;
}

window.onload = function () {
    // If page is refreshed, continue to display user info
    if (!userAgentApplication.isCallback(window.location.hash) && window.parent === window && !window.opener) {
        var user = userAgentApplication.getUser();
        if (user) {
            callGraphApi();
        }
    }
}

/**
 * Call the Microsoft Graph API and display the results on the page. Sign the user in if necessary
 */
function callGraphApi() {
    var user = userAgentApplication.getUser();
    if (!user) {
        // If user is not signed in, then prompt user to sign in via loginRedirect.
        // This will redirect user to the Azure Active Directory v2 Endpoint
        userAgentApplication.loginRedirect(graphAPIScopes);
        // The call to loginRedirect above frontloads the consent to query Graph API during the sign-in.
        // If you want to use dynamic consent, just remove the graphAPIScopes from loginRedirect call.
        // As such, user will be prompted to give consent when requested access to a resource that 
        // he/she hasn't consented before. In the case of this application - 
        // the first time the Graph API call to obtain user's profile is executed.
    } else {
        // If user is already signed in, display the user info
        window.location = "calc.html"
        
    }
}

/**
 * Callback method from sign-in: if no errors, call callGraphApi() to show results.
 * @param {string} errorDesc - If error occur, the error message
 * @param {object} token - The token received from login
 * @param {object} error - The error string
 * @param {string} tokenType - The token type: For loginRedirect, tokenType = "id_token". For acquireTokenRedirect, tokenType:"access_token".
 */
function loginCallback(errorDesc, token, error, tokenType) {
    if (errorDesc) {
        showError(msal.authority, error, errorDesc);
    } else {
        callGraphApi();
    }
}

/**
 * Show an error message in the page
 * @param {string} endpoint - the endpoint used for the error message
 * @param {string} error - Error string
 * @param {string} errorDesc - Error description
 */
function showError(endpoint, error, errorDesc) {
    var formattedError = JSON.stringify(error, null, 4);
    if (formattedError.length < 3) {
        formattedError = error;
    }
    document.getElementById("errorMessage").innerHTML = "An error has occurred:<br/>Endpoint: " + endpoint + "<br/>Error: " + formattedError + "<br/>" + errorDesc;
    console.error(error);
}

/**
 * Call a Web API using an access token.
 * @param {any} endpoint - Web API endpoint
 * @param {any} token - Access token
 * @param {object} responseElement - HTML element used to display the results
 * @param {object} showTokenElement = HTML element used to display the RAW access token
 */
function callWebApiWithToken(endpoint, token, responseElement, showTokenElement) {
    var headers = new Headers();
    var bearer = "Bearer " + token;
    headers.append("Authorization", bearer);
    var options = {
        method: "GET",
        headers: headers
    };

    fetch(endpoint, options)
        .then(function (response) {
            var contentType = response.headers.get("content-type");
            if (response.status === 200 && contentType && contentType.indexOf("application/json") !== -1) {
                response.json()
                    .then(function (data) {
                        // Display response in the page
                        console.log(data);
                        responseElement.innerHTML = JSON.stringify(data, null, 4);
                        if (showTokenElement) {
                            showTokenElement.parentElement.classList.remove("hidden");
                            showTokenElement.innerHTML = token;
                        }
                    })
                    .catch(function (error) {
                        showError(endpoint, error);
                    });
            } else {
                response.json()
                    .then(function (data) {
                        // Display response as error in the page
                        showError(endpoint, data);
                    })
                    .catch(function (error) {
                        showError(endpoint, error);
                    });
            }
        })
        .catch(function (error) {
            showError(endpoint, error);
        });
}

/**
 * Sign-out the user
 */
function signOut() {
    userAgentApplication.logout();
}
<!DOCTYPE html>


    <!-- bootstrap reference used for styling the page -->
    
    Home




    
    

Страница также подключена к файлу msalconfig, но я не буду включать этот файл по соображениям безопасности, поскольку он содержит некоторые токены.

Если пользователь успешно вошел в систему, он / она будет перенаправлен на calc.html, простое приложение-калькулятор, которое я разработал только для тестирования. Однако в настоящий момент любой может получить доступ к файлу calc.html, если перейдет по URL-адресу. Мне нужен способ, позволяющий только зарегистрированным пользователям получать доступ к странице, так как в конечном итоге проект позволит различным профессорам и другим сотрудникам в моем учреждении изменять схемы для своих курсов в течение десятилетнего периода. Есть ли способ сделать это без PHP? Если да, то как эти пути выглядят? Я бы предпочел, чтобы все было по сети и на стороне клиента, если это возможно, но я открыт для всего.

1 Ответ

0 голосов
/ 06 сентября 2018

Это довольно открытый вопрос, но я попытаюсь ответить на него.

Во-первых, вы заявляете, что не желаете делиться msaclconfig.js - и я вполне понимаю, если вы не хотите делиться этим со Переполнением стека. Тем не менее, вы предоставляете этот файл всем, кто загружает вашу страницу входа. Это может быть кто угодно.

Для указанного вами варианта использования - несколько человек редактируют и просматривают один и тот же набор данных - вам потребуется компонент на стороне сервера. Однако вам не обязательно создавать или размещать этот компонент самостоятельно. Поскольку вы уже используете сервисы Microsoft для аутентификации, возможно, вы могли бы также использовать их сервисы для хранения данных? Например, API Graph явно рекламирует, что он может получить доступ к Excel, и это может работать как серверная часть хранилища.

Если вы используете службы Microsoft для аутентификации и хранения данных, неавторизованный пользователь, загружающий страницу приложения, может не быть проблемой. Они могут видеть саму страницу, но не могут видеть или редактировать расписание - при условии, что разрешения на просмотр и редактирование резервного хранилища данных, конечно, установлены соответствующим образом. Это, конечно, компромисс безопасности. Просмотр приложения помогает потенциальному злоумышленнику, но это может быть приемлемо, если сервер достаточно безопасен.

Аналогичная вещь применима к любому хранилищу, которое вы можете использовать. При аутентификации генерируется какой-то токен аутентификации. Это должно быть что-то такое, что только сервер может генерировать действительные токены, и что сервер может позже проверить, что токен, полученный от клиента, действителен. При каждом запросе к хранению данных этот токен проверяется, и доступ к данным осуществляется только с действительным токеном. Просмотр статической страницы приложения может не вызывать проблем, поскольку фактическое конфиденциальное содержимое доставляется только авторизованным и авторизованным пользователям.

...