Как я могу связать аутентификацию / авторизацию пользователя Rails с существующими разрешениями на сервере базы данных MySQL? - PullRequest
2 голосов
/ 21 марта 2012

У нас есть сервер баз данных MySQL с множеством баз данных. У нас есть много учетных записей на сервере, которые контролируют доступ к различным базам данных. Я хотел бы связать приложение Rails с этими уже существующими учетными записями. Каждая система аутентификации, которую я могу найти (пока 4), предполагает, что я буду создавать таблицу, предназначенную для модели "Пользователь". Я просто хочу использовать таблицу mysql.user для аутентификации и таблицу mysql.db для авторизации. Существуют ли какие-либо системы аутентификации Rails, которые могли бы использовать «настоящую» систему привилегий MySQL вместо того, чтобы положить одну в ТОП базы данных? Было бы это даже желательно? Если мне придется написать это самому, кто-нибудь предвидит скрывающиеся трудности с таким подходом?

Ответы [ 2 ]

0 голосов
/ 24 июня 2016

Итак, я видел, как за это проголосовали, и отметил, что я никогда не публиковал то, что я сделал.Вот что я разобрался.«GINA» была отдельной, унаследованной базой данных, в которой хранились данные и учетные записи пользователей.Я создал раздел YAML для этого соединения в database.yml и изменил модель User для работы со схемой.

user.rb

class User < ActiveRecord::Base
    establish_connection :gina
    self.table_name = "mysql.user"
    self.primary_key = "user"
end

users_controller.rb

def authenticate
    user = params[:username]
    pass = params[:password]
    valid = authenticate_user(user, pass)
    if valid
        session[:username] = user
        session[:password] = pass
        cookies[:username] = user
        cookies[:password] = pass
        redirect_to gina_tables_path
    else
        redirect_to gina_tables_path, :notice => "Login failed."
    end
end

application_controller.rb

def authenticate_user(user, pass)
    begin
        u = nil if u == 'root'
        u = User.find(user) # <- Here's the call to get the user, with password.
        unless u.nil?
            hash = "*" + Digest::SHA1.hexdigest(Digest::SHA1.digest(pass)).upcase
            old_hash = old_password(pass)
            if u.Password === hash || u.Password === old_hash
                session[:username] = user
                return true
            end
            return false
        end
    rescue Exception => e
        Rails.logger.info(e)
        return false
    end
end

Поскольку модель User основана на строке имени пользователя, User.find (user) получает пользователя из пользовательской таблицы MySQL, которая содержит свой хешированный пароль.,Таким образом, весь трюк сводился к тому, чтобы использовать тот же самый тип хэша пароля, который использует MySQL, и сравнить этот хеш (предоставленный пароль) с хешем в базе данных для этого пользователя.Если они равны, это авторизованный логин.

0 голосов
/ 21 марта 2012

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

Другая причина, по которой веб-приложения часто используют одно и то же имя пользователя / соединение с БД, заключается в том, что при запуске в многопроцессорной среде требуется использовать пулы соединений с БД, в которых они поддерживают соединения с БД, и просто помещать их обратно в пул доступные соединения. Если бы у каждого пользователя было свое собственное соединение, которое он должен был бы инициировать, у вас были бы серьезные проблемы с масштабированием, поскольку у вас было бы открытое соединение с БД для каждого пользователя и вы не могли бы повторно использовать существующие соединения между пользователями.

Если вы можете немного уточнить ваши требования, возможно, мы сможем найти лучшее решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...