与Spring Security在同一应用程序中的两个领域?

时间:2010-09-08 20:59:30

标签: java spring security spring-security

我们正在构建一个可供经过身份验证的用户和匿名用户使用的Web应用程序。如果您决定不注册/登录,则只有一组有限的功能。使用Spring Security通过OpenID完成用户身份验证。这很好。

但是,该应用程序还附带了一个部署在<host>/<context-root>/admin的管理UI。我们可以在Spring Security中有两个独立的领域(例如/admin/**的基本身份验证)吗?如何配置?

3 个答案:

答案 0 :(得分:18)

Spring Security在版本3.1中添加了对此场景的支持,该版本目前作为候选版本提供。它由SEC-1171实现,语法的详细信息在3.1中包含的手册中。

然而,它使用起来非常简单。基本上,您只需在Spring Security配置中定义多个http元素,每个领域一个。我们这样使用它:

<!-- 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 /admin下的所有网址都属于该领域而不是默认领域 - 因此/admin下的网址会使用基本身份验证。

答案 1 :(得分:1)

可能的解决方案:

  • /admin添加URL拦截器,需要“ROLE_ADMIN”
  • 配置org.springframework.security.web.authentication.www.BasicAuthenticationFilter的实例以截取/admin网址,并在用户提供相应凭据时将其验证为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的默认实现是一个被动过滤器,即它只是在请求中查找基本的auth头,如果它不存在 - 什么都不做。如果您希望过滤器明确要求客户端进行基本身份验证,则需要将默认实现扩展为开始身份验证入口点:

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网址 - 通过在doFilter方法中进行硬编码或提供适当的包装bean。

答案 2 :(得分:0)

我想不出有两个领域的直接方式(我自己也没试过):

您可以定义两个过滤器in your web.xml,其中每个过滤器具有不同的弹簧配置并且可以自行设置环境。全局事物进入app配置,过滤器配置中的域特定。

如果只是针对不同的身份验证方法,您可以write your own filter然后决定调用哪个过滤器。