Java spring-rest/ Jersey 如何使用过滤器确保休息路线安全
Java spring-rest/ Jersey how secure rest route with filter
我在 pom.xml
中使用了以下内容,它实际上保护了 root route,
我看到身份验证过程在浏览器中启动了几秒钟
<filter>
<filter-name>CsrfFilter</filter-name>
<filter-class>org.apache.catalina.filters.RestCsrfPreventionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CsrfFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
现在,当用户选择它们时,我需要保护它们的特定路由...
@Path("/run")
public class Service {
...
@GET
@Path("connect/{param}")
public Response connectToHost(@PathParam("param") String host) {
我应该怎么做?如上所述通过 pom 上的配置还是通过每条路线的代码?
首先应将过滤器添加到 web.xml 文件中。它不应 添加到 pom.xml 文件。 pom.xml 只是构建项目的清单。
由于最好只为您预期的 CSRF 预防过滤器保护特定的 url,因此请在过滤器映射中使用特定的 url。
为上述 /run
路径提供了示例。
<filter>
<filter-name>CsrfFilter</filter-name>
<filter-class>org.apache.catalina.filters.RestCsrfPreventionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CsrfFilter</filter-name>
<url-pattern>/run</url-pattern>
</filter-mapping>
请参考this oracle documentation了解web.xml元素的用法。
要进一步了解过滤请求和响应,请参阅 this oracle tutorial。
参考this practical tutorial了解如何在xml和注释方法中配置过滤器。请注意,您不必以两种方式进行配置。它可以根据您的喜好以基于 xml 或基于注释的方式完成。
您需要 class 扩展 WebSecurityConfigurerAdapter
@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
RequestMatcher csrfRequestMatcher = new RequestMatcher() {
private AntPathRequestMatcher[] requestMatchers = {
new AntPathRequestMatcher("/run/connect/**")
};
@Override
public boolean matches(HttpServletRequest request) {
for (AntPathRequestMatcher rm : requestMatchers) {
// If request matches specified urls, apply csfr
if (rm.matches(request)) { return true; }
}
return false;
}
};
http
// Enable csrf only on some request matches
.csrf()
.requireCsrfProtectionMatcher(csrfRequestMatcher)
//Other configurations
}
}
您的问题中有一些令人困惑的地方,但我会尽力涵盖。
一个。过滤器设置 - 根据您的问题,您在 pom.xml
中进行了过滤器设置。但实际上过滤器设置总是在 web.xml
文件中进行。如果您错误地命名了 pom.xml 则忽略,但如果没有则将过滤器设置移动到 web.xml.
两个。 在您的问题标签中,您提到您的查询与 spring-boot、spring-security 有关。但是您所附的代码示例表明您可能正在使用 jersey 来创建 rest api,而不是使用 spring、spring-security。您实际上是在尝试在 tomcat 服务器级别的较低级别使用 csrf 保护。没关系。
三个。 CSRF 保护可以与 spring 安全以及 tomcat api 一起使用。
FOUR. 如果您想了解 spring 安全性如何为 rest 端点提供 csrf 保护,您必须在代码中提供以下配置。
@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
}
这将为您的应用程序的所有 POST、PUT、PATCH、DELETE 请求提供 csrf 保护。请参阅 - https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html 了解更多详情。
五个。 现在,关于如何为基于 jersey 的休息端点的多条路由提供 csrf 保护的实际问题...您可以提供多个 url 模式,如下所示。
<filter>
<filter-name>CsrfFilter</filter-name>
<filter-class>org.apache.catalina.filters.RestCsrfPreventionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CsrfFilter</filter-name>
<url-pattern>/run</url-pattern>
<url-pattern>/path1</url-pattern>
<url-pattern>/path2</url-pattern>
</filter-mapping>
有关 RestCsrfPreventionFilter
的更多详细信息,请参阅 - https://tomcat.apache.org/tomcat-8.0-doc/config/filter.html#CSRF_Prevention_Filter_for_REST_APIs。
**
如果您未使用任何其他规范,则使用 spring 安全性是保护完整 Web 服务安全的最佳方式。
**
1。 使用Spring方式需要声明
过滤器映射 ->
<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>
2。然后你必须创建一个 spring-security.xml 。你可以声明你的
你想阻止的方法 access.So 你可以要求一些
在访问该方法之前检查授权。
<beans:bean id="cacheManager"
class="org.springframework.cache.support.SimpleCacheManager">
<beans:property name="caches">
<beans:set>
<beans:bean
class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean">
<beans:property name="name" value="ltPrevileges"/>
</beans:bean >
<beans:bean
class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean">
<beans:property name="name" value="dashboard"/>
</beans:bean >
</beans:set>
</beans:property>
</beans:bean>
<beans:bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheCacheManager" >
<beans:property name="cacheManager" ref="ehcache"></beans:property>
</beans:bean>
<beans:bean id="ehcache"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" >
<beans:property name="configLocation" value="classpath:ehcache.xml"></beans:property>
<beans:property name="shared" value="true"></beans:property>
</beans:bean>
<security:http use-expressions="true" auto-config="false"
entry-point-ref="http403EntryPoint"
pattern="/sheel/practice/getBatchDetails"
create-session="stateless">
<security:csrf disabled="true" />
<security:custom-filter position="PRE_AUTH_FILTER"
ref="authorizationGlobalFilterBean" />
</security:http>
</beans:bean>
<!-- Login auth ends here -->
<!-- PreAuth starts here -->
<security:http use-expressions="true" auto-config="false"
entry-point-ref="http403EntryPoint" pattern="/framework/**"
create-session="stateless">
<security:csrf disabled="true" />
<security:custom-filter position="PRE_AUTH_FILTER"
ref="siteminderFilter" />
</security:http>
<beans:bean id="authorizationGlobalFilterBean"
class="com.xplanr.framework.security.AuthorizationGlobalFilter">
</beans:bean>
<beans:bean id="siteminderFilter"
class="org.springframework.security.web.authentication.preauth.RequestHeader AuthenticationFilter">
<beans:property name="principalRequestHeader" value="sessionId" />
<beans:property name="authenticationManager"
ref="authenticationManager" />
</beans:bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider
ref="preauthAuthProvider" />
</security:authentication-manager>
<beans:bean id="preauthAuthProvider"
class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<beans:property name="preAuthenticatedUserDetailsService">
<beans:bean id="userDetailsServiceWrapper"
class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<beans:property name="userDetailsService"
ref="customUserDetailsService" />
</beans:bean>
</beans:property>
</beans:bean>
<beans:bean id="customUserDetailsService"
class="com.practice.framework.security.CustomUserDetailsService">
</beans:bean>
<beans:bean id="http403EntryPoint"
class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint">
</beans:bean>
<!--PreAuth ends here -->
</beans:beans>
我在 pom.xml
中使用了以下内容,它实际上保护了 root route,
我看到身份验证过程在浏览器中启动了几秒钟
<filter>
<filter-name>CsrfFilter</filter-name>
<filter-class>org.apache.catalina.filters.RestCsrfPreventionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CsrfFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
现在,当用户选择它们时,我需要保护它们的特定路由...
@Path("/run")
public class Service {
...
@GET
@Path("connect/{param}")
public Response connectToHost(@PathParam("param") String host) {
我应该怎么做?如上所述通过 pom 上的配置还是通过每条路线的代码?
首先应将过滤器添加到 web.xml 文件中。它不应 添加到 pom.xml 文件。 pom.xml 只是构建项目的清单。
由于最好只为您预期的 CSRF 预防过滤器保护特定的 url,因此请在过滤器映射中使用特定的 url。
为上述 /run
路径提供了示例。
<filter>
<filter-name>CsrfFilter</filter-name>
<filter-class>org.apache.catalina.filters.RestCsrfPreventionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CsrfFilter</filter-name>
<url-pattern>/run</url-pattern>
</filter-mapping>
请参考this oracle documentation了解web.xml元素的用法。
要进一步了解过滤请求和响应,请参阅 this oracle tutorial。
参考this practical tutorial了解如何在xml和注释方法中配置过滤器。请注意,您不必以两种方式进行配置。它可以根据您的喜好以基于 xml 或基于注释的方式完成。
您需要 class 扩展 WebSecurityConfigurerAdapter
@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
RequestMatcher csrfRequestMatcher = new RequestMatcher() {
private AntPathRequestMatcher[] requestMatchers = {
new AntPathRequestMatcher("/run/connect/**")
};
@Override
public boolean matches(HttpServletRequest request) {
for (AntPathRequestMatcher rm : requestMatchers) {
// If request matches specified urls, apply csfr
if (rm.matches(request)) { return true; }
}
return false;
}
};
http
// Enable csrf only on some request matches
.csrf()
.requireCsrfProtectionMatcher(csrfRequestMatcher)
//Other configurations
}
}
您的问题中有一些令人困惑的地方,但我会尽力涵盖。
一个。过滤器设置 - 根据您的问题,您在 pom.xml
中进行了过滤器设置。但实际上过滤器设置总是在 web.xml
文件中进行。如果您错误地命名了 pom.xml 则忽略,但如果没有则将过滤器设置移动到 web.xml.
两个。 在您的问题标签中,您提到您的查询与 spring-boot、spring-security 有关。但是您所附的代码示例表明您可能正在使用 jersey 来创建 rest api,而不是使用 spring、spring-security。您实际上是在尝试在 tomcat 服务器级别的较低级别使用 csrf 保护。没关系。
三个。 CSRF 保护可以与 spring 安全以及 tomcat api 一起使用。
FOUR. 如果您想了解 spring 安全性如何为 rest 端点提供 csrf 保护,您必须在代码中提供以下配置。
@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
}
这将为您的应用程序的所有 POST、PUT、PATCH、DELETE 请求提供 csrf 保护。请参阅 - https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html 了解更多详情。
五个。 现在,关于如何为基于 jersey 的休息端点的多条路由提供 csrf 保护的实际问题...您可以提供多个 url 模式,如下所示。
<filter>
<filter-name>CsrfFilter</filter-name>
<filter-class>org.apache.catalina.filters.RestCsrfPreventionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CsrfFilter</filter-name>
<url-pattern>/run</url-pattern>
<url-pattern>/path1</url-pattern>
<url-pattern>/path2</url-pattern>
</filter-mapping>
有关 RestCsrfPreventionFilter
的更多详细信息,请参阅 - https://tomcat.apache.org/tomcat-8.0-doc/config/filter.html#CSRF_Prevention_Filter_for_REST_APIs。
**
如果您未使用任何其他规范,则使用 spring 安全性是保护完整 Web 服务安全的最佳方式。
** 1。 使用Spring方式需要声明 过滤器映射 ->
<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>
2。然后你必须创建一个 spring-security.xml 。你可以声明你的 你想阻止的方法 access.So 你可以要求一些 在访问该方法之前检查授权。
<beans:bean id="cacheManager"
class="org.springframework.cache.support.SimpleCacheManager">
<beans:property name="caches">
<beans:set>
<beans:bean
class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean">
<beans:property name="name" value="ltPrevileges"/>
</beans:bean >
<beans:bean
class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean">
<beans:property name="name" value="dashboard"/>
</beans:bean >
</beans:set>
</beans:property>
</beans:bean>
<beans:bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheCacheManager" >
<beans:property name="cacheManager" ref="ehcache"></beans:property>
</beans:bean>
<beans:bean id="ehcache"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" >
<beans:property name="configLocation" value="classpath:ehcache.xml"></beans:property>
<beans:property name="shared" value="true"></beans:property>
</beans:bean>
<security:http use-expressions="true" auto-config="false"
entry-point-ref="http403EntryPoint"
pattern="/sheel/practice/getBatchDetails"
create-session="stateless">
<security:csrf disabled="true" />
<security:custom-filter position="PRE_AUTH_FILTER"
ref="authorizationGlobalFilterBean" />
</security:http>
</beans:bean>
<!-- Login auth ends here -->
<!-- PreAuth starts here -->
<security:http use-expressions="true" auto-config="false"
entry-point-ref="http403EntryPoint" pattern="/framework/**"
create-session="stateless">
<security:csrf disabled="true" />
<security:custom-filter position="PRE_AUTH_FILTER"
ref="siteminderFilter" />
</security:http>
<beans:bean id="authorizationGlobalFilterBean"
class="com.xplanr.framework.security.AuthorizationGlobalFilter">
</beans:bean>
<beans:bean id="siteminderFilter"
class="org.springframework.security.web.authentication.preauth.RequestHeader AuthenticationFilter">
<beans:property name="principalRequestHeader" value="sessionId" />
<beans:property name="authenticationManager"
ref="authenticationManager" />
</beans:bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider
ref="preauthAuthProvider" />
</security:authentication-manager>
<beans:bean id="preauthAuthProvider"
class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<beans:property name="preAuthenticatedUserDetailsService">
<beans:bean id="userDetailsServiceWrapper"
class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<beans:property name="userDetailsService"
ref="customUserDetailsService" />
</beans:bean>
</beans:property>
</beans:bean>
<beans:bean id="customUserDetailsService"
class="com.practice.framework.security.CustomUserDetailsService">
</beans:bean>
<beans:bean id="http403EntryPoint"
class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint">
</beans:bean>
<!--PreAuth ends here -->
</beans:beans>