I was reading about how Authentication works in Spring and found that there are two filters taking care of the Authentication.
AuthenticationProcessingFilter BasicProcessingFilter
So I set breakpoints within BasicProcessingFilter::doFilterHttp and AuthenticationProcessingFilter::attemptAuthentication and AuthenticationProcessingFilterEntryPoint::commence and the program didn't stop at any of them.
Does it mean that my web-application currently doesn't have an authentication mechanism at all?
Maybe it has something to do with that I defined a custom resource filter as follows:
<beans:bean id="secureResourceFilter"
class="my.custom.class.CustomSecureResourceFilter">
<beans:property name="jdbcSecuredUrlRoleDao" ref="jdbcSecuredUrlRoleDao" />
</beans:bean>
In my Spring-security configuration I didn't define
AuthenticationProcessingFilter and BasicProcessingFilter directly. I just specify
<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>
in web.xml.
Expect if you use Spring boot, you have to at least configure your Spring context. Either you use Java config, or XML files.
For Java config: http://docs.spring.io/autorepo/docs/spring-security/3.2.x/guides/helloworld.html
For XML files: http://www.springbyexample.org/examples/simple-spring-security-webapp-spring-config.html
Note that you can see which are the filters used in your application by putting a break point in the delegating filter proxy and see the filter chain. Sub-filters are applied sequentially.
Related
If I use CAS server and my application in the same machine, logout is working fine for me. But if CAS server is deployed on the different machine and my application is deployed on the different machine, then cas logout is not working.
I am calling the following url from my application:
CAS Server URL: https://108.51.62.36:9443/cas/logout
And I have got the following entries in web.xml of my application:
<filter>
<filter-name>CAS Single Sign Out Filter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Included to support Single Logout. Note that the SingleSignOutFilter
is included in the springSecurityFilterChain. However, it could also be placed
as the first filter-mapping in the web.xml -->
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
Whe you use CAS, this create a secure cookie domain. You can see the value and modify in WEB-INF/spring-configuration:
ticketGrantingTicketCookieGenerator.xml
warnCookieGenerator.xml
So, I suggest don't use Ip. Use another like https://my.domaing.com:9443/cas/logout
I want to use two different Spring web contexts, each have own contextConfig, spring servlet and filter, that should be mapped to different urls. I have a
Standard Grails project, mapped to '/'
And an existing Spring webapp, that I want to map to /extra/
I know that I can deploy both into one Tomcat, but I'm looking for a way of making one app (one war, etc), because It can simplify our deployment and development process.
This applications don't need to share beans or anything, should be completely separate. Both have DispatcherServlet and DispatcherFilter (and both are using Spring Security, but different configuration)
How I can configure web.xml for such webapp?
I've tried to add new filter:
<filter>
<filter-name>extraSpringSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>contextAttribute</param-name>
<param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.extraSpring</param-value>
</init-param>
<init-param>
<param-name>targetBeanName</param-name>
<param-value>extraSecurityFilterBean</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>extraSpringSecurityFilterChain</filter-name>
<url-pattern>/extra/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
and spring dispatcher servlet:
<servlet>
<servlet-name>extraSpring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>springConfigLocation</param-name>
<param-value>classpath:extra-spring-web.xml</param-value>
</init-param>
</servlet>
Where:
two context xml in classpath (inside exra library jar):
extra-spring-web.xml
extra-spring-security.xml (!!! how I should configure it?)
extra-spring-security.xml
is pretty standard Spring Security config
have configured bean extraSecurityFilterBean
have dependecy to beans from -web context (but it's not required to be)
It's semi-working now:
as I see from logs, extraSpring servlet successfully load beans from extra-spring-web.xml
but after accessing url /extra/ I got NoSuchBeanDefinitionException: No bean named 'extraSecurityFilterBean' is defined.
So, the question, how I can define context for DelegatingFilterProxy? I even tried to add this files into main context (contextConfigLocation param), it's not what i'm looking for, but it didn't work.
I've taken a look into DelegatingFilterProxy sources, but it's not clear for me how it loads the context.
As per my comment on the question, if the security filter chain is defined in extra-spring-security.xml then you need to ensure that that file is loaded by your extra DispatcherServlet in addition to extra-spring-web.xml either by <import>ing the -security file from the -web one or configuring it as:
<servlet>
<servlet-name>extraSpring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:extra-spring-web.xml
classpath:extra-spring-security.xml
</param-value>
</init-param>
</servlet>
You will also need to ensure that the security filter in the Grails application doesn't apply to /extra URIs, exactly how you do this depends on whether you're using annotations, database RequestMap entries etc.
If the modules are completely separate: the easiest way is to package them as two different webapp. Tens of different spring-based apps can run in one appserver -even on a modest developer machine- without issues.
A few questions
What does your Spring Security configuration look like?
I'm confused why the error states "No bean named 'apiservSecurityFilterChain' is defined" but the web.xml you have posted only references extraSpringSecurityFilterChain (the bean names should match or some important configuration is being left out).
Possible Answer
I'm guessing the problem is that the filter-name needs to match Spring Security's bean name (cannot know for sure without seeing the Spring Security configuration you are using). The default value used by the Spring Security namespace is springSecurityFilterChain, so try the following in the web.xml instead (notice extraSpringSecurityFilterChain changed to springSecurityFilterChain):
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>contextAttribute</param-name>
<param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.extraSpring</param-value>
</init-param>
<init-param>
<param-name>targetBeanName</param-name>
<param-value>extraSecurityFilterBean</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/extra/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
I'm trying to understand the reccommended way for defining Spring Security in Spring-MVC applications, where the bean definitions is split across multiple parent/child contexts.
For example, my current app's web.xml looks as follows, (which I understand to be fairly standard)
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml
/WEB-INF/securityContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<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>
<servlet>
<servlet-name>spring-mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
So, I have a standard ContextLoaderListener defined at /, which loads my global configs - applicationContext.xml and securityContext.xml.
I also define the spring mvc DispatcherServlet at /app/, which loads it's own beans from spring-mvc-servlet.xml.
As I understand it, config defined in spring-mvc-servlet.xml is not visible to config defined in either of the top-level context files.
Where then is the best place to define app-level security concepts? For example, I'd like to add the following filter.
<security:http pattern="/oauth/token" create-session="stateless" entry-point-ref="oauthAuthenticationEntryPoint">
<security:custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
</security:http>
This is so that requests to /app/oauth/token pass through this filter, and get basic authentication processed.
Because this pertains directly to a concern of the Spring-MVC app, I initially defined it in spring-mvc-context.xml (which is why the app is excluded from the url).
However, this means it's not visible to the security config defined in securityContext.xml, so it's ignored.
So, I move it up to securityContext.xml, but in doing so, also must move all the dependencies.
I quickly end up moving everything up to applicationContext.xml, which leaves the spring-mvc-context.xml almost empty.
Is this common? What is the reccomended split between what is defined in top-level contexts, and what gets defined in child contexts?
Given that spring-mvc defines a series of controllers, which I want to mark as #Secured, how will these be processed if the controller is not visible to the security context?
Do I need to move my <mvc:annotation-driven /> from the servlet.xml to the global applicationContext.xml?
Do I need additional configuration within the spring-mvc-servlet.xml to tell it to participate in Spring security?
I've read the documentation on Spring-MVC, but there's very few specifics on how to configure this.
Additionally, the Spring OAuth examples seem to define everything within a single config file, which doesn't seem very real-world, and seems to contradict other examples I've read.
First: the beans defined within applicationContext.xml (ContextLoaderListener) can not access the one defined in spring-mvc-servlet.xml (DispatcherServlet) but not the other way around.
You asked:
Given that spring-mvc defines a series of controllers, which I want to mark as #Secured, how will these be processed if the controller is not visible to the security context?
So this works without problems, because the controllers must be defined in the spring-mvc-servlet.xml, so they "see" the Spring Security stuff defined in applicationContext.xml
Do I need to move my from the servlet.xml to the global applicationContext.xml?
No
Do I need additional configuration within the spring-mvc-servlet.xml to tell it to participate in Spring security?
No
... which leaves the spring-mvc-context.xml almost empty. Is this common?
The spring-mvc-context.xml should contain every thing that is related to Web Stuff (except secrutiy). So the common parts of the spring-mvc-context.xml are component scan for #Controller, some Interceptors (mvc:interceptors), mvc:resources, mvc:default-servlet-handler, mvc:view-controller, ReloadableResourceBundleMessageSource, CookieLocaleResolver, .SimpleMappingExceptionResolver...
BTW: If you use component scan, then you need two of them, one at applicationContext.xml to scan for #Service #Repository and #Component (But not #Controller) and a second in spring-mvc-context.xml that only scan for #Controller!
#See also this question: ContextLoaderListener or not? It discuss the theme from an other point of view.
i want to create url pattern that lead to filter in jsf2.
I tried this code
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>www.mysite.com</url-pattern>
</filter-mapping>
but i don't get to my filter.
can you help?
thanks
You are expecting to map the URL path, i.e. the part of URL that follows host and your web application name.
This is how full URL looks like:
http://www.mysite.com:8080/myapp/path1/path2/path3
where:
8080 is a port - optional - default 80
myapp - the context path of your web application. It is empty if your application is default web application on your app server.
path1/path2/path2 the path. This is what you are mapping using <filter-mapping> tag.
So, if for example you want to pass through your filter all requests to JSP pages say:
<url-pattern>*.jsp</url-pattern>
If your UI is under directory ui and you want to filter such requests say:
<url-pattern>/ui/*</url-pattern>
etc.
I hope I get this right:
You want to point an URL to your already created ServletFilter in your JSF 2.0 web application?
You have to register your filter in your webapps web.xml file and map it to your desired URL, e.g.
<!-- register your filter -->
<filter>
<filter-name>YourFilterName</filter-name>
<filter-class>com.your.filter.class</filter-class>
</filter>
<filter-mapping>
<filter-name>YourFilterName</filter-name>
<!-- Mapped to any URL -->
<url-pattern>/*</url-pattern>
</filter-mapping>
I have a single WAR that runs two servlets. One provides AMF remoting to Flex clients and other SOAP/HTTP to web service clients. I currently have Spring Security configured to authenticate the Flex clients using DaoAuthenticationProvider. However, I'd like to use a different authentication provide for the SOAP/HTTP. Possibly basic authentication or some other form.
Is it possible? or do I need two WARs?
I think you'll run into problems issues with instantiating two security filter chains. The problem is that the <http> element constructs a security filter chain with a hard-wired bean name ("springSecurityFilterChain"). If you have more than one active <http> element in the webapp's spring configs, this is likely to fail.
In theory you could work around this by not using the SpringSecurity namespace and configuring the filter chains "by hand" using plain Spring XML wiring of the SpringSecurity classes. In practice, configuring SpringSecurity that way is hard.
You might be able to start two separate securityChains, I don't know if you'll run into the issues Stephen outlines.
If you filter on two different url patterns corresponding to the two servlet url patterns you should be able to filter appropriately.
<filter>
<filter-name>flexSpringSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>flexSpringSecurityFilterChain</filter-name>
<url-pattern>/messagebroker/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>webSpringSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>webSpringSecurityFilterChain</filter-name>
<url-pattern>/web/*</url-pattern>
</filter-mapping>