如何使用 Spring Security 为微服务创建自定义安全过滤器

Posted

技术标签:

【中文标题】如何使用 Spring Security 为微服务创建自定义安全过滤器【英文标题】:How to create custom security filter for microservices using Spring Security 【发布时间】:2016-12-20 12:54:06 【问题描述】:

我对 Spring 安全性的基本概念很少。我想为一个应用程序开发多个微服务,我想在其中使用可用于所有微服务的单点身份验证和授权。为了使其更具体,我想创建一个只能在每个微服务应用程序的 web.xml 中使用的通用过滤器。我不想在所有微服务中使用以下内容。

spring-security.xml

<http>
        <intercept-url pattern="/index*" access="ROLE_USER" />
        <access-denied-handler error-page="/customaccessdenied.jsp" />
        <intercept-url pattern="/manage*" access="ROLE_ADMIN" />
        <form-login default-target-url="/index" always-use-default-target="true"/>
        <logout/>
        <!-- <remember-me/> -->
    </http>

    <authentication-manager>
        <authentication-provider>
            <user-service>
                <user name="admin" password="admin" authorities="ROLE_ADMIN,ROLE_USER" />
                <user name="deb" password="deb" authorities="ROLE_USER" />
            </user-service>
        </authentication-provider>
    </authentication-manager>



web.xml
=======
<!-- Spring Security -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

我不想在所有微服务中使用上述内容。我的应用程序应如下图所示。

请帮助我如何实现它,如果您有任何示例应用程序,请提供链接。同样,重点是将所有与安全相关的东西放在一个地方,并使用该库和自定义过滤器,只过滤所有微服务的 web.xml。

我想这样实现

<filter>
        <filter-name>mySecurityFilterChain</filter-name>
        <filter-class>com.world.india.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>mySecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

在这方面我需要您的帮助。希望对其他人有所帮助。

【问题讨论】:

对我来说“我想创建一个只能在每个微服务应用程序的web.xml中使用的通用过滤器。我不想在所有微服务中使用以下内容” 听起来很矛盾。能否请您详细说明。 您需要一个单独的身份验证服务,以便可以将所有未经授权的请求定向到它,这可能会暴露 REST API 或登录页面。所有其他微服务和 Web App 应该只允许授权请求。这可以在配置文件中设置。这样,您所有与授权相关的代码都将驻留在单个模块中。 【参考方案1】:

您可以简单地将所有视图放在文件夹中并设置特定角色的访问权限。 因此,任何带有 /service/* 的请求都可以重定向到登录屏幕,而所有其他请求可能不需要身份验证 (/*)

<http pattern="/resources/**" security="none" />
    <http>
    <intercept-url pattern="/service/*" access="ROLE_ADMIN" />
    <access-denied-handler error-page="/customaccessdenied.jsp" />
    <intercept-url pattern="/manage*" access="ROLE_ADMIN" />
    <form-login default-target-url="/index" always-use-default-     target="true"/>
    <logout/>
    <!-- <remember-me/> -->
</http>

您可以按照tutorial 设置您的自定义安全配置

【讨论】:

【参考方案2】:

有点不清楚您在问什么:从您的图像看来,所有微服务都将驻留在同一个 Web 应用程序中,由同一个 web.xml 配置,但您的代码 sn-p 表明您的微服务将驻留在单独的Web 应用程序,这确实很有意义。

无论哪种方式:只需在 web.xml 中添加一个根应用程序上下文,您可以在其中指定安全配置:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:/common-security-config.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

common-security-config.xml 将是同一 Web 应用程序中所有子应用程序上下文的基本应用程序上下文(在您的情况下:所有微服务等)。把你的 Spring Security 配置放在那里,你应该没事。

如果您的所有微服务都驻留在同一个 Web 应用程序中,那么您只需要这样做;如果没有,只需创建一个包含安全配置(在src/main/resources 中)和安全配置可能需要的任何支持类的通用模块。添加对该模块的引用,并在所有微服务模块的web.xml中添加通用配置。

请注意,无论哪种方式,如果您想使用方法级别的安全性(使用例如@Secured),则需要在每个子微服务的配置中包含此配置。

【讨论】:

【参考方案3】:

从本质上讲,您的问题听起来像是您想要一个可重用的 spring security java 配置(而不是 spring-security.xml)。如果是这样,您可以创建自定义安全依赖项或使用安全即服务。

依赖项:将您的安全实现放在一个 jar(例如 com.world.india.DelegatingFilterProxy)中,并将这个 jar 作为依赖项添加到您的每个服务中。这样一来,您的所有安全更改都将隔离到不同的模块,并且无论何时升级安全性,对其他微服务的唯一更改就是依赖版本。

服务:将您的安全应用程序也部署为服务。现在,问题被简化为在您自己的两个服务(即安全微服务和其他微服务)之间建立安全握手。使用这种方法,安全服务的升级对于使用它的其他服务(例如 A-MicroService)是无缝且透明的(如果您使用服务发现机制)。

有关非基于 XML 的配置的提示,请查看以下答案:Configure Spring Security without XML in Spring 4

【讨论】:

以上是关于如何使用 Spring Security 为微服务创建自定义安全过滤器的主要内容,如果未能解决你的问题,请参考以下文章

在 Docker 中将 Spring-cloud-config 服务器托管为微服务

如何使用 spring-security-saml2 配置服务提供者以使用 EncryptedAssertions?

如何使用 Spring Security 和 Angularjs 保护 Spring Rest 服务?

Spring starter security or spring cloud security 如何保护整个微服务架构?

我们如何使用带有 Spring 5.0 的最新 spring-security-oauth2 jar 来实现授权服务器?

如何使用 Spring Security 实现具有两级令牌认证的 Spring Boot 微服务?