I'm using JBoss 4.2 with Java Seam and in my application there is an login-form implemented.
Now if I submit the form in the GUI the Parameters will be sent via HTTP-POST, but if I try to send the Data via HTTP-GET it will be accepted too.
That should be prevented, but I didn't find out how.
Could I set the Method in the pages.xml or do I need to find out programmatically if the Request is Post or Get.
Are there other ways to do that or how should I do it?
Thanks!
Add the followin Statement in the web.xml:
<security-constraint>
<web-resource-collection>
<web-resource-name>Post Pages</web-resource-name>
<description />
<url-pattern>/*.xhtml</url-pattern>
<http-method>POST</http-method>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
This will only allow POST Request in the defined url.patterns
Related
We are trying to add an API to WSO2AM which has the problem, that we need to add (invisible for users) an Authorization Key.
We are able to add it using Mediator with that configuration:
<sequence xmlns="http://ws.apache.org/ns/synapse" name="Add_Fahrplan_AuthKey">
<property name="REST_URL_POSTFIX"
expression="fn:concat(get-property('axis2','REST_URL_POSTFIX'),
'&authKey=**HERE_IS_THE_SECRET**')"
scope="axis2"
type="STRING"/>
</sequence>
We have 4 get methods
/location
/departure
/arrival
/journeyDetails <-- needs an different AuthKey
But for the fourth get method journeyDetails we need to add the AuthKey in a different way with different characters.
Is it possible to do that in a Mediator configuration? And in case of yes, how can we do it?
Please keep in mind that we are not very familiar with synapse configuration syntax. We tried
value="/location"
but it resulted in an AM-error while invoking the API and we tried
<filter> with <then> and <else>
which resulted again in an AM error.
Thanks for any help
I am migrating a Spring MVC app from JBoss 7.1.1 to Wildfly 8.1, which has required (encouraged?) me to use the new "undertow" module instead of the older "web" module. Things are coming right along, except that now requests to "/", which used to invoke the controller method annotated with #RequestMapping("/"), no longer reach the controller method. Instead, it appears that such requests are being immediately rewritten (not redirected) to "/index.html". Since I don't have (and have never needed) such a file, all requests for "/" are now generating 404 errors.
Interestingly, all of the other #RequestMapping-annotated controller methods continue to function normally.
Here is the relevant snippet from my standalone.xml file.
<subsystem xmlns="urn:jboss:domain:undertow:1.1">
<buffer-cache name="default"/>
<server name="default-server">
<http-listener name="default" socket-binding="http" max-post-size="4194304"/>
<host name="default-host" alias="localhost">
</host>
</server>
<servlet-container name="default">
<jsp-config development="true"/>
</servlet-container>
</subsystem>
I suspect that when the subsystem definition for Wildfly's undertow module does not explicitly declare a handler, Wildfly defaults to a file handler, which may be responsible for the the URL rewrites -- but I am not certain of this.
Documentation about handlers in the Undertow project, upon which Wildfly's undertow module is based, indicate support for a "Redirect" handler. I have considered using this to work around the unexpected "/" rewriting, but it is not clear to me whether Wildfly's undertow module supports this, and if it does, how to configure it in standalone.xml. Even if I was able, however, I think it would feel like a hack, and I'd prefer to get to the root of the problem (no pun intended) instead.
There are many S.O. questions describing disappointing RequestMapping("/") behavior, and many answers suggesting using other paths (such as "", "/index", etc.), but don't forget: the existing (unchanged) code works just fine in JBoss 7.1.1. (Also, none of those questions mention Wildfly, which is probably the key consideration for this question.) Nevertheless, I experimented with the various suggestions and got nowhere. It simply seems like the URL is being rewritten before it ever reaches the dispatcher servlet.
So, in summary, my question is:
How can I get a Spring MVC app with RequestMapping("/") to run in Wildfly 8.1 as it does in JBoss 7.1.1?
In Wildfly, if your web.xml doesn't have a <welcome-file-list> element, then one is provided for you, as if you had configured it this way:
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
With this default configuration, when Wildfly receives a request for for "/", the path is automatically rewritten as index.html. This path will then not match the controller method annotated with RequestMapping("/").
JBoss 7 apparently behaves differently, perhaps only referring to the welcome file list after failing to find a matching servlet.
Whatever the cause, you can work around the new behavior by explicitly defining your own welcome file list and including, as the last <welcome-file> element, an empty welcome file:
<welcome-file></welcome-file>
This allows Wildfly to rewrite "/" as "/", in turn allowing the request for "/" to be processed by the servlet dispatcher (provided that its url-pattern is set to /). The servlet dispatcher will then invoke the controller method annotated with RequestMapping("/").
I am using Spring Security 3.2.3 in my Spring MVC application and getting some unexpected behavior.
According to the documentation here, it should be possible to use ${_csrf.token} in the meta tags of my html:
<meta name="_csrf" content="${_csrf.token}" />
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" content="${_csrf.headerName}" />
From where I extract the value of "content" using JQuery and place it into the Request Header using AJAX.
For some reason though, Spring Security doesn't "convert" this into an actual token, it just gets sent into the header as a literal string "${_csrf.token}".
Trying the alternate route of using ${_csrf.token} in a hidden input according to the documentation, I then tried to check what the token evaluates to by checking the input's value, but it's still just plain text "${_csrf.token}".
Since it seems that Spring Security isn't in effect, am I missing some kind of configuration? I am currently using a barebones Spring Security Java configuration (as opposed to xml) as shown here:
import org.springframework.context.annotation.*;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.*;
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf();
}
}
I know configure is getting called since I put a debug statement in it, so I assume that CSRF protection is indeed enabled since it should be by default.
I realize that the syntax "${}" is JSP Expression Language, and I am currently successfully using it to evaluate the context into an object with Thymeleaf, for example:
th:object="${context}"
So I tried adding "th:" in front of the meta tag's "content" like so:
<meta name="_csrf" th:content="${_csrf.token}"/>
But it results in an exception that this cannot be evaluated:
Exception evaluating SpringEL expression: "_csrf.token"
I think the key here may be figuring out how to get the expression to evaluate properly in my view.
I finally solved this problem, but it basically required rewriting Spring Security. Here it is in all its glory.
First, I followed the suggestions in Eyal Lupu's great blog post here, but I had to tweak it to my situation because of my AJAX requirement.
As for the Thymeleaf situation, the key tidbit is hidden away in the archives of the Thymeleaf forums - Infamous Issue 7.
https://github.com/thymeleaf/thymeleaf-spring/issues/7#issuecomment-27643488
The last comment by the creator of Thymeleaf himself says that:
th:action ... detects when this attribute is being applied on a
tag --which should be the only place, anyway--, and in such case
calls RequestDataValueProcessor.getExtraHiddenFields(... ) and adds the
returned hidden fields just before the closing tag.
That was the key phrase I needed to get the token to work. Unfortunately it's completely not obvious why th:action would also kick off getExtraHiddenFields, but at any rate it does, and that's what matters.
So for anyone struggling with Thymeleaf + Spring Security CSRF + AJAX POST, here are my steps (this is paring it down quite a bit but these are the high-level concepts to solve it):
Implement the Spring interface RequestDataValueProcessor and register it in Spring Security's XML config so you can override the method getExtraHiddenFields, which allows you to insert a hidden input field into the HTML (with the token of course). The token itself is generated with a Java.Util UUID.
With JQuery, read the value from that hidden field and set the Request Header's "X-CSRF-Token" attribute so that it gets sent over HTTP. It's not possible to simply leave the token in the hidden input field because we are not doing a form Submit, instead we use AJAX POST to call methods on the server side.
Extend Spring's HandlerInterceptorAdapter and register it as an interceptor so that every time a POST method is done, the "preHandle" method on the server side is called so it can compare the request token (extracted from the HTTP header in the previous step) to the session's token (should be the same!). After it does this check, it can either allow the request to go through or return an error.
I started with the same source article as you, I think, and the same "you should be able to" add answers as you did. I fought it a different way. I made Thymeleaf give me the answer I wanted.
<meta name="_csrf" th:content="${_csrf.token}"/>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" th:content="${_csrf.headerName}"/>
Thymeleaf put the attribute "content" with the requested Spring EL contents. I then used the provided JavaScript/JQuery to extract the info from the meta tags straight into the CSRF header.
Before adding the thymeleaf-extras-springsecurity namespace and its dependency into my project, I had similar problems. I never did get the meta tags to work, even with thymeleaf-extras-springsecurity. But I did successfully retrieve Spring Security's csrf token using the hidden input. I have instructions below that work for me:
In the html tag, add:
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"
In your pom.xml (if you're using Maven) you'll need to add the dependency: thymeleaf-extras-springsecurity4.
Then add the hidden input inside your page's body to retrieve the csrf token.
<input type="hidden" id= "csrf-token" th:name="${_csrf.parameterName}" th:content="${_csrf.token}" />
and then use that within your javascript/jquery as follows:
function f1() {
var token1 = $('input#csrf-token').attr("content");
...
$.ajax({
...
type: "POST",
beforeSend: function (request)
{
request.setRequestHeader("X-CSRF-TOKEN", token1);
},
...
This all assumes that you have spring security enabled, and that you have NOT turned off csrf protection.
You have incorrect configuration for springSecurityFilterChain in your web.xml. Correct definition is:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
Spring Security uses set of servlet filters to provide the functionality it is offering (including CSRF protection). These filters are defined as Spring beans (i.e. they are instantiated and managed by Spring application context). DelegatingFilterProxy is a special type of servlet filter, which finds root application context on the registered servlet context and delegates every call to the same named bean.
Your issue is a different one, just stumbled across this one as well and it took me several hours to figure out the cause. The cause for the issue described by you is that you did not enable csrf support within your spring-security.xml
This little snippet needs to go into your security-config.xml:
<!-- Static resources such as CSS and JS files are ignored by Spring Security -->
<security:http pattern="/static/**" security="none" />
<security:http use-expressions="true">
<!-- Enables Spring Security CSRF protection -->
<security:csrf/>
<!-- Configures the form login -->
<security:form-login
login-page="/login"
login-processing-url="/login/authenticate"
authentication-failure-url="/login?error=bad_credentials"
username-parameter="username"
password-parameter="password"/>
<!-- Configures the logout function -->
<security:logout
logout-url="/logout"
logout-success-url="/login"
delete-cookies="JESSIONID"/>
<!-- Anyone can access these urls -->
<security:intercept-url pattern="/auth/**" access="permitAll"/>
<security:intercept-url pattern="/login" access="permitAll"/>
<security:intercept-url pattern="/signin/**" access="permitAll"/>
<security:intercept-url pattern="/signup/**" access="permitAll"/>
<security:intercept-url pattern="/user/register/**" access="permitAll"/>
<!-- The rest of our application is protected. -->
<security:intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
<!-- Adds social authentication filter to the Spring Security filter chain. -->
<security:custom-filter ref="socialAuthenticationFilter" before="PRE_AUTH_FILTER" />
</security:http>
....
...
..
.
Save time by configuring this correctly...
Cheerio,
Flo!
In case you don't need to use Thymeleaf, I'd suggest the following:
Add this to the top of your page:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
Add this to your login form:
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
Add these dependencies to your pom.xml:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
After struggling a lot, that worked for me.
I'm making a Spring MVC web-app with some RESTfull resources as an API.
I need the RESTfull part to have some custom filters as I do not want any redirection and I want any exception to be translated with the corresponding HTTP error code and a basic JSON description.
On the other hand, the rest of the website have to be more common and redirect people when they are not logged in etc.
One more thing, I wish to use the #Secured annotations and a post-authentication in some case.
How do I define the multiple http namespaces correctly (on Spring 3.1)?
Here is my erroneous configuration:
<global-method-security secured-annotations="enabled" />
<http pattern="/rest/**" authentication-manager-ref="authenticationManager" entry-point-ref="restAuthenticationEntryPoint">
<form-login login-page="/rest/login" login-processing-url="/rest/postlogin"
authentication-success-handler-ref="restAuthenticationSuccessHandler"
authentication-failure-handler-ref="restAuthenticationFailureHandler"
username-parameter="username" password-parameter="password" />
<logout logout-url="/rest/logout" invalidate-session="true" />
</http>
<http pattern="/**" authentication-manager-ref="authenticationManager">
<form-login login-page="/login" login-processing-url="/postlogin"
username-parameter="username" password-parameter="password" />
<logout />
</http>
The funny part is that this configuration works partially as I can login with /rest/login and I get the response from my custom success handler. I can also login from /login and I get the proper redirection to /. The logout are working both fine too.
Next, all the controllers beans have #Secured("ROLE_USER") in the secured methods. But all the secured methods don't ever get secured. Why is that so?
#Secured({"ROLE_USER"})
#RequestMapping(method = RequestMethod.GET, headers = { "Range" })
public #ResponseBody
HttpEntity<List<T>> list(#RequestHeader("Range") String range) {
I've read documentations everywhere and I'm more confused than ever.
Why are my methods not being secured?
Must the http namespace define an access so that the #Secured annotations work?
Are the http namespace overwriting my #Secured annotations? If it's so, how can I define multiple "login pages" with custom filters and being able to use annotations?
Here are some facts:
* I'm using Spring and SpringSecurity 3.1
* I have a custom AuthenticationManager to retrieve user details from hibernate daos.
* Some controllers are extending an abstract class where the #Secured annotations lies. But it still doesn't work for a simple controller.
* My controllers are discovered with a context:component-scan and a base-package.
* The security works fine with one http namespace.
please help, i'm getting mad with this!
Check out this answer about making sure the web context is visible to the global-method-security declaration and possibly using class proxying.
To answer your other questions, no the http namespace shouldn't affect the use of #Secured annotations, other than that the user is authenticated by the web part of the application and that information will be used by the method security interceptor when making an access decision. Unless you override it (using access-decision-manager-ref), method security will use a standard AccessDecisionManager which grants or denies access based on the roles a user has.
I need to disable PUT, DELETE & TRACE HTTP requests on my Application Server, Apache Tomcat 6.0.
All other sources, i have searched till now, have directed me towards the limit parameter in httpd.conf, Hence I'd put it before-hand that I am not using Apache Web Server, and requests are directly being handled by Tomcat, and so there is no httpd.conf in picture.
Please suggest how should I do it on Tomcat?
Inside your WEBINF, add you can add a security constraint:
<security-constraint>
<web-resource-collection>
<web-resource-name>Forbidden</web-resource-name>
<url-pattern>/blah/*</url-pattern>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
<http-method>TRACE</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>empty_role</role-name>
</auth-constraint>
</security-constraint>
Alternatively, you can do these two things:
In server.xml, edit the <connector> element, add an attribute: allowTrace="false". Then edit the DefaultServlet: $CATALINA_HOME/conf/web.xml
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>
org.apache.catalina.servlets.DefaultServlet
</servlet-class>
<!-- blah blah blah -->
<init-param>
<param-name>readonly</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
The answer lies in the servlet specification. In looking at the API for the servlet: http://java.sun.com/products/servlet/2.5/docs/servlet-2_5-mr2/javax/servlet/http/HttpServlet.html you'll see that different methods handle different kind of HTTP requests. Also, there is a great feature called filters that can be used to wrap some code around servlets and filters.
So the solutions are:
Modify the servlet to only support do and get; or
Create a filter to clear those other kind of requests.