如何使用 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 来实现授权服务器?