Создание защищенного паролем PDF. Как получить уникальный пароль для каждого пользователя?

Я загрузил свои отчеты на JasperServer, где я планирую отчеты и отправляю PDF-файлы в виде вложений по электронной почте пользователям, использующим API-интерфейс заданий. Все работает отлично, однако нам также нужно, чтобы PDF-файлы были зашифрованы. Я прочитал тему вики и смог зашифровать pdf.

Но мы хотим, чтобы пароли были динамическими и разными для каждого пользователя (например, какая-то комбинация их номеров телефонов и даты рождения). Пример, описанный в ссылке, указывает пароль как свойство отчета в файле jrxml.

<property name="net.sf.jasperreports.export.pdf.user.password" value="123456"/>
<property name="net.sf.jasperreports.export.pdf.owner.password" value="123456"/> 

Пароль указывается в виде строки и одинаков для каждого pdf-файла, сгенерированного из этого jrxml.

Я пробовал что-то вроде этого

<property name="net.sf.jasperreports.export.pdf.user.password" value="{$F{dateOfBirth}}"/>

где $F{dateOfBirth} — это дата рождения пользователя, для которого выполняется запрос. Но вместо того, чтобы вводить значение поля, он просто считает его строкой и устанавливает пароль = "{$F{dateOfBirth}}"

Как мне смириться с этим? Есть ли способ установить разные пароли для каждого пользователя?

ПРИМЕЧАНИЕ. Источник данных настроен для отчета на jasperserver. При вызове API выполнения задания Jasperserver выполняет запрос, заполняет отчет, экспортирует его в формате pdf и отправляет пользователю по электронной почте.


person user7153719    schedule 25.11.2016    source источник
comment
@DaveJarvis Спасибо за ответ, Дэвис! Хотя, как я сказал выше, я не могу устанавливать значения с помощью кода Java, потому что отчет запускается JasperServer при вызовах API-интерфейса выполнения задания (community.jaspersoft.com/documentation/) и использует источник данных, настроенный для отчета. Кроме того, что касается свойствExpressions, я думаю, что они предназначены для установки свойств для текстовых полей и таких элементов, где свойства шифрования PDF являются свойствами отчета. В любом случае, я попробую и дам вам знать. Ваше здоровье!   -  person user7153719    schedule 26.11.2016
comment
@Dave Я попробовал выражения свойств, но Jasperserver не принимает jrxml. Это не работает. Разве нет никого, кто использовал динамические пароли для своего jrxml?   -  person user7153719    schedule 26.11.2016
comment
Есть ли у вас возможность выполнить постобработку PDF-файла после его создания, но до его отправки по сети?   -  person Dave Jarvis    schedule 26.11.2016
comment
Нет, оставшийся API выполнения задания выполняет отчет, экспортирует его в формате pdf и отправляет в виде вложения.   -  person user7153719    schedule 26.11.2016
comment
@ user7153719 Вы не можете использовать выражение с параметром (или полем, переменной) в property. Единственный шанс использовать выражение — использовать элемент propertyExpression, но его нельзя использовать в разделе jasperReport. Вы можете использовать Java API   -  person Alex K    schedule 26.11.2016
comment
@Dave Я пробовал это и с параметрами. Это тоже не работает. В любом случае, некоторое время назад я задал другой вопрос JasperReports, на который не получил ответа. Не могли бы вы взглянуть на (stackoverflow.com/questions/40577448/) и посмотрите, можете ли вы помочь. Спасибо за ваше время!   -  person user7153719    schedule 26.11.2016
comment
@Alex Не могли бы вы уточнить, как мне использовать Java API, чтобы решить эту проблему?   -  person user7153719    schedule 26.11.2016
comment
1) Вы можете изменить код библиотеки JasperReports 2) Вы можете изменить код JR Server 3) Вы можете добавить обработчик сообщений   -  person Alex K    schedule 26.11.2016
comment
@Alex AFAIK jasperserver использует скомпилированные банки для обеспечения функций. Как вы предлагаете изменить код?   -  person user7153719    schedule 27.11.2016
comment
Исходный код здесь и Руководство по сборке :)   -  person Alex K    schedule 27.11.2016
comment
Запрашивает имя пользователя/пароль. Требует аутентификации.   -  person user7153719    schedule 27.11.2016


Ответы (2)


Добавьте следующий код в код Java.

JasperPrint print = JasperFillManager.fillReport(jasper, параметры, beanColDataSource2); print.setProperty("net.sf.jasperreports.export.pdf.user.password", "jasper123");

Добавьте JRXML.

 property name="net.sf.jasperreports.export.pdf.encrypted" value="True" 

 property name="net.sf.jasperreports.export.pdf.128.bit.key" value="True"

 property name="net.sf.jasperreports.export.pdf.permissions.allowed" value="PRINTING"
person Pramin Senapati    schedule 21.03.2019

Как упоминалось в одном комментарии, просто используйте Java.

Вот пример того, как я бы это закодировал (это не идеально, но я думаю, вы его получите):

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

import net.sf.jasperreports.engine.JRDefaultScriptlet;
import net.sf.jasperreports.engine.JRScriptletException;
import net.sf.jasperreports.engine.fill.JRFillParameter;

public class GetBirthdayScriptlet extends JRDefaultScriptlet {

    private Connection conn;

    private Connection getConnection() throws JRScriptletException {
        if (conn == null) {
            if (getParameterValue(JRFillParameter.REPORT_CONNECTION) != null) {
                conn = (Connection) (getParameterValue(JRFillParameter.REPORT_CONNECTION));
            } else {
                throw new RuntimeException("No db-connection configured in the report!");
            }
        }
        return conn;
    }

    public String getBirthday(String email) throws JRScriptletException, SQLException {
        ResultSet result = null;
        String resultString = null;
        CallableStatement stmt = getConnection().prepareCall("select birthday from birthday_table where email = " + email);
        stmt.executeUpdate();
        result = stmt.getResultSet();
        if(result.next()){
            result.getString(1);
        }
        return resultString;
    }
}

Упакуйте этот небольшой фрагмент в банку и добавьте его в свой путь сборки Studio, а также загрузите его на свой сервер Jaspersoft.

В вашем отчете щелкните правой кнопкой мыши Скриптлеты -> «Создать скриптлет». Класс скриптлета — GetBirthdayScriptlet (это класс codenippet).

Выражение, которое вы хотите использовать в своем отчете:

$P{>>scriptlet-name<<_SCRIPTLET}.getBirthday("[email protected]")

Вместо ввода строки просто используйте параметр.

Кроме того, возможно, стоит подумать об использовании встроенного параметра Jaspersoft LoggedInUserEmailAddress.

Это помогает, если вы хотите, чтобы живые отчеты были зашифрованы.

person Markus Deindl    schedule 30.11.2016
comment
Спасибо за ответ! Хотя я также пробовал использовать скриптлеты. Проблема заключалась в том, где использовать значение параметра пароля, то есть куда поместить $P{››имя-скриптлета‹‹_SCRIPTLET}.getBirthday([email protected]) в jrxml. Я пробовал что-то вроде этого ‹property name=net.sf.jasperreports.export.pdf.user.password›$P{››имя-скриптлета‹‹_SCRIPTLET}.getBirthday([email protected])‹/property › но тогда jasperserver не загрузил jrxml. Не могли бы вы рассказать мне, как установить значение свойства пароля в параметр скриптлета? - person user7153719; 30.11.2016
comment
Кроме того, пользователь указывает параметры запроса через API-интерфейс выполнения задания. Итак, [email protected] в $P{››имя-скриптлета‹‹_SCRIPTLET}.getBirthday([email protected]) фактически будет указан пользователем в вызовах API. - person user7153719; 30.11.2016
comment
Если вы хотите использовать выражения в свойствах, просто используйте <propertyExpression name="net.sf.jasperreports.export.pdf.user.password"><![CDATA[$P{Password}]]></propertyExpression> - person Markus Deindl; 01.12.2016
comment
Вам придется сделать это в элементе, поскольку компилятор не создает никаких параметров перед установкой свойств отчета. Обычно это работает нормально, но как я только что узнал, export.pdf.user.password — это один из редких случаев, когда это не работает. Теперь я не вижу пути решения этой проблемы... - person Markus Deindl; 01.12.2016
comment
Спасибо за помощь в любом случае!! Я отправил еще один вопрос stackoverflow.com/questions/40577448/, на которое я еще не получил ответа. Не могли бы вы взглянуть на него и посмотреть, если вы могли бы помочь. - person user7153719; 05.12.2016