Две области в одном приложении с Spring Security?

Мы создаем веб-приложение, доступное как аутентифицированным, так и анонимным пользователям. Если вы решите не регистрироваться / не входить в систему, у вас будет ограниченный набор функций. Аутентификация пользователя выполняется через OpenID с помощью Spring Security. Это нормально работает.

Однако приложение также поставляется с пользовательским интерфейсом администратора, который развертывается в <host>/<context-root>/admin. Можем ли мы иметь две отдельные области с Spring Security (например, базовую аутентификацию для /admin/**)? Как это нужно настроить?


person Marcel Stör    schedule 08.09.2010    source источник


Ответы (3)


Spring Security добавила поддержку этого сценария в версии 3.1, которая в настоящее время доступна как Release Candidate. Он был реализован SEC-1171, и подробности синтаксиса приведены в руководстве, включенном в 3.1. .

Однако пользоваться им довольно просто. По сути, вы просто определяете несколько http элементов в своей конфигурации Spring Security, по одному для каждой области. Мы используем это так:

<!-- Configure realm for system administration users -->
<security:http pattern="/admin/**" create-session="stateless">
    <security:intercept-url pattern='/**' access='ROLE_ADMIN' requires-channel="https" />
    <security:http-basic/>  
</security:http>


<!-- Configure realm for standard users -->
<security:http auto-config="true" access-denied-page="/error/noaccess" use-expressions="true" create-session="ifRequired">
    <security:form-login login-page="/login"
            ...
            ...
</security:http>

Ключевой момент, на который следует обратить внимание, - это pattern="/admin/**" на первом http элементе. Это сообщает Spring, что все URL-адреса в /admin подчиняются этой области, а не области по умолчанию - и, следовательно, URL-адреса в /admin вместо этого используют базовую аутентификацию.

person gutch    schedule 20.02.2011
comment
Я копался повсюду, пытаясь понять, как именно это сделать, спасибо, что так ясно указал на это! - person David Parks; 15.03.2011
comment
Spring Security 3.1.0 официально выпущен 7 декабря 2011 г. - person lrkwz; 14.05.2012
comment
Я делаю именно это, и если я вошел в раздел администратора, я также вошел в раздел пользователя, но не авторизован (конечно). Я думаю, это потому, что Spring Security держит авторизацию в сеансе под одним ключом. Есть ли способ настроить безопасность Spring для сценария, в котором вы можете войти в раздел администратора и пользователя одновременно с другим объектом авторизации? - person michal.kreuzman; 04.12.2012
comment
похоже, что синтаксис для атрибута доступа неправильный, должен быть: access = hasRole ('ROLE_name') - person Adam; 31.10.2013

Возможное решение:

  • Добавить перехватчик URL для /admin, требуется "ROLE_ADMIN"
  • Настройте экземпляр org.springframework.security.web.authentication.www.BasicAuthenticationFilter для перехвата /admin URL-адреса и аутентификации пользователя как ROLE_ADMIN, если он предоставляет соответствующие учетные данные

Пример конфигурации:

<security:intercept-url pattern="/admin" access="ROLE_ADMIN"/>

<bean id="basicAuthenticationEntryPoint" 
      class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint">
    <property name="realmName" 
              value="WS realm"/>
</bean>

<bean id="basicAuthenticationProcessingFilter"
      class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
    <property name="authenticationManager" 
              ref="authenticationManager"/>
    <property name="authenticationEntryPoint" 
              ref="basicAuthenticationEntryPoint"/>    
</bean>

Примечание: реализация BasicAuthenticationFilter по умолчанию является пассивным фильтром, то есть он просто ищет в запросе базовый заголовок аутентификации и, если он отсутствует, ничего не делает. Если вы хотите, чтобы фильтр явно запрашивал базовую аутентификацию от клиента, вам необходимо расширить реализацию по умолчанию, чтобы перейти к точке входа аутентификации:

public class BasicAuthenticationFilter 
       extends org.springframework.security.web.authentication.www.BasicAuthenticationFilter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        final HttpServletRequest request = (HttpServletRequest) req;
        final HttpServletResponse response = (HttpServletResponse) res;

        String header = request.getHeader("Authorization");

        if ((header != null) && header.startsWith("Basic ")) {
            super.doFilter(req, res, chain);
        } else {
            getAuthenticationEntryPoint().commence(request, response, new AuthenticationCredentialsNotFoundException("Missing credentials"));
        }
    }
}

Кроме того, вам необходимо настроить фильтр для применения только к /admin URL - либо жестко закодировав это в методе doFilter, либо предоставив соответствующий bean-компонент оболочки.

person Boris Kirzner    schedule 06.01.2011

Я не могу придумать простой способ иметь две области (и сам не пробовал):

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

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

person dube    schedule 09.09.2010