2014-01-23 5 views
2

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

У меня есть веб-сайт со страницей по умолчанию (index.jsp). Существует ссылка с индексной страницы на страницу администратора (admin.jsp). Эта страница долгое время защищена паролем с Spring без проблем. Вот контекст безопасности файлов я использую:

<beans:beans xmlns="http://www.springframework.org/schema/security" 
      xmlns:beans="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.1.xsd 
        http://www.springframework.org/schema/security 
        http://www.springframework.org/schema/security/spring-security-3.1.xsd"> 

    <global-method-security pre-post-annotations="enabled" secured-annotations="enabled"/>  

    <http use-expressions="true"> 
     <intercept-url pattern="/admin.jsp" access="hasRole('administrator')" /> 
     <intercept-url pattern="/**" access="permitAll" /> 
     <form-login login-page="/login.jsp" default-target-url="/admin.jsp" /> 
     <logout /> 
    </http> 

    <authentication-manager> 
     <authentication-provider> 
      <user-service> 
       <user name="${admin.username}" password="${admin.password}" authorities="administrator" /> 
      </user-service> 
     </authentication-provider> 
    </authentication-manager> 
</beans:beans> 

теперь у меня есть необходимость защитить паролем index.jsp, а также. Если я дублирует дочерние элементы для элемента (и я создал отдельные Login.jsp файлы, не уверен, если это необходимо), как это:

<http use-expressions="true"> 
     <intercept-url pattern="/index.jsp" access="hasRole('user')" /> 
     <form-login login-page="/indexLogin.jsp" default-target-url="/index.jsp" /> 
     <logout /> 

     <intercept-url pattern="/admin.jsp" access="hasRole('administrator')" /> 
     <form-login login-page="/adminLogin.jsp" default-target-url="/admin.jsp" /> 
     <logout /> 
    </http> 

    <authentication-manager> 
     <authentication-provider> 
      <user-service> 
       <user name="${admin.username}" password="${admin.password}" authorities="administrator" /> 
       <user name="${user.username}" password="${user.password}" authorities="user" /> 
      </user-service> 
     </authentication-provider> 
    </authentication-manager> 

Тогда index.jsp является защищенным паролем точно так, как ожидалось. Однако, если я нажму кнопку, которая открывает страницу admin.jsp на новой вкладке, я получаю сообщение об ошибке 403 - Access. Я предполагаю, что это потому, что он автоматически пытается использовать учетные данные пользователя на странице администратора.

Затем я попытался создать два отдельных элементов, каждый из которых с элементами для каждой отдельной страницы:

<http use-expressions="true"> 
     <intercept-url pattern="/index.jsp" access="hasRole('user')" /> 
     <form-login login-page="/indexLogin.jsp" default-target-url="/index.jsp" /> 
     <logout /> 
    </http> 

    <http use-expressions="true"> 
     <intercept-url pattern="/admin.jsp" access="hasRole('administrator')" /> 
     <form-login login-page="/adminLogin.jsp" default-target-url="/admin.jsp" /> 
     <logout /> 
    </http> 

Тогда я получаю сообщение об ошибке с указанием:

java.lang.IllegalArgumentException: Шаблон универсального матча ('/ **') определяется перед другими шаблонами в цепочке фильтров, заставляя их игнорировать. Пожалуйста, проверьте заказ в вашем пространстве имен или конфигурации фильтра FilterChainProxy.

Может ли кто-нибудь дать мне указатель на то, как заставить Spring запрашивать учетные данные каждый раз, когда он обращается к index.jsp или admin.jsp и не допускает, чтобы существующие учетные данные должен быть использован?

ответ

1

Вы, наверное, не нужно Spring Security «запрашивать учетные данные каждый раз доступ либо index.jsp или admin.jsp». Это было бы не обычным случаем для Spring Security, и даже если вам удастся это сделать, это сделает вещи намного сложнее, когда они будут.

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

Вам необходимо заменить access="permitAll" на access="hasRole('user')" в вашем исходном коде. Так что ваш <http> тег должен выглядеть следующим образом:

<http use-expressions="true"> 
    <intercept-url pattern="/admin.jsp" access="hasRole('administrator')" /> 
    <intercept-url pattern="/**" access="hasRole('user')" /> 
    <form-login login-page="/login.jsp" default-target-url="/admin.jsp" /> 
    <logout /> 
</http> 

Кроме того, сохранить свои изменения в <authentication-manager> тега, но заменить authorities="administrator" с authorities="user,administrator":

<authentication-manager> 
    <authentication-provider> 
     <user-service> 
      <user name="${admin.username}" password="${admin.password}" authorities="user,administrator" /> 
      <user name="${user.username}" password="${user.password}" authorities="user" /> 
     </user-service> 
    </authentication-provider> 
</authentication-manager> 

Spring Security соответствует <intercept-url> правил в порядке, в которые они определены.Во-первых, он проверяет, соответствует ли запрашиваемая страница шаблону /admin.jsp. Если это так, hasRole('administrator') будет использоваться в качестве правила доступа для этой страницы. Все остальные страницы будут соответствовать шаблону /**. Поскольку все прошедшие проверку подлинности пользователи (включая administrator) принадлежат роли user, все остальные страницы будут доступны любому аутентифицированному пользователю.

Вы не можете использовать более одного <form-login> или <logout> тег внутри <http>. Я также сомневаюсь, что вы можете определить более одного раздела <http> в конфигурации Spring.

Дополнительную информацию о настройке Spring Security см. В разделе Spring Security Reference.

UPDATE

Кроме того, замените default-target-url="/admin.jsp" с default-target-url="/index.jsp", потому что вы не хотите, обычные (неадминистративные) пользователи будут перенаправлены на admin.jsp.

+0

. Я понимаю концепцию, которую вы объясняете, и мне она нравится, однако, когда я следую что вы описали, я получил в браузере следующее: «Страница не перенаправляется должным образом. Firefox обнаружил, что сервер перенаправляет запрос на этот адрес таким образом, который никогда не будет завершен». Когда я обращаюсь к url ​​по умолчанию, я перенаправлен в файл приветственного файла (index.jsp), и я могу видеть в адресной строке, что меня перенаправляют на login.jsp. Вот когда я вижу ошибку в Firefox. – Bal

+0

Простое изменение to исправил проблему! – Bal

0

Попробуйте использовать «отказе в доступе обработчик», как это:

<http ...> 
    ... 
    <access-denied-handler error-page="the page you want to redirect to"/> 
</http> 
+0

Так что я должен использовать два отдельных элемента: , один для определения каждой страницы, которая нуждается в безопасности? Если да, то как мне обойти исключение «Универсальный шаблон соответствия ...»? – Bal

+0

Нет, только один элемент , а теперь вместо того, чтобы получать '403 - Access is denied error', вы получите настроенную страницу eorror. –

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