Spring OAuth2 - ensure call to OAuth2ProtectedResourceFilter - servlets

How do I ensure that a call is being made to the OAuth2ProtectedResourceFilter when a request is sent with the oauth_token in the Authorization header?

It always passes through a filter if it is mapped properly

As mentioned, everything that you want to be secured, needs to go through a spring security filter:
Here a sample how a filter is mapped in front of the servlet (the spring MVC DispatcherServlet used for the authorization endpoints)
You could additionally map the same filter to any other servlet, for example to a jersey servlet you have configured.
In /WEB-INF/web.xml you need a filter-mapping like:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<servlet-name>spring-dispatcher</servlet-name>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<servlet>
<servlet-name>spring-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-mvc-dispatcher-servlet.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>spring-dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
To ensure every call to '/*', or whatever pattern, is filtered you use http from the spring security namespace and a filter called OAuth2AuthenticationProcessingFilter, that will watch out for the Bearer Authorization header, you will need something like this in your /WEB-INF/spring-mvc-dispatcher-servlet.xml or where ever your spring security is configured:
<http pattern="/**"
create-session="never"
authentication-manager-ref="userAuthenticationManager"
access-decision-manager-ref="accessDecisionManager"
use-expressions="true">
<anonymous enabled="false" />
<custom-filter ref="oAuth2AuthenticationFilter" position="PRE_AUTH_FILTER" />
<access-denied-handler ref="oAuthAccessDeniedHandler" />
<intercept-url pattern="/**" access="isAuthenticated()" />
</http>
<beans:bean id="oAuth2AuthenticationFilter" class="org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter">
<beans:property name="authenticationManager" ref="userAuthenticationManager"/>
<beans:property name="authenticationEntryPoint" ref="oAuthAuthenticationEntryPoint"/>
</beans:bean>

Related

spring mvc prefix text to all urls

I want to add the following prefix to all my urls
/login should now be /springmvc/login
What are the changes that needs to be made. I add the following but no use. I also tried a updating all of the following no luck, sometime the login page works but the result page which is mostly return "login" does not work
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
<property name="pathPrefix" value="springmvc" />
<property name="caseSensitive" value="false" />
</bean>
I have updated my controller as follows
#RequestMapping("/springmvc")
public class LoginController {
my web.xml is as follows, I havn't updated those
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
my spring security related code is as follows
<http access-decision-manager-ref="accessDecisionManager" auto-config="true">
<intercept-url pattern="/welcome*" access="ADMIN" />
<form-login login-page="/login" default-target-url="/welcome"
authentication-failure-url="/loginfailed" />
<logout logout-success-url="/logout" />
</http>
I would start by adding '/springmvc' to the mapping for your dispatcher servlet.
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/springmvc/*</url-pattern>
</servlet-mapping>
That should give you a common prefix for your controllers. You may have to tweak spring security separately to get the login/logout links working. E.G.
<http access-decision-manager-ref="accessDecisionManager" auto-config="true">
<intercept-url pattern="/springmvc//welcome*" access="ADMIN" />
<form-login login-page="/springmvc/login" default-target-url="/springmvc/welcome"
authentication-failure-url="/springmvc/loginfailed" />
<logout logout-success-url="/springmvc/logout" />
</http>
The ControllerClassNameHandlerMapping class is for setting up "convention over configuration" mappings. In other words the path is derived from the class/package name which means you don't need the #RequestMapping annotation at all.

Spring Security Intercepted URL Throws a 404 Error

I get a 404 error when I try to access a Spring Security protected URL after I have successfully logged in, but do not get the error when I do not protect the URL with Spring Security.
I am using Spring-MVC, Spring Security and Hibernate. I have tried to get what the problem might be, but have totally failed. I need your help guys.
My spring-security.xml file is as:
<http auto-config="true">
<intercept-url pattern="/sec/*" access="ROLE_USER" />
<form-login login-page="/login"
authentication-success-handler-ref="successHandler" authentication-failure-handler-ref="failureHandler"
authentication-failure-url="/login/error" />
<remember-me/>
<logout logout-success-url="/login" />
<access-denied-handler error-page="/403"/>
</http>
The dispatcher-servlet.xml is as:
<mvc:annotation-driven/>
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer" p:definitions="/WEB-INF/tiles.xml" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="/WEB-INF/application"/>
<property name="cacheSeconds" value="1"/>
and web.xml is as:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/dispatcher-servlet.xml,
/WEB-INF/spring-security.xml,
/WEB-INF/applicationContext.xml,
/WEB-INF/spring-db.xml
</param-value>
</context-param>
<filter>
<filter-name>hibernateSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
<init-param>
<param-name>flushMode</param-name>
<param-value>ALWAYS</param-value>
</init-param>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hibernateSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</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>
<welcome-file-list>
<welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>
Note that the Spring Security Authentication works just fine. Its the urls it protects that kind of are no longer being mapped by the dispatcher. Someone please help me solve this. Thank you in advance.
I have got the problem. I had set the wrong role in the database for the user I was trying to log in as. So essentially its a 403 error of which I hadn't mapped the 403 handling page hence throwing the 404 error. Thanx to all those who tried to help.

No mapping found for HTTP request with URI [/favicon.ico]

I can't recall what I have changed on my code but whenever I click on any links on my web it gives me this :
WARN : org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/favicon.ico] in DispatcherServlet with name 'mvc-dispatcher'
A portion of my web.xml
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter>
<filter-name>HttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
some configuration of my mvc-dispatcher-servlet.xml
<!-- Handles HTTP GET requests for /resources/** by efficiently serving
up static resources in the ${webappRoot}/resources directory -->
<mvc:resources mapping="/resources/**" location="resources/" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources
in the /WEB-INF/views directory -->
<beans:bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
<beans:property name="order" value="1" />
</beans:bean>
<!-- testing for pdf export -->
<beans:bean class="org.springframework.web.servlet.view.XmlViewResolver">
<beans:property name="location" value="/WEB-INF/spring-pdf-views.xml" />
<beans:property name="order" value="0" />
</beans:bean>
Other than that everything works fine, means any page is loaded correctly without any error. May I know what might cause this ? And who is using that .ico image ?
Most web browsers attempt to fetch a site's favicon at the root of the context with a request for the /favicon.ico resource automatically. In your case is not handled by any configured Spring mapping.
If you have a favicon at /favicon.ico or in another location you could configure a mapping in Spring to resolve the request to a valid resource:
<mvc:resources mapping="/favicon.ico" location="/favicon.ico" />
The favicon.ico : icon in the browser tab
Since Spring Security are using
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Did you exclude the favicon.ico from filtering by Spring Security?
<http pattern="/favicon.ico" security="none" />
Try to locate favicon.ico in your html page as below:
<html>
<head>
<link href="[YOUR_FAVICON_PATH]/favicon.ico" rel="icon" type="image/x-icon" />
</head>
</html>

Change servlet-mappings for Spring and Spring Security

I'm currently writing a Spring MVC application, secured by Spring Security. For the login a basic form authentication is used and since I didn't added further configuration the credentials are POSTed to http://www.localhost:8080/myWebApp/j_spring_security_check.
So far so good, but now I've introduced a second servlet (CometD), which shall not be affected by Spring nor Spring Security. For this, I tried to change the servlet-mappings to map Spring and Spring Security against /app, respectively /app/*, and the other Servlet against cometd/*. My web.xml looks as follows:
<!-- Spring security -->
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</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>/app/*</url-pattern>
</filter-mapping>
<!-- Spring MVC -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/app</url-pattern>
</servlet-mapping>
<!-- CometD -->
<servlet>
<servlet-name>cometd</servlet-name>
<servlet-class>org.cometd.server.CometdServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cometd</servlet-name>
<url-pattern>/cometd/*</url-pattern>
</servlet-mapping>
The problem with this is that after this changes I'm be able to login any more. The server is not able to find any request mapping and the client tells me
NetworkError: 404 Not Found - http://localhost:8080/myWebApp/app/j_spring_security_check.
What's wrong with this mappings? How can I configure Spring and Spring Security to only handle requests for specific mappings and not for / and /* as described in the documentation?
Thanks a lot in advance!
Best,
René
Leave your springSecurityFilterChain mapped to /. Change your security config:
<http use-expressions="true">
<intercept-url pattern="/cometd/**" access="permitAll" />
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
</http>

Two DispatcherServlets and DelegatingFilterProxy do not work together

There ara two DispatcherServlets in my app. One is for jsp service and dispatches admin's addresses.
<servlet>
<servlet-name>adminServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/adminServlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>adminServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Second DispatcherServlet dispatches addresses where xml or json are sending.
<servlet>
<servlet-name>userServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/userServlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>userServlet</servlet-name>
<url-pattern>/user/*</url-pattern>
</servlet-mapping>
There is also DelegatingFilterProxy to ensure security
<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>
Security context configuration file:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/login.do"
access="permitAll" requires-channel="http" />
<intercept-url pattern="/*"
access="hasRole('ROLE_USER')" requires-channel="http" />
<intercept-url pattern="/admin/*"
access="hasRole('ROLE_ADMIN')" requires-channel="http" />
<form-login login-page="/login.do"
login-processing-url="/loginProcess" username-parameter="user"
password-parameter="password" default-target-url="/admin" />
<logout logout-url="/logout.do"
invalidate-session="true" />
<remember-me key="secCh4"
token-validity-seconds="3600" data-source-ref="dataSource" />
<session-management
session-fixation-protection="newSession">
</session-management>
<intercept-url pattern="/user/*" access="hasRole('ROLE_USER')" />
</http>
The part of service which is dispatched by adminServlet need authentication and is secured, but the part which is dipatched by userServlet is completely unsecured and any authentication is not necessary. I don't know why, I set url-pattern in DelegatingFilterProxy to /* and i also set
<intercept-url pattern="/user/*" access="hasRole('ROLE_USER')" />
Any ideas?
DelegatingFilterProxy has nothing to do with DispatcherServlet. In fact, Spring MVC is not needed and you can use any other frame, like Struts.
With your rule <intercept-url pattern="/user/*" access="hasRole('ROLE_USER')" /> you are specifying to intercept urls like /user/list/ or /user/4, but not /user/4/save. If you want to intercept all urls starting with /user/ try with <intercept-url pattern="/user/**" access="hasRole('ROLE_USER')" />. You can read a little more here.
Anyway, remember that intercept-url order is important, too.

Resources