Reputation:
I use the following in the pom.xml
which is actually securing the root route,
I see the authentication process starting in the browser for few seconds
<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>
Now I've specific routes that I need to secure when user chooses them...
@Path("/run")
public class Service {
...
@GET
@Path("connect/{param}")
public Response connectToHost(@PathParam("param") String host) {
How I should do it ? via configuration on the pom as above or via code for each route ?
Upvotes: 10
Views: 1359
Reputation: 845
**
** 1. Using Spring way,you need to declare Filter Mapping ->
<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. Then you have to create a spring-security.xml . You can declare your method which you want to prevent to access.So you can ask for some authorization checked before accessing that methods.
<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>
Upvotes: 2
Reputation: 2858
There are some confusing points in your questions, but I'll try to cover whatever I can.
ONE. filter settings - As per your question you made filter settings in pom.xml
. But actually filter settings are always made in web.xml
file. If you have mistakenly named pom.xml then ignore but if not then move the filter settings to web.xml.
TWO. In your question tags you have mentioned that your query is related to spring-boot, spring-security. But the code sample that you have attached suggests you are perhaps using jersey for creating rest apis and not using spring, spring-security. You are actually trying to use csrf protection at lower level at tomcat server level. Thats fine.
THREE. CSRF protection can be leveraged with spring security as well as tomcat apis.
FOUR. If you want to understand how spring security provides csrf protection to rest endpoints you will have to provide following configuration in your code.
@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
}
This will provide csrf protection to all POST, PUT, PATCH, DELETE requests to your application. Refer - https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html for more details.
FIVE. Now for your actual question of how to provide csrf protection to multiple routes to your jersey based rest endpoints... You can provide multiple url patterns like following.
<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>
Refer - https://tomcat.apache.org/tomcat-8.0-doc/config/filter.html#CSRF_Prevention_Filter_for_REST_APIs for more details on RestCsrfPreventionFilter
.
Upvotes: 6
Reputation: 463
You will need a class that extends 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
}
}
Upvotes: 1
Reputation: 754
First of all Filters should be added to web.xml file. It should not be added to pom.xml file. pom.xml is only the manifest for building your project.
Since it is best to secure only certain urls for your intended CSRF Prevention filter, use specific urls in filter mapping.
Example is provided for the mentioned /run
path.
<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>
Please refer this oracle documentation to understand the usage of web.xml elements.
To understand further regarding filtering requests and responses, refer this oracle tutorial.
Refer this practical tutorial on understand hoe to configure the filters in both xml and annotation methods. Note that you do not have to do the configurations in both ways. It can be done in either xml based or annotation based way as you're comfortable.
Upvotes: 1