Spring Security Intercept-url pattern not working - spring-mvc

My application can have below URLs:
/siteadmin/homepage/
/siteusers/customer/createCustomer
Below is my spring-security.xml:
<beans:beans>
<http auto-config="true">
<intercept-url pattern="/siteusers***" access="isAuthenticated()" />
<!-- <intercept-url pattern="siteusers/home/*" access="hasRole('USER') OR hasRole('ADMIN')" /> -->
<intercept-url pattern="/siteadmin***" access="hasRole('ROLE_ADMIN')" />`enter code here`
<form-login login-page="/siteusers/loginprocess/login" default-target-url="/siteusers/home/homepage"
login-processing-url="/siteusers/loginprocess/login"
authentication-failure-url="/siteusers/loginprocess/login?error" username-parameter="username"
password-parameter="password" />
<logout logout-success-url="/siteusers/loginprocess/login?logout" logout-url="/siteusers/loginprocess/logout" />
<!-- enable csrf protection -->
<csrf />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="b" password="123456" authorities="ROLE_ADMIN" />
<user name="a" password="a" authorities="ROLE_USER" /><!-- This user can not access /admin url -->
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
If I logged in with user 'a' and hit URL http://localhost:8080/siteadmin/homepage/ it is allowing user 'a' to view the page although his role is not admin. But when I try to hit http://localhost:8080/siteadmin then Spring Security is working fine ie. its showing access denied page.
I want to restrict /admin/* URLs for users who doesn't have Admin role.

See AntPathMatcher:
The mapping matches URLs using the following rules:
? matches one character
* matches zero or more characters
** matches zero or more directories in a path
Some examples:
com/t?st.jsp - matches com/test.jsp but also com/tast.jsp or com/txst.jsp
com/*.jsp - matches all .jsp files in the com directory
com/**/test.jsp - matches all test.jsp files underneath the com path
org/springframework/**/*.jsp - matches all .jsp files underneath the org/springframework path
org/**/servlet/bla.jsp - matches org/springframework/servlet/bla.jsp but also org/springframework/testing/servlet/bla.jsp and org/servlet/bla.jsp
Your pattern /siteadmin***misses slashes. Use /siteadmin/**.

Related

Workflow admin console doesn't work: Possible CSRF attack noted

What I have:
Alfresco Share v5.2.d (r134641-b15, Aikau 1.0.101.3, Spring Surf
5.2.d, Spring WebScripts 6.13, Freemarker 2.3.20-alfresco-patched, Rhino 1.7R4-alfresco-patched, Yui 2.9.0-alfresco-20141223)
Alfresco Community v5.2.0 (r134428-b13) schema 10005
I want to use the workflow admin console. The console is available by link: http://....:8080/alfresco/s/admin/admin-workflowconsole
I'd like to be able to view all process definitions, delete the definition of the process, etc.
For example:
show definitions all
undeploy definition ...
use definition ...
etc
After accessing the console I try to execute any command, but get this exception (copy from screen):
HTTP Status 500 - Possible CSRF attack noted when comparing token in session and request parameter. Request: POST /alfresco/s/admin/admin-workflowconsole
type Exception report
message Possible CSRF attack noted when comparing token in session and request parameter. Request: POST /alfresco/s/admin/admin-workflowconsole
description The server encountered an internal error that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: Possible CSRF attack noted when comparing token in session and request parameter. Request: POST /alfresco/s/admin/admin-workflowconsole
org.springframework.extensions.webscripts.servlet.CSRFFilter$AssertTokenAction.run(CSRFFilter.java:845)
org.springframework.extensions.webscripts.servlet.CSRFFilter.doFilter(CSRFFilter.java:312)
org.alfresco.web.app.servlet.GlobalLocalizationFilter.doFilter(GlobalLocalizationFilter.java:68)
How to configure workflow admin console?
What I was trying to do:
As written by Axel Faust,
The web-client-security-config.xml has a default configuration for the
CSRFPolicy segment and can be overriden via the
web-scripts-config-custom.xml file in the alfresco/extension path.
Thus, I created the file web-scripts-config-custom.xml, then added to it missing rule and placed it under the path /opt/alfresco-community/tomcat/shared/classes/alfresco/exten‌​sion:
<alfrescoco-config>
<config evaluator="string-compare" condition="CSRFPolicy" replace="true">
<filter>
<rule>
<request>
<method>GET</method>
<path>/service/admin/.*</path>
</request>
<action name="generateToken">
<param name="session">{token}</param>
<param name="cookie">{token}</param>
</action>
</rule>
<rule>
<request>
<method>GET</method>
<path>/s/admin/.*</path>
</request>
<action name="generateToken">
<param name="session">{token}</param>
<param name="cookie">{token}</param>
</action>
</rule>
</filter>
</config>
</alfresco-config>
It doesn't work...
I added full configuration:
<alfresco-config>
<!--
CSRF filter config to mitigate CSRF/Seasurfing/XSRF attacks
To disable the CSRF filter override the <filter> to not contain any values, for example:
<config evaluator="string-compare" condition="CSRFPolicy" replace="true">
<filter/>
</config>
#since 5.2
-->
<config evaluator="string-compare" condition="CSRFPolicy">
<!--
Force creation of a Session when the filter matches a path - this should only be used when you are
confident the filtered part of the web application is using an authentication mechanism that will avoid
protected pages being accessed until the user is authenticated. Otherwise this would be a route to
a Session fixation attack.
-->
<session>true</session>
<!--
Properties that may be used inside the rest of the CSRFPolicy config to avoid repetition but
also making it possible to provide different values in different environments.
I.e. Different "Referer" & "Origin" properties for test & production etc.
Reference a property using "{propertyName}".
-->
<properties>
<!-- There is normally no need to override this property -->
<token>alf-csrftoken</token>
<!--
Override and set this property with a regexp that if you have placed Alfresco behind a proxy that
does not rewrite the Referer header.
-->
<referer></referer>
<!--
Override and set this property with a regexp that if you have placed Alfresco behind a proxy that
does not rewrite the Origin header.
-->
<origin></origin>
</properties>
<!--
Will be used and exposed to the client side code in Admin.CSRF
Use the Admin.CSRF.getHeader() or Admin.CSRF.getParameter() with Admin.CSRF.getToken()
to set the token in custom 3rd party code.
-->
<client>
<cookie>{token}</cookie>
<header>{token}</header>
<parameter>{token}</parameter>
</client>
<!-- The first rule with a matching request will get its action invoked, the remaining rules will be ignored. -->
<filter>
<!-- Refresh token on each new page visit -->
<rule>
<request>
<method>GET</method>
<path>/service/enterprise/admin/.*</path>
</request>
<action name="generateToken">
<param name="session">{token}</param>
<param name="cookie">{token}</param>
</action>
</rule>
<rule>
<request>
<method>GET</method>
<path>/s/enterprise/admin/.*</path>
</request>
<action name="generateToken">
<param name="session">{token}</param>
<param name="cookie">{token}</param>
</action>
</rule>
<rule>
<request>
<method>GET</method>
<path>/service/admin/.*</path>
</request>
<action name="generateToken">
<param name="session">{token}</param>
<param name="cookie">{token}</param>
</action>
</rule>
<rule>
<request>
<method>GET</method>
<path>/s/admin/.*</path>
</request>
<action name="generateToken">
<param name="session">{token}</param>
<param name="cookie">{token}</param>
</action>
</rule>
<!--
Verify multipart requests contain the token as a parameter
and also correct referer & origin header if available
-->
<rule>
<request>
<method>POST</method>
<header name="Content-Type">multipart/.+</header>
</request>
<action name="assertToken">
<param name="session">{token}</param>
<param name="parameter">{token}</param>
</action>
<action name="assertReferer">
<param name="referer">{referer}</param>
</action>
<action name="assertOrigin">
<param name="origin">{origin}</param>
</action>
</rule>
<!--
Verify that all remaining state changing requests contain a token in the header and correct referer & origin headers
if available. We "catch" all content types since just setting it to "application/json.*" since a webscript that doesn't
require a json request body otherwise would be successfully executed using i.e."text/plain".
-->
<rule>
<request>
<method>POST|PUT|DELETE</method>
</request>
<action name="assertToken">
<param name="session">{token}</param>
<param name="header">{token}</param>
</action>
<action name="assertReferer">
<param name="referer">{referer}</param>
</action>
<action name="assertOrigin">
<param name="origin">{origin}</param>
</action>
</rule>
</filter>
</config>
</alfresco-config>
It doesn't work...
As described here, I added to the web.xml the following:
<filter-mapping>
<filter-name>CSRF Token Filter</filter-name>
<url-pattern>/service/admin/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CSRF Token Filter</filter-name>
<url-pattern>/s/admin/*</url-pattern>
</filter-mapping>
It doesn't work...
I tried to disable CSRF filter by the following way:
<alfresco-config>
<config evaluator="string-compare" condition="CSRFPolicy" replace="true">
<filter/>
</config>
</alfresco-config>
It doesn't work...
How to configure workflow admin console?
Finally, I found my mistake!..
Instead of the web-scripts-config-custom.xml I created web-script-config-custom.xml. I missed the letter 's'
Now everything is OK.
Thank you very much, Axel Faust!..

Spring MVC make individual page accessible without login

I am using Spring MVC and I am trying to make an html page accesible without the need to login. My security xml configuration is as follows:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/err404.html" access="permitAll()" />
<intercept-url pattern="/login.html" access="permitAll()"/>
<intercept-url pattern="/accesibleWithoutLogin.html" access="permitAll()" />
<intercept-url pattern="/assets/**" access="permitAll()" />
<intercept-url pattern="/**" access="hasRole('AUTH_ADMIN')" />
<form-login login-page="/login.html"
login-processing-url="/static/j_spring_security_check"
authentication-success-handler-ref="authSuccessHandler"
authentication-failure-url="/login.html?t=error" />
<access-denied-handler error-page="/403" />
<logout logout-success-url="/login.html?act=logout" />
</http>
with this configuration I can access accesibleWithoutLogin.html but all the back-end(ajax requests to spring mvc) functionality is lost.
How can this page be fully functinal without having to login?

Redirect loop in Spring Security app

I am developing a Spring MVC / Spring Security application.
I do not have any exceptions or errors, but there is a redirect loop on one of the pages.
I'm using Spring 3.0.1 and Spring Security 3.0.1.
My dispatcher-security.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<security:http auto-config="true" use-expressions="true">
<security:form-login login-page="/login" default-target-url="/login" authentication-failure-url="/fail2login"/>
<security:logout logout-success-url="/"/>
<security:intercept-url pattern="/auth/**" access="hasRole('ANONYMOUS')" />
<security:intercept-url pattern="/js/**" access="hasRole('ANONYMOUS')" />
<security:intercept-url pattern="/css/**" access="hasRole('ANONYMOUS')" />
<security:intercept-url pattern="/**" access="hasRole('ADMIN')" />
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:jdbc-user-service data-source-ref="dataSource1"
users-by-username-query=" select name,password,enabled from user where name=?"
authorities-by-username-query="select u.name, r.role from user u, role r where u.role = r.auto_id and u.name =? "
/>
</security:authentication-provider>
</security:authentication-manager>
</beans>
Please help me......
The default-target-url attribute defines the page where the user is redirected in case of a successful login. Usually it is the home page of your application. You have default-target-url="/login", so it redirects you back to the login page after a successful login.
I do not understand the meaning of the ANONYMOUS role in you example. If it is the build-in role for anonymous users, I think it is called ROLE_ANONYMOUS.
In this case you probably use it incorrectly, and these two lines:
<security:intercept-url pattern="/js/**" access="hasRole('ANONYMOUS')" />
<security:intercept-url pattern="/css/**" access="hasRole('ANONYMOUS')" />
should be replaced with something like this:
<security:intercept-url pattern="/js/**" access="hasRole('ROLE_ANONYMOUS') or hasRole('ROLE_USER')" />
<security:intercept-url pattern="/css/**" access="hasRole('ROLE_ANONYMOUS') or hasRole('ROLE_USER')" />
Otherwise unauthontificated users ONLY will be able to access the /js/ and /css/ directories.
ROLE_USER in not a build-in role, it is a role that you define manually for all authenticated users.
See also:
What is the difference between ROLE_USER and ROLE_ANONYMOUS
The Spring Security Reference: Anonymous Authentication

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 Authentication is not working as expected in my configuration

I have configured spring authentication as below and its not working as expected
<sec:http auto-config="true">
<!-- Restrict URLs based on role -->
<sec:intercept-url pattern="pages/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<sec:intercept-url pattern="/css/style.css" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<sec:intercept-url pattern="pages/**" access="ROLE_USER" />
<!-- Override default login and logout pages -->
<sec:form-login login-page="/login.jsp"
default-target-url="/pages/products.xhtml"
authentication-failure-url="/login.html?login_error=1" />
<sec:logout logout-url="/logout" logout-success-url="/login.jsp" />
</sec:http>
On server start up i have been redirected to login.jsp ,if i use login form i am redirected to products.xhtml so far fine but if i directly access products.xhtml , it just allowing me to access the product.xhtml(Even after closing the broser or even on server restart) instead of redirecting to login.jsp . Could anyone just me what i am missing exactly?
Thanks & Regards
Vijay
Your patterns and URLs aren't consistent. You have "/login.jsp" for the login page and "pages/login.jsp" in the intercept-url pattern.
Try using:
<http pattern="/css/**" security="none">
<http>
<intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login login-page="/login.jsp"
default-target-url="/pages/products.xhtml"
authentication-failure-url="/login.html?login_error=1" />
<logout logout-url="/logout" logout-success-url="/login.jsp" />
</http>
The debug log for a particular request will explain exactly why it is or isn't secured.
Make sure you do not have a Cookie or a valid session...

Resources