2016-07-11 2 views
1

Я следующие конфигурации безопасности пружинных:Spring JSP безопасности авторизированным тег не работает

<security:http auto-config="true"> 
    <security:intercept-url pattern="/**" access="permitAll" /> 
    <security:form-login 
     login-processing-url="/j_spring_security_check" 
     login-page="/login" 
     default-target-url="/" 
     authentication-failure-url="/login?error" 
     username-parameter="login" 
     password-parameter="password" /> 
    <security:logout logout-url="/j_spring_security_logout" logout-success-url="/login" /> 
    <security:csrf disabled="true"/> 
</security:http> 

Я хочу, чтобы сделать конкретную страницу (скажем индексной страницы («/»)) доступны для всех (и с проверкой подлинности и не- пользователи, прошедшие проверку подлинности), но в то же время могут управлять тем, какие части должны отображаться в jsp, в зависимости от того, аутентифицирован ли пользователь или нет, и его роли.

Моя часть JSP выглядит следующим образом:

<%@ page contentType="text/html" pageEncoding="UTF-8"%> 
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> 
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> 
<%@ taglib prefix="t" tagdir="/WEB-INF/tags" %> 

<t:main> 
    <jsp:attribute name="title"> 
     Posts 
    </jsp:attribute> 
    <jsp:body> 
     <sec:authorize access="hasRole('ADMIN')"> 
      <a href="/blog/createPost">Create post</a> 
     </sec:authorize> 

     <br> 

     <c:forEach var="post" items="${posts}"> 
      <hr width="300" align="left"> 
      <div> 
       <h4><a href="/blog/viewPost/${post.id}">${post.title}</a></h4> 
       <div>${post.content}</div> 
      </div> 
     </c:forEach> 
    </jsp:body> 
</t:main> 

Все механизм аутентификации работает отлично. Проблема в том, что ссылка никогда не отображается, даже если я вхожу в систему, используя роль «ADMIN».

Я пытался отладки моя реализация UserDetailsService и проверить, что «ADMIN» роль успешно извлекается и разливают в UserDetails:

@Override 
public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException { 
    User user = userDao.findOneByLogin(login); 

    if (user == null) { 
     throw new UsernameNotFoundException(login + " not found"); 
    } 

    List<GrantedAuthority> authList = new ArrayList<>(); 
    List<Role> roles = user.getRoles(); 

    for (Role role : roles) { 
     authList.add(new SimpleGrantedAuthority(role.getName())); 
    } 

    return new org.springframework.security.core.userdetails.User(
      user.getLogin(), user.getPassword(), authList); 
} 

Спасибо, заранее!

+0

Пожалуйста, покажите полный код jsp, где используется тег безопасности. – shazin

+0

@shazin Я вставил полный код jsp. –

ответ

1

После нескольких часов поиска и чтений Spring Security 4 документов, наконец, я понял причину проблема.

Вот некоторая информация от весенних Docs:

hasRole([role])

Возвращает истину, если текущий принципал имеет указанную роль. По умолчанию, если поставленная роль не начинается с «ROLE_», она будет добавлена. Это можно настроить, изменив defaultRolePrefix на DefaultWebSecurityExpressionHandler.

hasAuthority([authority])

Возвращает истину, если текущий принципал имеет указанный орган.

Таким образом, в соответствии с приведенными выше утверждениями, мы можем заключить, что, по умолчанию, Spring Security 4 ожидает, что вся ваша «роль», чтобы начать с префиксом «ROLE_», в то время как все остальные threated как простые властями/разрешения.

В моем случае у меня была роль «ADMIN», сохраненная в базе данных, и всякий раз, когда я пытался проверять роль, как hasRole('ADMIN') Spring преобразовывал это в hasRole('ROLE_ADMIN'), оценивая это выражение как false.

Здесь есть два типа исправлений: я переименую свою роль «ADMIN» в «ROLE_ADMIN» (как ожидает Spring) в базе данных или вместо выражения hasAuthority('ADMIN').

1

Ваша проблема, кажется, в конфигурации. Чтобы использовать выражения hasRole, hasAnyRole, вы должны установить use-expressions="true" в теге security:http.

<security:http auto-config="true" use-expressions="true"> 

Иначе вы должны напрямую использовать имя роли непосредственно в теге безопасности,

<sec:authorize access="ADMIN"> 
    <a href="/blog/createPost">Create post</a> 
</sec:authorize> 
+0

Вот простой учебник: https://www.mkyong.com/spring-security/spring-security-access-control-example/ – kaqqao

+0

Документы говорят по умолчанию 'use-expression =" true "'. Во всяком случае, я попытался добавить его, но не помог. Пробовал непосредственно проверку, как 'access =" ADMIN "', это вызвало исключения jsp. –

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