2012-05-11 1 views
8

Я провел весь день в Google Googling и рассматривал различные вопросы здесь, пытаясь найти лучшее решение для реализации аутентификации и авторизации. Сейчас я придумал часть решения, но надеюсь, что кто-то сможет заполнить пробелы. Я понимаю, что есть много текста ниже, но, пожалуйста, медведь со мной: O)JSF: аутентификация и авторизация, лучший путь вперед

фон

Я унаследовал часть завершена приложение CRM, которое в настоящее время использует JSF 2.0, JavaEE 6, JPA и PostgreSQL база данных. К сожалению, ребята, которые изначально приступили к созданию этого веб-приложения в своей бесконечной мудрости, решили, что лучше всего оставить аутентификацию/авторизацию до конца - я должен его вставить.

Приложение по существу разделено на три слоя - виды, управляемые бобы и DAO. Это означает, что управляемые компоненты особенно «жирны», поскольку они содержат всю логику бизнес-логики, валидации и навигации.

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

  1. Формы проверки подлинности на основе проверки в отношении учетных данных, хранящихся в базе данных PostgreSQL.
  2. Единственная страница, которая будет общедоступной (анонимными пользователями), будет страницей входа в систему.
  3. Мне нужно предотвратить доступ к определенным областям приложения на основе роли пользователей. Например, только пользователи с ролью «Админ» должны иметь доступ к странице создания/редактирования пользователя.
  4. Мне также необходимо ограничить доступ к определенной области страницы. Например, пользователь с ролью «Торговый представитель» должен иметь возможность просматривать сведения о клиентах, но кнопка сохранения/редактирования должна отображаться только в том случае, если у пользователя есть роль «Служба обслуживания клиентов».

Где я в

Первое, что я планирую делать это следовать этому примеру User Authentication and Authorization using JAAS and Servlet 3.0 Login. Это, я считаю, выполнит мои первые 3 требования.

Чтобы показать/скрыть кнопки сохранения и т. Д. На страницах, я могу использовать технику, описанную в this SO answer. Это частично решит требование 4, однако я считаю, что мне все же необходимо обеспечить методы действий и/или управляемые компоненты. Например, я хотел бы иметь возможность добавить аннотацию или что-то к методу save() на компоненте клиента, чтобы гарантировать, что только пользователи с ролью «Служба обслуживания клиентов» могут вызвать это - вот где я начинаю сталкиваться с проблемами ,

Я предполагаю, что одним из вариантов было бы сделать что-то похожее на то, что я предлагаю сделать в представлении, и использовать facesContext, чтобы проверить, является ли текущий пользователь «в роли». Я не увлекаюсь этим, потому что он просто загромождает мой код и вместо этого будет использовать аннотации. Если бы я пошел по этому маршруту, как бы мне вернуть статус http 403?

Javax.annotation.security. * Аннотации, похоже, подходят для декларативно определенного доступа к областям приложения, однако, насколько я понимаю, их можно добавить только в EJB. Это означало бы, что мне нужно будет переместить всю мою бизнес-логику из управляемых компонентов, где она в настоящее время находится на новых EJB. Я думаю, что это будет иметь дополнительное преимущество: отделить бизнес-логику от своего собственного набора классов (делегатов, сервисов или всего, что вы решите называть их).Однако это был бы довольно большой рефактор, которому не удастся избежать отсутствия тестов на единицу или интеграции. Я не уверен, должна ли ответственность за контроль доступа быть на этом новом уровне обслуживания - я думаю, что это должно быть на управляемых компонентах.

Других альтернатив

В ходе моего исследования я нашел много людей, упоминая такие структуры, как Spring и пласты. У меня ограниченный опыт работы с Seam, я думаю, что это было бы хорошо подходит для этого проекта, и из того, что я помню, я считаю, что он решает вопросы авторизации, которые у меня есть, но я думаю, что это слишком поздно, чтобы представить его сейчас ,

Я также видел Сиро упоминается в разных местах. Посмотрев на 10 minute tutorial, это показалось хорошим подспорьем, особенно в сочетании с Deluan Quintao's taglib, но мне не удалось найти никаких учебных пособий или примеров того, как интегрировать его с веб-приложением JSF.

Другая альтернатива, с которой я столкнулся на удивление регулярно, - это обычное решение - это кажется сумасшедшим для меня!

Резюме

В общем то, я бы очень хотел некоторые рекомендации по ли я отправиться вниз правильный путь с точки зрения осуществления аутентификации и авторизации, и как я заполняю в этой отсутствующей части крепежного человека методы и/или управляемые компоненты (или, по меньшей мере, код, который они делегируют) и/или как я могу вручную возвращать HTTP Status 403.

+1

> Я не смог найти никаких учебных пособий или примеров того, как их интегрировать с веб-приложением JSF. - Сейчас один, но он все еще не идеален: http://balusc.blogspot.com/2013/01/apache-shiro-is-it-ready-for-java-ee-6.html –

ответ

3

После проведения большого объема исследований я пришел к выводу, что, во-первых, требования моего приложения выиграют от развертывания на сервере приложений, который полностью реализует спецификацию Java EE, а не в контейнере сервлетов, таком как Tomcat. Поскольку проект, над которым я работаю, использует Maven, ключевым моментом здесь было правильное установление зависимостей - это было непросто, и он принял справедливую битву, пробную версию и ошибку: я уверен, что существует более научный подход, который может быть принято.

Мне тогда пришлось create a mysql module, чтобы заставить мое приложение правильно поговорить с базой данных, а затем удалить фабрику, которая была реализована для создания DAO и конвертировать их в EJB. Мне также пришлось обновить hibernate.cfg.xml, чтобы ссылаться на источник данных, который я добавил, и persistence.xml, чтобы установить тип транзакции в JTA, а также ссылаться на источник данных JTA. Единственное другое осложнение заключалось в том, что использовался шаблон Open Session In View, что означало, что я закончил с лёгкими ошибками инициализации в спящем режиме, когда объекты были просмотрены в представлениях. Я переопределил фильтр, как показано внизу этого ответа, чтобы обойти это. Я рассматриваю это как временную меру, чтобы все снова работало, прежде чем я могу надеяться реорганизовать эту область и удалить необходимость в фильтре.

Перемещение в JBoss заняло чуть больше дня, и я уверен, что это могло быть сделано намного быстрее, если бы я был более опытным с Java EE и Maven. Теперь, когда я нахожусь в этом положении, я вхожу в хорошее положение, чтобы иметь возможность отбросить безопасность шва 3 в проект и использовать это, вместо того, чтобы пытаться взломать решение, которое по сути является тем направлением, которое я собирался предпринять. Хорошая вещь о Seam 3 заключается в том, что вы можете в определенной степени выбрать, какие модули вы используете, а не добавлять всю структуру (например, Seam 2). Я думаю, что ряд других модулей также будет полезен, но поможет мне, среди прочего, избавиться от шаблона открытого сеанса.

Одна вещь, которая касалась меня использованием Seam, состояла в том, что мне сообщили о DeltaSpike. Кажется, похоже, что он, вероятно, заменит шов, и нет планов на какие-либо другие версии шва. Я решил, что, поскольку шов все еще поддерживается, и если DeltaSpike занимает столько времени, чтобы реализовать его в качестве шва 3, то довольно безопасно использовать шов 3.

Я надеюсь, обойтись, написав надлежащее сообщение в блоге, описывающее эта миграция достаточно подробно.

public class OSVRequestFilter implements Filter { 

    private static final String UserTransaction = "java:comp/UserTransaction"; 

    private static Logger logger = LoggerFactory.getLogger(EntityManagerRequestFilter.class); 

    public void init(FilterConfig config) throws ServletException { 
    } 

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
     if (request instanceof HttpServletRequest) { 
      doFilter(request, response, chain, getUserTransaction()); 
     } 
    } 

    private UserTransaction getUserTransaction() throws ServletException { 
     try { 
      Context ctx = new InitialContext(); 
      return (UserTransaction)PortableRemoteObject.narrow(ctx.lookup(UserTransaction), UserTransaction.class); 
     } 
     catch (NamingException ex) { 
      logger.error("Failed to get " + UserTransaction, ex); 
      throw new ServletException(ex); 
     } 
    } 

    private void doFilter(ServletRequest request, ServletResponse response, FilterChain chain, UserTransaction utx) throws IOException, ServletException { 
     try { 
      utx.begin(); 

      chain.doFilter(request, response); 

      if (utx.getStatus() == Status.STATUS_ACTIVE) 
       utx.commit(); 
      else 
       utx.rollback(); 
     } 
     catch (ServletException ex) { 
      onError(utx); 
      throw ex; 
     } 
     catch (IOException ex) { 
      onError(utx); 
      throw ex; 
     } 
     catch (RuntimeException ex) { 
      onError(utx); 
      throw ex; 
     } 
     catch (Throwable ex){ 
      onError(utx); 
      throw new ServletException(ex); 
     } 
    } 

    private void onError(UserTransaction utx) throws IOException, ServletException { 
     try { 
      if ((utx != null) && (utx.getStatus() == Status.STATUS_ACTIVE)) 
       utx.rollback(); 
     } 
     catch (Throwable e1) { 
      logger.error("Cannot rollback transaction", e1); 
     } 
    } 

    public void destroy() { 
    } 
} 
2

вы пробовали что-нибудь с Spring Security - последняя версия 3 существо

http://janistoolbox.typepad.com/blog/2010/03/j2ee-security-java-serverfaces-jsf-spring-security.html

http://ocpsoft.org/java/jsf-java/spring-security-what-happens-after-you-log-in/

, а не с помощью запроса фильтра или с использованием JAAS, пружинная безопасностью является всеобъемлющей системой безопасности, которая позволит решить большинство ваших проблем безопасности. Вы можете использовать его для аутентификации пользователя с использованием области db, авторизации и перенаправления по мере необходимости на основе предоставленной информации аутентификации.

вы можете обеспечить методы, которые вы написали http://blog.solidcraft.eu/2011/03/spring-security-by-example-securing.html

@PreAuthorize ("hasRole ('ROLE_XXX')") является способ

сделать определенные элементы страницы безопасной .. // содержание

более чтения и примеры http://static.springsource.org/spring-security/site/petclinic-tutorial.html

+0

Спасибо за ваш ответ. Я как бы беру твой совет, но с явным поворотом - вместо этого я буду использовать защиту от шва: O) – s1mm0t

Смежные вопросы