I need to apply a Filter to facilitate setting the request.setCharacterEncoding("UTF-8") before first use of the request.getParameter(), otherwise my parameters are read as ISO_8859_1, setting it later does not work.
Unfortunately the 1st 'reading' filter is the Spring (4.3.13.RELEASE) Security 'CsrfFilter' & I'm unable to set a filter before it.
I'm using a minimal (no login required) spring security chain defined by:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/**" access="hasRole('ROLE_ANONYMOUS')" />
<access-denied-handler ref="myAccessDeniedHandler"/>
</http>
The whole application works except for reading characters outside of ISO_8859_1, I need full UTF-8 support. Ive confirmed the network traffic is UTF. But is popping out of the request.getParameter() calls as ISO_8859_1.
My solution was to add a Spring GenericFilterBean as below.
<http>
<custom-filter after="FIRST" ref="utf8Filter" />
</http>
<beans:bean id="utf8Filter" class="my.SetRequestEncodingFilter"/>
But this generates a run time startup exception.
Caused by: org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: No AuthenticationEntryPoint could be established. Please make sure you have a login mechanism configured through the namespace (such as form-login) or specify a custom AuthenticationEntryPoint with the 'entry-point-ref' attribute
I'm unable to find a security chain setup that allows inclusing of a filter (but needs to before the csf filter).
I'm thinking this is really a CsrfFilter bug'et, but it shouldnt be compromising subsequent getParameter() usage - but I dont really want to go there.
I tried the following - same result
<http auto-config="true" use-expressions="true" entry-point-ref="http403EntryPoint">
<intercept-url pattern="/**" access="hasRole('ROLE_ANONYMOUS')" />
<access-denied-handler ref="myFormAccessDeniedHandler"/>
</http>
<beans:bean id="http403EntryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint">
</beans:bean>
Any suggestions?
You can explicitly give default character encoding to be used by application by giving following argument at run time of application:
-Dfile.encoding=UTF-8
Since you're running Tomcat, you can just configure the input encoding in server.xml at the HTTP Connector like this:
<Connector port="8080" protocol="HTTP/1.1"
URIEncoding="UTF-8"
... >
Adding a WebApplicationInitializer seems to have resolved the issue without the need to worry about the servlet chain. I also didnt have to touch my web.xml.
public void onStartup(ServletContext servletContext) throws ServletException {
FilterRegistration.Dynamic encodingFilter = servletContext.addFilter("encoding-filter", new CharacterEncodingFilter());
encodingFilter.setInitParameter("encoding", "UTF-8");
encodingFilter.setInitParameter("forceEncoding", "true");
encodingFilter.addMappingForUrlPatterns(null, false, "/*");
}
Related
I am facing this problem...
I have the spring security filter
on my web.xml
<filter>
<filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
I am using spring security and I have this at my springSecurity-applicationContext.xml
<http
authentication-manager-ref="myAuthManager"
access-decision-manager-ref="accessDecisionManager"
entry-point-ref="authenticationEntryPoint"
create-session="ifRequired"
access-denied-page="/unauthorized">
<custom-filter ref="myPreAuthenticatedFilter" position="PRE_AUTH_FILTER"/>
<logout logout-success-url="/page/home"/>
<anonymous key="anonymous"/>
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/method/do" access="IS_AUTHENTICATED_ANONYMOUSLY()"/>
</http>
So, at myPreAuthenticationFilter I have a filter that extends of AbstractPreAuthenticatedProcessingFilter
I am trying to execute /method/do with a DELETE or a POST without success.
I am wondering what would be the best way to do it?
For some reason when I put a break point on myPreAuthenticationFilter at doFilter and make the request with DELETE nothing happens, only when I do the GET.
I want that endpoint to have no security.
I made this and worked
<http pattern="/method/do" security="none"/>
Not sure why this works and others dont or where I should look for.
Any idea?
The errors I get are Forbidden
If using spring-security 4 or above, csrf filter is enabled by default and it actually blocks any POST, PUT or DELETE requests which do not include de csrf token.
If you are not sending the csrf token in any of this kind of requests, you should make a test just disabling it configuring <csrf disabled="true"/> in your secured <http> section in your security xml, this way:
<http
authentication-manager-ref="myAuthManager"
access-decision-manager-ref="accessDecisionManager"
entry-point-ref="authenticationEntryPoint"
create-session="ifRequired"
access-denied-page="/unauthorized">
<custom-filter ref="myPreAuthenticatedFilter" position="PRE_AUTH_FILTER"/>
<logout logout-success-url="/page/home"/>
<anonymous key="anonymous"/>
<intercept-url pattern="/method/do" access="IS_AUTHENTICATED_ANONYMOUSLY()"/>
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<csrf disabled="true"/>
</http>
Edit
I have just realized that the order of the intercept-url should be just the opposite, starting from the most specific and ending with the most generic (I have already modified in the sample configuration I suggested)
In your case, it does not affect the behaviour given that both mappings have same access policy, but it should be this way.
Fairly new to Spring, so this may be basic.
We've recently transitioned from Spring 3 to 4 and running into some header issues with the new defaults tied to one of our partners business logic
We would like to keep the defaults everywhere except for a specific URL "/stg/strategem/strg/drammin.syg"
Currently we have:
<http use-expressions="true" entry-point-ref="web.AuthenticaionEntryPoint">
<intercept-url pattern="/admin/**" access = "hasAnyRole('GKR_ADMIN', 'GKR_ADMIN_ADV')"/>
<intercept-url pattern="/**" access = "hasAnyRole('GKR_USER')"/>
</http>
How can I configure this so that ["/stg/strategem/strg/drammin.syg"] is still secured but is the only place where the below header configuration applies?
<headers defaults-disabled="true">
<content-type-options />
<hsts include-subdomains="true" max-age-seconds="31536000"/>
<frame-options policy="SAMEORIGIN"/>
<xss-protection block="false"/>
</headers>
UPDATE 1: Was able to make the URL I need headerless more specific
UPDATE 2:
I just tried adding another http block, but I keep getting the Spring Error
A universal match pattern ('/**')
is defined before other patterns in the filter chain, causing them to be ignored.
Regardless of what order I put these blocks in, I've even tried removing the "/**" pattern, this error still comes up.
My attempt:
<http use-expressions="true" entry-point-ref="web.AuthenticaionEntryPoint">
<intercept-url pattern="/admin/**" access = "hasAnyRole('GKR_ADMIN', 'GKR_ADMIN_ADV')"/>
<intercept-url pattern="/**" access = "hasAnyRole('GKR_USER')"/>
</http>
<http use-expressions="true" entry-point-ref="web.AuthenticaionEntryPoint">
<headers defaults-disabled="true">
<content-type-options />
<hsts include-subdomains="true" max-age-seconds="31536000"/>
<frame-options policy="SAMEORIGIN"/>
<xss-protection block="false"/>
</headers>
<intercept-url pattern="/stg/strategem/strg/drammin.syg" access = "hasAnyRole('GKR_ADMIN', 'GKR_ADMIN_ADV', 'GKR_USER')"/>
</http>
UPDATE 3: Was able to find a solution, check it out in the Answers
You should be able to have multiple <http> blocks with different configuration for each. See Spring Security Reference - Multiple Security
Alright folks, I was able to get this working by using a separate HTTP block that had a pattern, but no intercept URL. Trying to make both have security configurations was what caused the issue.
Thanks Zilvinas for pointing me down the right path.
The first block applies header configs to just the specific url. Everything else gets Spring's defaults.
The second block applies security measures. (including to the specific url since I have a /** wildcard)
<http pattern="/stg/strategem/strg/drammin.syg">
<headers defaults-disabled="true">
<content-type-options />
<hsts include-subdomains="true" max-age-seconds="31536000"/>
<frame-options policy="SAMEORIGIN"/>
<xss-protection block="false"/>
</headers>
</http>
<http use-expressions="true" entry-point-ref="web.AuthenticaionEntryPoint">
<intercept-url pattern="/admin/**" access = "hasAnyRole('GKR_ADMIN', 'GKR_ADMIN_ADV')"/>
<intercept-url pattern="/**" access = "hasAnyRole('GKR_USER')"/>
</http>
I want to define access for some pages for user who has one of following roles (ROLE1 or ROLE2)
I'm trying to configure this in my spring security xml file as following:
<security:http entry-point-ref="restAuthenticationEntryPoint" access-decision-manager-ref="accessDecisionManager" xmlns="http://www.springframework.org/schema/security" use-expressions="true">
<!-- skipped configuration -->
<security:intercept-url pattern="/rest/api/myUrl*" access="hasRole('ROLE1') or hasRole('ROLE2')" />
<!-- skipped configuration -->
</security:http>
I've tried various ways like:
access="hasRole('ROLE1, ROLE2')"
access="hasRole('ROLE1', 'ROLE2')"
access="hasAnyRole('[ROLE1', 'ROLE2]')"
etc
but nothing seems to be working.
I'm keep getting exception
java.lang.IllegalArgumentException: Unsupported configuration attributes:
or
java.lang.IllegalArgumentException: Failed to parse expression 'hasAnyRole(['ROLE1', 'ROLE2'])'
how should it be configured?
Thanks
How try with , separate. See doc here and here.
<security:intercept-url pattern="/rest/api/myUrl*" access="ROLE1,ROLE2"/>
OR
hasAnyRole('ROLE1','ROLE2')
The problem was that I configured custom access-decision-manager-ref="accessDecisionManager"
and didn't pass one of the voters.
Solved by adding org.springframework.security.web.access.expression.WebExpressionVoter to accessDecisionManager bean.
I use Spring Security 3.1.4 to secure a Spring MVC 3.2.4 application deployed to Tomcat. I have the following Spring Security configuration:
<http auto-config="true" use-expressions="true">
<http-basic />
<logout ... />
<form-login ... />
<intercept-url pattern="/" access="isAnonymous() or hasRole('ROLE_USER')" />
<intercept-url pattern="/about" access="isAnonymous() or hasRole('ROLE_USER')" />
<intercept-url pattern="/login" access="isAnonymous() or hasRole('ROLE_USER')" />
<intercept-url pattern="/under-construction" access="isAnonymous() or hasRole('ROLE_USER')" />
<intercept-url pattern="/admin-task*" access="hasRole('ROLE_USER') and hasRole('ROLE_ADMINISTRATOR')" />
<intercept-url pattern="/resources/**" access="isAnonymous() or hasRole('ROLE_USER')" />
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
</http>
I noticed that URL patterns without a trailing slash (e.g., /about) do not match URLs with a trailing slash (e.g., /about/) and vice-versa. In other words, a URL with a slash and an identical URL without a slash are treated as two different URLs by Spring Security. The problem could be fixed by using two security rules:
<intercept-url pattern="/about" access="isAnonymous() or hasRole('ROLE_USER')" />
<intercept-url pattern="/about/" access="isAnonymous() or hasRole('ROLE_USER')" />
Is there a better solution?
I know that path-type="regex" allows to define URL patterns with regular expressions, but I would like to avoid any unnecessary complexity if it's possible.
Update
As Adam Gent noted, there is an additional problem that involves URLs with a dot: /about.foo and /about are treated as the same URL by Spring MVC. However, Spring Security treats them as two different URLs. So, one more security rule may be necessary:
<intercept-url pattern="/about.*" .../>
Spring Security 4.1+
Spring Security has now added a new matcher which is aware of your Spring MVC URL matching configuration. This tells Spring Security to match paths based on the same rules that Spring MVC uses, eliminating the possibility of a URL being valid, but unsecured.
First you need to replace any old matchers with the new MVC matcher. Spring Security is now in sync with however you have configured Spring MVC so you are free to add or remove any path matching configuration. I recommend sticking with the defaults where possible.
Java Config
If you were using antMatchers, you now should use mvcMatchers:
protected configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.mvcMatchers("/about").hasRole("USER");
}
XML Config
You need to add the attribute request-matcher to your http tag:
<http request-matcher="mvc">
<intercept-url pattern="/about" access="hasRole('USER')"/>
</http>
Full Reference
Please note that you also should no longer be prefixing your roles with "ROLE_" as Spring Security does this for you automatically.
Spring Security Before 4.1
I've not been able to find a way to handle both trailing slash and path suffixes in Spring Security. Obviously it is possible to write a regexp to handle these cases but this seems to make the security rules overly complex and prone to error. I want to be as confident as possible that I'm not exposing resources accidentally.
Therefore, my approach is to disable this behaviour in Spring by configuring the path matcher to be strict about both trailing slashes and suffixes.
Java Config
#Configuration
public class ServletConfig extends WebMvcConfigurerAdapter {
#Override
public void configurePathMatch(final PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(false);
configurer.setUseTrailingSlashMatch(false);
}
}
XML Config
<mvc:annotation-driven>
<mvc:path-matching suffix-pattern="false" trailing-slash="false" />
</mvc:annotation-driven>
<intercept-url pattern="/about/**"...
also works for me in Spring Security 3.1.4.
This secures /about, /about/, and /about/anything_else
I have used separate patterns for the same url. It is working for Spring security 3.1.7.RELEASE
<security:intercept-url pattern="/mypage./**" access="hasAnyRole('admin','reportviewer')"/>
<security:intercept-url pattern="/mypage" access="hasAnyRole('admin','reportviewer')"/>
<security:intercept-url pattern="/mypage/**" access="hasAnyRole('admin','reportviewer')"/>
what is the use of auto-config=true in spring security.
In which scenario we should use this.
what is the actual use of using auto-config=true ?
auto-config="true" is equivalent to:
<http>
<form-login />
<http-basic />
<logout />
</http>
so it gives you a very basic security configuration to boot.
Source: https://docs.spring.io/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#ns-auto-config
auto-config='true' means
for the intercept-url pattern the spring security provides the default login screen
This is one of the cases where we use auto-config = true:
<http auto-config='true'>
<intercept-url pattern="/**" access="ROLE_USER" />
</http>
This declaration means we want all URLs within our application to be secured, requiring the role ROLE_USER to access them. The element is the parent for all web-related namespace functionality. The element defines a pattern which is matched against the URLs of incoming requests using an ant path style syntax
Spring Security Reference:
"Use of this attribute is not recommended. Use explicit configuration elements instead to avoid confusion."
Source: https://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/html5/#nsa-http-attributes