I am using BlazeDS and Spring Security and have set up my application using a Spring Security filter chain and Dispatcher Servlet in my web.xml and in my application-context.xml I have set up the following...
<s:http
auto-config="true"
access-decision-manager-ref="accessDecisionManager"/>
<s:authentication-manager>
<s:authentication-provider
user-service-ref="userService"/>
</s:authentication-manager>
<f:message-broker>
<f:secured/>
</f:message-broker>
<s:global-method-security
access-decision-manager-ref="accessDecisionManager">
<s:protect-pointcut
expression="execution(* com.my.app.Server.*(..))"
access="ROLE_USER"/>
</s:global-method-security>
This generally works. The Spring message broker correctly allows me to access my java Server class and the 'secured' tag works and allows me to log into the channel set using my custom authentication manager (via userService). I can call remote methods on the Server class no problem.
However, I cannot get the global method security to work at all. I cannot get Spring to invoke my accessDecisionManager, or even to deny access to methods on the Server class, no matter which access role I use. Does anybody know how I can get this to work?
Incidentally, my Server class is not a Spring bean or anything like that, it is just a standard Java class as would be used in standard Flex remoting. Would this make a difference?
I'm using Spring Security 3 and Flex 4.5
Point cuts and aspects only works for Spring beans, if it is plain java object spring cannot intercept any method calls as it is not proxied. Please create a spring bean for your server class and it should be working fine.
Once you created the spring bean you can expose the bean through blaze DS using flex:remoting-destination
Related
I've got a Java EE application which uses Spring Security for authentication (configured with Java config). The same application contains a websocket server implemented with javax.websocket package.
My question is how to turn off Spring Security authentication for any incoming websocket connections without turning off HTTP authentication?
You can have all requests matching a particular pattern bypass the security filter. For example, if your WS endpoint is
/websocket you can add this to your configuration:
<http pattern="/websocket/**" security="none" />
I don't like to configure Spring programmatically so I don't know how this is done with Java code, but after a 10,000 feet look at the
classes I think it's maybe done with a WebSecurity + WebSecurityConfigurerAdapter setup.
I have a Spring MVC application secured with Spring Security. The majority of the application uses simple HTTP to save resources, but a small part processes more confidential information and requires an HTTPS channel.
Extract from the security-config.xml :
<sec:http authentication-manager-ref="authenticationManager" ... >
...
<sec:intercept-url pattern="/sec/**" requires-channel="https"/>
<sec:intercept-url pattern="/**" requires-channel="http"/>
</sec:http>
All worked fine until we decided to migrate it to the main server, where the application servers run behind reverse proxies. And as now HTTPS is processed by the reverse proxies the application server only sees HTTP requests, and disallows access to the /sec/** hierarchy.
After some research, I found that the proxies add a X-Forwarded-Proto: https header (*), but in Spring Security HttpServletRequest.isSecure() is used to determine the channel security offered (extract from SecureChannelProcessor javadoc).
How can I tell Spring Security that a X-Forwarded-Proto: https header is enough for a secure request?
I know I could report that part on proxies configuration, but the proxies administrator really does not like that solution, because there are many application behind the proxies and the configuration could grow to a non manageable state.
I an currently using Spring Security 3.2 with XML config, but I'm ready to accept answers based on Java config and/or more recent version.
(*) Of course, the proxies remove the header if it was present in incoming request, so the application can be confident in it.
Kind of a followup to NeilMcGuigan's answer that showed that the solution was servlet container side.
Tomcat is even better. There is a valve dedicated to masking the side effects of a reverse proxy. Extract from Tomcat documentation for Remote IP Valve:
Another feature of this valve is to replace the apparent scheme (http/https), server port and request.secure with the scheme presented by a proxy or a load balancer via a request header (e.g. "X-Forwarded-Proto").
Example of the valve configuration :
<Valve className="org.apache.catalina.valves.RemoteIpValve"
internalProxies="192\.168\.0\.10|192\.168\.0\.11"
remoteIpHeader="x-forwarded-for" proxiesHeader="x-forwarded-by"
protocolHeader="x-forwarded-proto" />
That way with no other configuration of the application itself, the call to Request.isSecure() will return true if the request contains a header field of X-Forwarded-Proto=https.
I had thought of two other possibilities, but definitively prefere that one :
use a filter active before Spring Security ChannelProcessingFilter to wrap the request with a HttpServletRequestWrapper overriding isSecure() to process a X-Forwarded-Proto header - need writing and testing the filter and the wrapper
use a Spring BeanPostProcessor to look for a ChannelProcessingFilter and manually inject a ChannelDecisionManager able to consider the X-Forwarded-Proto header - really too low level
Spring Boot makes it dead simple (at least with embedded Tomcat).
1. Add the following lines to your application.properties:
server.forward-headers-strategy=native
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto
2. Do the following trick with your HttpSecurity configuration.
// final HttpSecurity http = ...
// Probably it will be in your `WebSecurityConfigurerAdapter.configure()`
http.requiresChannel()
.anyRequest().requiresSecure()
Source is Spring Boot reference guide
84.3 Enable HTTPS When Running behind a Proxy Server
Please also check the answer below for a specifics related to Spring Boot 2.2
If your site is HTTPS and you're running Apache Tomcat behind another system that's handling TLS termination, you can tell Tomcat to "pretend" that it's handling the TLS termination.
This makes request.isSecure() return true;
To do so, you need to add secure="true" to your Connector config in server.xml.
https://tomcat.apache.org/tomcat-7.0-doc/config/http.html
See also the scheme attribute.
I am using Spring4 with Spring Security 3.2.4.
I have some http configurations in my security configuration in order to host form based authentication and REST services (with authentication) together.
For the pages and REST services which require app-authentication everything works fine with my current configuration but for the pages which does not require authentication, such as login and register, the anonymous authentication is not initialised somehow. Speaking in Java:
SecurityContextHolder.getContext().getAuthentication() returns null.
I expect that anonymous authentication is initialised as the documentation (http://docs.spring.io/spring-security/site/docs/3.2.4.RELEASE/reference/htmlsingle/#introduction) refers:
Anonymous authentication support is provided automatically when using the HTTP configuration Spring Security 3.0 and can be customized (or disabled) using the element. You don’t need to configure the beans described here unless you are using traditional bean configuration.
Does anyone have an idea why does it not happen although the documentation refers? (Beside the fact, that the documentation for 3.2.4 refers to 3.0 version and some of the given configuration suggestions refer deprecated implementation)
I tried using Basic Authentication by changing the server.xml config of Tomcat 6.0 but it did not worked: BASIC authentication in jersey JAX-RS service and Tomcat 6.0 getting failed
Hence I am opting a way where no server specific config is needed and I can add up the roles directly in my code (either client or server; not sure about theavailable options).
Please provide me some ideas about the possible options for setting the user roles so that I can authenticate my Web Service methods using the #RolesAllowed annotation.
You need to go back and figure out why your security constraints weren't working. Maybe start with the default file realm before moving on to JDBC realms. #RolesAllowed in an annotation that triggers behavior in the container.
If you really want to do it yourself (a bad idea) they you'd probably start by creating a custom servlet filter that implemented the entire basic http challenge mechanism. Next you'd have to replace the SecurityContext provider in Jersey.
They "thing" that enables #RolesAllowed in jersey is this: http://java.net/projects/jersey/sources/svn/content/trunk/jersey/jersey-server/src/main/java/com/sun/jersey/api/container/filter/RolesAllowedResourceFilterFactory.java Which, by the way, don't forget to add as an init-param to your jersey servlet. The RolesAllowedResourceFilterFactory gets its security info from an injected SecurityContext which I'm sure at some point just delegates off to the Servlet API for credential info.
So basically if you don't want to take the time to get security constraints working you are going to end up replacing most of the chain...like I said, a bad idea.
The features on application servers are there to keep you from having to spend time creating infrastructure code, if you write your own infrastructure code you're going to have a bad time.
I would like to set up a webservice endpoint using Spring's SimpleJaxWsServiceExporter for ease of use, but I also need to protect the webservice using a subclass of Jespa's HttpSecurityFilter
I suspect this does not work out of the box as SimpleJaxWsServiceExporter is using a separate HTTP server to the host webapp containing the filter - how should I accomplish this?
I have a class annotated with #WebService and in my applicationContext.xml
<bean class="org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter"
p:baseAddress="http://localhost:9581/"/>
I found a couple of alternative ways to host the endpoint within the same HTTP server (behind the filter)
Either using JAX-WS WSSpringServlet and registering my #WebService beans via the wss:binding xml tag under the http://jax-ws.dev.java.net/spring/servlet namespace, or my preferred option, as JAX-WS Spring integration has Maven dependencies on Spring 2, using CXF.