Статьи

Добавление Spring-Security в Openxava

Вступление

Цель этой статьи — показать, как интегрировать Spring Security поверх автономного приложения Openxava.

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

На этой странице будет показано, как добавить функции безопасности (аутентификация / авторизация) Spring. Основное внимание будет уделено аспектам авторизации, поскольку авторизация часто зависит от конкретной среды предприятия.

Чтобы продемонстрировать интеграцию, в этой статье будет использовано демонстрационное приложение minuteproject Lazuly, созданное для Openxava .

Первая часть определяет и объясняет действия, которые необходимо предпринять. Во второй части объясняется, что может сделать минутный проект для ускорения вашей разработки путем создания привычной интеграции Spring-безопасности для вашего приложения Openxava.

В конце концов, набор тестов будет гарантировать, что полученное приложение правильно защищено для прямого доступа к URL, а также для отображения контента. Кроме того, интеграция технологически неинтрузивна . Вам не нужно менять код Openxava, чтобы он работал.

Spring-Security Openxava интеграция

Технический доступ
URL-
адрес Шаблон URL-адреса выглядит следующим образом
: http: // имя_сервера: порт / applicationcontext / xava / module.jsp? Application = appName & module = moduleName,
который трудно защитить.
Модуль и приложение передаются как параметры.

URL-адрес должен быть пересмотрен с
http: // имя_сервера: порт / applicationcontext / applicationPath / module.
Доступ к параметру запрещен.

Включение доступа по новому URL
Добавьте сервлет

package net.sf.minuteproject.openxava.web.servlet;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ModuleHomeServlet extends HttpServlet {
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  RequestDispatcher dispatcher;
  String [] uri = request.getRequestURI().split("/");
  if (uri.length < 4) {
   dispatcher = request.getRequestDispatcher("/xava/homeMenu.jsp");
  } else {
   dispatcher = request.getRequestDispatcher(
   "/xava/home.jsp?application=" + uri[1] + "&module=" + uri[3]);
  }
  dispatcher.forward(request, response);
 }
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  doGet(request, response);
 }
}

homeMenu.jsp — это страница, содержащая заголовок с меню (для защиты и URL-адрес ссылки на меню которого соответствуют защищенному формату) и нижний колонтитул.

Добавьте конфигурацию сервлета.
Фрагмент конфигурации сервлета в Openxava servlets.xml.

 <servlet>
 <servlet>
  <servlet-name>moduleHome</servlet-name>
  <servlet-class>net.sf.minuteproject.openxava.web.servlet.ModuleHomeServlet</servlet-class>
 </servlet>
 
 <servlet-mapping>
  <servlet-name>moduleHome</servlet-name>
  <url-pattern>/MenuModules/*</url-pattern>
 </servlet-mapping>
 
</servlet>

Этот фрагмент будет упакован в war.xml во время сборки с помощью скрипта муравья OpenXava.

Доступ
Jsp Запретить любой доступ Openxava jsp, за исключением одного из меню.

Для этого добавьте пружинный applicationContext-security.xml в ваш путь к классу (например, папка Openxava src).

<b:beans xmlns="http://www.springframework.org/schema/security"
...
    <http realm="conference Realm">
        <!-- default url -->
  <intercept-url pattern="/xava/homeMenu.jsp" access="ROLE_APPLICATION_USER"/>        
        <intercept-url pattern="/xava/**/*.jsp" access="ROLE_NOT_PRESENT"/>
...

Это означает, что все пути после xava будут доступны (например, css …) безопасно. Jsp ожидает, что один homeMenu.jsp будет доступен для всех зарегистрированных пользователей (т. Е. С ролью ROLE_APPLICATION_USER cf атрибуции в части авторизации далее).
Конечно, убедитесь, что роль ROLE_NOT_PRESENT действительно отсутствует в вашем приложении.

Доступ к бизнесу
Идея состоит в том, чтобы предоставить CRUD доступ на основе сущностей на основе ролей.

Определите роли и UC
Чтобы быть более точным, я определяю 3 роли с их областью действия.
Администратор может администрировать объекты ROLE и COUNTRY.
Application_user может управлять всеми другими связанными с конференцией таблицами, за исключением таблицы основных данных, упомянутой выше.

Рецензент может получить доступ к статистическим представлениям, но не к администрации.
И рецензент, и администратор могут делать то, что может делать Application_user.

В applicationContext-security.xml роль может быть сопоставлена ​​с конкретными URL-адресами.

<b:beans xmlns="http://www.springframework.org/schema/security"
....
    <http realm="conference Realm">
   <!-- secured country -->
        <intercept-url pattern="/MenuModules/Country" access="ROLE_ADMINISTRATOR"/>
  <!-- secured role -->
        <intercept-url pattern="/MenuModules/Role" access="ROLE_ADMINISTRATOR"/>
 <!-- secured stat_mb_by_role -->
        <intercept-url pattern="/MenuModules/MemberPerRoleCountryAndConference" access="ROLE_REVIEWER"/>
 <!-- secured stat_mb_per_ctry_conf -->
        <intercept-url pattern="/MenuModules/MemberPerCountryAndConference" access="ROLE_REVIEWER"/>
  <intercept-url pattern="/MenuModules/**" access="ROLE_APPLICATION_USER"/>

Влияние доступа к ролям на вашу модальную навигацию.
Будьте последовательны
Как я уже говорил, «доступ CRUD к объекту основан на ролях », но механизм воздействия должен отражать это.

OpenXava имеет аннотацию для создания объекта из другого. Тогда логично, что мы не можем создать сущность B из сущности A, если у нас нет прав CRUD на сущность B.

В этом случае механизм будет состоять только из функций поиска.
В нашем сценарии это означает, что пользователь с «application_user» может выбрать только страну, но не может ее создать (нет значков создания или обновления).

Это также верно на уровне меню, пользователь имеет право видеть только те пункты меню, которые соответствуют его профилю.

Здесь меню сделано в JSP. Чтобы обеспечить доступ, вы можете заключить код в код для защиты с помощью кода taglib, поставляемого с Spring Security, или добавить небольшой тег taglib, например следующий isUserInRole.tag, расположенный в web / WEB-INF / tags / common.

<%@ attribute name="role" required="true" %>

<%!

    public boolean hasRole(javax.servlet.http.HttpServletRequest request, String role) {
        return request.isUserInRole(role) || 
            request.isUserInRole(role.toUpperCase()) || 
            request.isUserInRole("ROLE_"+role.toUpperCase());
    }
%>

<%
     String [] roles = role.split(",");
     int length = roles.length;
     boolean isInRole = false;
     for (int i = 0; i < length;i++) {
      String role = (roles[i]);
         if(hasRole(request, role)) {
             isInRole = true;
             break;
         }   
     }
    if(isInRole) {
%>
        <jsp:doBody/>
<%        
    }
%>

Оберните код для защиты здесь меню администратора и каждого пункта меню

<mp:isUserInRole role="administrator">
    <li class="topitem">
      <a href="#" onclick="return false;">
      Administration
      </a>
   <ul class="submenu">
<mp:isUserInRole role="administrator">
        <li><a href="/conference/MenuModules/Country" >Country</a></li>
</mp:isUserInRole>
<mp:isUserInRole role="administrator">
        <li><a href="/conference/MenuModules/Role" >Role</a></li>
</mp:isUserInRole>
   </ul>
 </li>
</mp:isUserInRole> 

Аутентификация / Авторизация

Чтобы пользователь мог работать, он должен быть аутентифицирован и авторизован (момент, когда его профиль роли загружен, предоставляя ему права доступа к бизнесу). Я использую простую аутентификацию и авторизацию на основе информации БД.

Конечно, вы не должны использовать это в производстве;)   В applicationContext-security.xml добавьте следующий фрагмент.

    <authentication-manager>
      <authentication-provider>
        <jdbc-user-service 
          data-source-ref="dataSource" 
          users-by-username-query="SELECT username,password,active FROM user_authentication WHERE username = ?"
          authorities-by-username-query="SELECT username,role FROM user_authorisation WHERE username = ?" 
          />
      </authentication-provider> 
    </authentication-manager>  
    <b:bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <b:property name="jndiName"><b:value>java:comp/env/jdbc/conferenceDS</b:value></b:property>
    </b:bean>  

Оба запроса авторизации и аутентификации должны быть действительными.
Здесь они выполняются поверх представлений, что означает, что вам нужно реализовать 2 представления: user_authentication и user_authorisation.
Источник данных такой же, как и в представлении приложения Openxava, что
дает вам гибкость, потому что, если у вас есть уровень детализации косвенного действия, такой как (user-роль-разрешение), ваше представление может связать пользователя с ролью

Поток аутентификации

В конце концов вам нужно обработать поток аутентификации, состоящий из

  • страница приветствия
  • страница авторизации
  • доступ запрещен
  • ссылка для выхода

Поток обрабатывается applicationContext-security.xml

Добавьте следующий фрагмент.

    <authentication-manager>
    <http realm="conference Realm">

        <intercept-url pattern="/" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
        <intercept-url pattern="/index.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
        <intercept-url pattern="/hello.htm" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
        <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
        <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1"/>
        <http-basic/>
        <logout logout-success-url="/index.jsp"/>
        <remember-me />
        <access-denied-handler error-page="/accessDenied.jsp"/> 

Login.jsp сильно вдохновлен весенним образцом петклиники

<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<%@ page pageEncoding="UTF-8" %>

<html>
  <head>
    <title>Login</title>
  </head>

  <body onload="document.f.j_username.focus();">
    <h1>Login test</h1>

    <p>Locale is: <%= request.getLocale() %></p>
    <%-- this form-login-page form is also used as the
         form-error-page to ask for a login again.
         --%>
    <c:if test="${ not empty param.login_error}">
      <font color="red">
        Your login attempt was not successful, try again.


        Reason: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}"/>.
      </font>
    </c:if>   

    <form name="f" action="<c:url value='j_spring_security_check'/>" method="POST">
      <table>
        <tr><td>User:</td><td><input type='text' name='j_username' value='<c:if test="${ not empty param.login_error }"><c:out value="${SPRING_SECURITY_LAST_USERNAME}"/></c:if>'/></td></tr>
        <tr><td>Password:</td><td><input type='password' name='j_password'></td></tr>
        <tr><td><input type="checkbox" name="_spring_security_remember_me"></td><td>Don't ask for my password for two weeks</td></tr>

        <tr><td colspan='2'><input name="submit" type="submit"></td></tr>
        <tr><td colspan='2'><input name="reset" type="reset"></td></tr>
      </table>

    </form>

  </body>
</html>

index.jsp

<html>
  <head>
    <title>Welcome to Conference</title>
  </head>

  <body>
    <h1>Welcome to Conference</h1>

<a href="/conference/xava/homeMenu.jsp">login</a>

  </body>
</html>

accessDenied.jsp


Доступ заблокирован!

Чтобы не забыть, что функциональность выхода здесь добавлена ​​в меню

<span id="logout"><a href="../j_spring_security_logout">Logoff</a></span> 

Spring зависимости безопасности

Добавьте

файлы безопасности Spring в web / WEB-INF / lib
spring-aop-3.0.4.RELEASE.jar

spring-asm-3.0.4.RELEASE.jar

spring-beans-3.0.4.RELEASE.jar

spring-context-3.0 .4.RELEASE.jar

spring-core-3.0.4.RELEASE.jar

spring-expression-3.0.4.RELEASE.jar

spring-jdbc-3.0.4.RELEASE.jar

spring-security-acl-2.0.3.jar

spring-security-config-3.1.0.M1.jar

spring-security-core-2.0.3.jar

spring-security-core-3.1.0.M1.jar

spring-security-core-tiger-2.0.3.jar

spring-security-taglibs-2.0.3.jar

spring-security-web-3.1.0.M1.jar

spring-tx-3.0.4.RELEASE.jar

spring-web-3.0.4.RELEASE.jar

Весенний контекст безопасности

Весенний контекст безопасности был упомянут на другом уровне, вот полная версия

<?xml version="1.0" encoding="UTF-8"?> 

<b:beans xmlns="http://www.springframework.org/schema/security" 
    xmlns:b="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <authentication-manager> 
      <authentication-provider> 
        <jdbc-user-service 
          data-source-ref="dataSource" 
          users-by-username-query="SELECT username,password,active FROM user_authentication WHERE username = ?" 
          authorities-by-username-query="SELECT username,role FROM user_authorisation WHERE username = ?" 
          /> 
      </authentication-provider> 
    </authentication-manager>  
    
    <http realm="conference Realm">

        <intercept-url pattern="/" access="IS_AUTHENTICATED_ANONYMOUSLY"/> 
        <intercept-url pattern="/index.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY"/> 
        <intercept-url pattern="/hello.htm" access="IS_AUTHENTICATED_ANONYMOUSLY"/> 
        <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>

        <!-- default url --> 

                <intercept-url pattern="/xava/homeMenu.jsp" access="ROLE_APPLICATION_USER"/>        
        <intercept-url pattern="/xava/**/*.jsp" access="ROLE_NOT_PRESENT"/>  
                
                <!-- secured country --> 
        <intercept-url pattern="/MenuModules/Country" access="ROLE_ADMINISTRATOR"/> 
                <!-- secured role --> 
        <intercept-url pattern="/MenuModules/Role" access="ROLE_ADMINISTRATOR"/> 
        <!-- secured stat_mb_by_role --> 
        <intercept-url pattern="/MenuModules/MemberPerRoleCountryAndConference" access="ROLE_REVIEWER"/> 
        <!-- secured stat_mb_per_ctry_conf --> 
        <intercept-url pattern="/MenuModules/MemberPerCountryAndConference" access="ROLE_REVIEWER"/>

        <intercept-url pattern="/MenuModules/**" access="ROLE_APPLICATION_USER"/> 
                
        <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1"/> 
        <http-basic/> 
        <logout logout-success-url="/index.jsp"/> 
        <remember-me /> 
        <access-denied-handler error-page="/accessDenied.jsp"/> 
    </http>

    <b:bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> 
        <b:property name="jndiName"><b:value>java:comp/env/jdbc/conferenceDS</b:value></b:property>

    </b:bean>    
         
</b:beans>

Ссылка на контекст

Openxava listeners.xml — это место, где вы можете установить, что web.xml-сниппеты должны быть упакованы в web.xml во время сборки Openxava.

Добавьте следующий фрагмент

 <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
     
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:applicationContext-security.xml
        </param-value>
    </context-param> 
 
 <filter>
   <filter-name>springSecurityFilterChain</filter-name>
   <filter-class>
     org.springframework.web.filter.DelegatingFilterProxy
   </filter-class>
 </filter>
 
 <filter-mapping>
   <filter-name>springSecurityFilterChain</filter-name>
   <url-pattern>/*</url-pattern>
 </filter-mapping>

Минутный путь 

Выполнение интеграции может занять много времени. Как вы можете заметить, здесь есть некоторые усилия, чтобы код соответствовал веб-приложению здесь Openxava, чтобы быть телохранителем Spring-Security. Между тем, когда речь идет о приложении, ориентированном на данные, эти знания можно кристаллизовать, чтобы они были немедленно доступны.

Потому что … есть основополагающая концепция, которая направляет наш выбор и приводит к лучшим оценкам.

Одно дело их исполнить, другое — заявить об этом. Вопрос в том, как нам указать, к какому объекту получить доступ и к какой роли. Идея состоит в том, чтобы с простотой выразить связь между ролью или разрешением и действием.

В нашем случае действия являются:

  • полный CRUD
  • механизм воздействия

Полный CRUD связан с определенной ролью.

Привязанность (связывание сущности с другим путем поиска) — это когда сущности связаны, но не все роли основных сущностей совпадают с ролями цели. В противном случае любовь идет с созданием и обновлением.

И роли:

  • администратор
  • Application_user
  • рецензент

Теперь настало время для занятий в начальной школе.

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

Раскрасьте все поля, которые полностью CRUD, с соответствующим цветом роли … Да, вы можете нарисовать один и тот же ящик дважды (в результате получается комбинация цветов).

Результат дает вам спектр доступа к цвету вашей БД.

Конечно, мы можем дополнительно уменьшить градиент с помощью другой функции (только для чтения, для конкретного контроллера …), но основная идея очевидна.

Что Minuteproject позволяет вам сделать это, обогащая вашу модель с этим цветовым спектром на уровне объекта или на уровне пакета. Это позволяет вам работать с концепцией, только закрытой для UC, независимой от технологических реализаций.

Фрагмент конфигурации минутного проекта

<package name="admin" alias="Administration">
 <security-color roles="administrator" />
</package>
<package name="statistics">
 <security-color roles="reviewer" />
</package>

поколение

Минутная конфигурация проекта заполнена

Конфигурация похожа на lazuly show case с аспектами безопасности

<!DOCTYPE root>
<generator-config>
 <configuration>
  <model name="conference" version="1.0" package-root="net.sf.mp.demo">
   <data-model>
    <driver name="mysql" version="5.1.16" groupId="mysql"
     artifactId="mysql-connector-java"></driver>
    <dataSource>
     <driverClassName>org.gjt.mm.mysql.Driver</driverClassName>
     <url>jdbc:mysql://127.0.0.1:3306/conference</url>
     <username>root</username>
     <password>mysql</password>
    </dataSource>
    <!-- for Oracle and DB2 please set the schema <schema> </schema> -->
    <primaryKeyPolicy oneGlobal="true">
     <primaryKeyPolicyPattern name="autoincrementPattern"></primaryKeyPolicyPattern>
    </primaryKeyPolicy>
   </data-model>
   <business-model>
    <generation-condition>
     <condition type="exclude" startsWith="user_"></condition>
    </generation-condition>
    <business-package default="conference">
     <condition type="package" startsWith="STAT" result="statistics"></condition>
     <condition type="package" startsWith="COUNTRY" result="admin"></condition>
     <condition type="package" startsWith="ROLE" result="admin"></condition>
    </business-package>
    <enrichment>
     <conventions>
      <column-naming-convention type="apply-strip-column-name-suffix"
       pattern-to-strip="_ID" />
      <reference-naming-convention
       type="apply-referenced-alias-when-no-ambiguity" is-to-plurialize="true" />
     </conventions>
     <package name="admin" alias="Administration">
      <security-color roles="administrator" />
     </package>
     <package name="statistics">
      <security-color roles="reviewer" />
     </package>
     <entity name="COUNTRY" content-type="reference-data">
      <semantic-reference>
       <sql-path path="NAME" />
      </semantic-reference>
     </entity>
     <entity name="CONFERENCE_MEMBER">
      <semantic-reference>
       <sql-path path="FIRST_NAME" />
       <sql-path path="LAST_NAME" />
      </semantic-reference>
      <field name="STATUS">
       <property tag="checkconstraint" alias="conference_member_status">
        <property name="PENDING" value="PENDING" />
        <property name="ACTIVE" value="ACTIVE" />
       </property>
      </field>
      <field name="EMAIL">
       <stereotype stereotype="EMAIL" />
      </field>
     </entity>
     <entity name="SPEAKER">
      <field name="BIO">
       <stereotype stereotype="HTML_TEXT" />
      </field>
      <field name="PHOTO">
       <stereotype stereotype="PHOTO" />
      </field>
      <field name="WEB_SITE_URL">
       <stereotype stereotype="WEBURL" />
      </field>
     </entity>
     <entity name="PRESENTATION">
      <field name="STATUS">
       <property tag="checkconstraint" alias="presentation_status">
        <property name="PROPOSAL" value="PROPOSAL" />
        <property name="ACTIVE" value="ACTIVE" />
       </property>
      </field>
     </entity>
     <entity name="SPONSOR">
      <field name="STATUS">
       <property tag="checkconstraint" alias="sponsor_status">
        <property name="PENDING" value="PENDING" />
        <property name="ACTIVE" value="ACTIVE" />
       </property>
      </field>
      <field name="PRIVILEGE_TYPE">
       <property tag="checkconstraint" alias="sponsor_privilege">
        <property name="GOLDEN" value="Golden" />
        <property name="SILVER" value="Silver" />
        <property name="BRONZE" value="Bronze" />
       </property>
      </field>
     </entity>
     <!-- views -->
     <entity name="stat_mb_per_ctry_conf" alias="MEMBER_PER_COUNTRY_AND_CONFERENCE">
      <virtual-primary-key isRealPrimaryKey="true">
       <property name="virtualPrimaryKey" value="ID" />
      </virtual-primary-key>
     </entity>
     <entity name="stat_mb_by_role" alias="MEMBER_PER_ROLE_COUNTRY_AND_CONFERENCE">
      <virtual-primary-key isRealPrimaryKey="true">
       <property name="virtualPrimaryKey" value="id" />
      </virtual-primary-key>
      <field name="stat_mb_per_ctry_conf_ID" linkToTargetEntity="stat_mb_per_ctry_conf"
       linkToTargetField="id"></field>
     </entity>
    </enrichment>
   </business-model>
  </model>
  <targets>
   <!-- openxava -->
   <target refname="OpenXava" name="OpenXava"
    fileName="mp-template-config-openxava-last-features.xml"
    outputdir-root="../../DEV/output/openxava-springsecurity/conference"
    templatedir-root="../../template/framework/openxava">
    <property name="add-spring-security" value="true" />
   </target>

   <target refname="CACHE-LIB" fileName="mp-template-config-CACHE-LIB.xml"
    templatedir-root="../../template/framework/cache">
   </target>

   <target refname="springsecurity" name="springsecurity"
    fileName="mp-template-config-spring-security.xml" 
                                outputdir-root="../../DEV/output/openxava-springsecurity/conference"
    templatedir-root="../../template/framework/security/spring">
   </target>

   <target refname="JPA2-LIB" fileName="mp-template-config-JPA2-LIB.xml"
    templatedir-root="../../template/framework/jpa">
   </target>

   <target refname="BSLA-LIB" fileName="mp-template-config-bsla-LIB-features.xml"
    templatedir-root="../../template/framework/bsla">
   </target>

  </targets>
 </configuration>
</generator-config>

Основные моменты

  • исключить объекты, начинающиеся с user_ (т. е. объект безопасности, используемый конфигурацией Spring)
  • добавить безопасный доступ на уровне пакета
    • Администратор пакета доступен только администратору роли
    • Статистика пакета доступна только для рецензента ролей
    • пакет по умолчанию (конференция) доступен любому application_user 
  • добавить след весны безопасности в цель
  • добавить ссылку в openxava на Spring-Security

Трек SpringSecurity, содержащий конфигурацию, еще не включен в минутный выпуск 0.8, но будет присутствовать для 0.8.1+.

Настройка базы данных.

Реализация представлений.

Здесь очень глупая реализация.

create view user_authentication as
select 
email as username,
first_name as password,
'1' as active
from 
conference_member
;
create view user_authorisation as
select cm.email as username, r.name as role 
from conference_member cm, role r, member_role mr
where mr.role_id = r.id
and mr.conference_member_id = cm.id
union
select cm.email as username, concat('ROLE_',r.name) as role 
from conference_member cm, role r, member_role mr
where mr.role_id = r.id
and mr.conference_member_id = cm.id
;

Как вы не можете, есть небольшая избыточность в представлении user_authentication, так как иногда администратор роли ссылается иногда на role_administrator. Это будет гомогенизировано в следующем выпуске.

Добавьте некоторое значение по умолчанию.

Здесь очень глупая реализация.

INSERT INTO country (id, name, iso_name) VALUES (-1, 'France', 'FR');
INSERT INTO address (id, street1, street2, country_id) VALUES(-1, 'rue 1', 'rue 2', -1);
INSERT INTO  conference_member (id, conference_id, first_name, last_name, email, address_id, status )
    VALUES  (-1, -1, 'f', 'a', '[email protected]', -1, 'ACTIVE' );
INSERT INTO role (id, name) VALUES (-1, 'ADMINSTRATOR' );  
INSERT INTO role (id, name) VALUES (-2, 'ROLE_APPLICATION_USER' );
INSERT INTO member_role (conference_member_id, role_id) VALUES (-1, -1);  
INSERT INTO member_role (conference_member_id, role_id) VALUES (-1, -2);

Поэтому, когда пользователь [email protected] подключается, он получает роль Администратор, которая позволяет ему получить доступ к меню администратора и создать новую роль с именем «REVIEWER». Он также может создать нового участника конференции и связать его с ролью REVIEWER.

Настройка приложения

Загрузите конфигурацию минутного проекта lazuly-openxava-springsecurity из 
кода Google минуты .

Скопировать файл в / mywork / config

Выполнить

в / mywork / config: model-generation.cmd mp-config-LAZULY-Openxava-with-spring-security.xml

Сгенерированный код отправляется в / DEV / output / openxava-springsecurity / conference

Packaging

Здесь упаковка / развертывание — это два шага (к сожалению):

  • в дистрибутиве OX больше нет команды start-tomcat / stop-tomcat
  • пружинные зависимости не включены

меры

  • Убедитесь, что Openxava 4.3 доступен, а для OX_HOME установлено Openxava 4.3
  • из / DEV / output / openxava-springsecurity / conference запустить сборку-конференцию (.cmd / sh). Это вызовет успешную сборку, но не развертывание из-за информации ранее.
  • Откройте проект, сгенерированный при сборке в рабочей области Openxava
  • Добавьте зависимости безопасности Spring
  • Запустите сервер Tomcat (примечание: источник данных для приложения находится в tomcat / config / context.xml)
  • Развертывание
  • наслаждаться

Тестирование 

страницы приветствия

URL по умолчанию в корне контекста приложения.
Страница авторизации

Любая другая прямая связь, вызываемая там, где пользователь не аутентифицирован, будет перехвачена и перенаправлена ​​на эту страницу.

Контекстное меню.

У пользователя есть доступ к части администратора и конференции, а не к статистике.

URL были изменены. Когда пользователь пытается получить доступ к стандартному URL-адресу в стиле OX, он получает
отказ в
доступе (например, module.jsp).

Добавить рецензента роли

Добавить пользователя


Влияет на пользователя с помощью рецензента ролей и по умолчанию (application_user)

Выйти 


(нажмите выход)

Войти как рецензент


На странице входа введите [email protected] и пароль = b

В контекстном меню вы видите «пакет администратора»

И вы получаете отказ в доступе при манипулировании непосредственно URL

 Теперь приложение защищено.

Вывод

В этой статье была показана конфигурация и манипуляции для интеграции безопасности Spring с openxava без вмешательства.

В нем подчеркивалась новая концепция «спектр доступа к цветам БД» и способы уплотнения информации о безопасности в мелкой конфигурации проекта.

Спектр цветового доступа к БД — это концепция, которая требует только расширения:

  • Специальные функции, контроллеры
  • Процедуры магазина

Это просто выразить и дружелюбный аналитик.

Это не связано с технологией.

Это шаг в простом определении мелкозернистого доступа, его сочетание с доступом на основе профиля и доступом на основе состояния (сделать вручную … на данный момент;)) может проложить путь к
интуитивным и неявным рабочим процессам вместо тяжелых решений BPM.