Spring Security XML config - spring

is there any way to do the opposite to "access"? Something like "deny".
<intercept-url pattern="/nexthome/logout" access="ROLE_USER,ROLE_ADMIN" />
And if there isn't, can I do it somehow?
For example:
<intercept-url pattern="/nexthome/logout" access="ROLE_USER,ROLE_ADMIN" deny="ROLE_DENY" />
In this situation if a user has ROLE_DENY I expect that he won't see /nexthome/logout

Enable expressions:
<http use-expressions="true">
Allow if USER or ADMIN but not if DENY.
<intercept-url pattern="/nexthome/logout" access="(hasRole('USER') or hasRole('ADMIN')) and !hasRole('DENY')">

Related

spring security session management conflict with tomcat webapp path

I am implementing the web logout process using spring security.
When I ran a web project with IDE (e.g., eclipse) in the development environment, I ran the webapp through the ROOT path, so it was processed normally.
However, when I distributed it to the actual environment, I registered the path to my service because I had to register several services in one Tomcat.
For example... http://localhost:8080/ -> http://localhost:8080/operator
As a result of distributing the webapp as above, two problems appeared.
When logging out, move to invalid-session-url.
Duplicate session detection, expired-url ignored and moved to invalid-session-url.
The example below is part of my spring security setting xml file.
When distributing to Tomcat, when adding path to the webapp, is there any part that needs to be set up in session-management?
It works normally in the local environment, so I think that's definitely the problem.
<security:http auto-config="true" use-expressions="true">
<security:csrf disabled="true"/>
<security:intercept-url pattern="/resources/**" access="permitAll" />
<security:intercept-url pattern="/favicon.io" access="permitAll" />
<security:intercept-url pattern="/login" access="permitAll" />
<security:intercept-url pattern="/callApiService" access="permitAll" />
<security:intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
<security:csrf disabled="true"/>
<security:form-login
login-page="/login"
login-processing-url="/loginprocess"
authentication-failure-url="/login?auth=fail"
authentication-success-handler-ref="customLoginSuccessHandler"
default-target-url="/"
/>
<security:logout
delete-cookies="JSESSIONID"
logout-url="/logout"
logout-success-url="/login"
/>
<security:session-management invalid-session-url="/login?auth=invalid">
<security:concurrency-control
max-sessions="1"
error-if-maximum-exceeded="false"
expired-url="/login?auth=expired"
/>
</security:session-management>
</security:http>

Upgrading Spring from 3.0.5 to 3.2.18 - Resources like images, CSS and JS are not accessible

I am new to Spring and started working on upgrade from 3.0.5 to 3.2.18, I have tried to modify the versions and change the artifact ID's to the new version (e.g org.springframework.core to spring-core, etc..) and updated the XSD versions from 3.0 to 3.2 in the declarations. I am facing one issue with the intercept-url in the applicationcontext-security.xml
<http auto-config="false" entry-point-ref="authenticationProcessingFilterEntryPoint" use-expressions="true">
<custom-filter position="FORM_LOGIN_FILTER" ref="authenticationProcessingFilter"/>
<custom-filter position="LAST" ref="loadUserContextFilter"/>
<logout logout-url="/static/j_spring_security_logout" logout-success-url="/login" />
<!-- Configure these elements to secure URIs in your application -->
....
...
..
<intercept-url pattern="/admin/campus/buildings/new" access="hasAnyRole('ROLE_RES.APP.CAMPUS.ADMIN_DEV','ROLE_RES.APP.CAMPUS.ADMIN_FULL')"/>
<intercept-url pattern="/admin/campus/buildings/*/sitesofservice/new" access="hasAnyRole('ROLE_RES.APP.CAMPUS.ADMIN_DEV','ROLE_RES.APP.CAMPUS.ADMIN_FULL')"/>
.....
<intercept-url pattern="/admin/**" access="hasAnyRole('ROLE_RES.APP.CAMPUS.ADMIN_FULL','ROLE_RES.APP.CAMPUS.ADMIN_DEV','ROLE_RES.APP.CAMPUS.ADMIN_DIFF')"/>
<intercept-url pattern="/batch/**" access="hasRole('ROLE_RES.APP.CAMPUS.ADMIN_BATCH')"/>
<intercept-url pattern="/resources/**" filters="none" access="permitAll" />
<intercept-url pattern="/static/**" access="permitAll" />
<intercept-url pattern="/**" access="permitAll" />
In the above file, <intercept-url pattern="/resources/**" filters="none" access="permitAll" /> application is throwing below exception.
Caused by: org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: The use of "filters='none'" is no longer supported. Please define a separate element for the pattern you want to exclude and use the attribute "security='none'".
I tried different approaches by removing the filters="none" and creating a new http attribute with security=none but none of them worked.
I referred to the below option
https://www.baeldung.com/security-none-filters-none-access-permitAll#security-none
and added a new http element, but still no luck.
After the above change, the file looks like below
<http pattern="/resources/**" security="none"/>
<http auto-config="false" entry-point-ref="authenticationProcessingFilterEntryPoint" use-expressions="true">
...
...
The application is building and deploying successfully, but images, CSS and JS are not loading. Not getting any errors in the logs (I am using IntelliJ by creating a new local tomcat server for deploying and testing the application)
Any help is appreciated!
what I see is that in your XML spring configuration file you wrote <http pattern="/resources/**" security="none"/> but in the image you showed css and js are located under styles and js so I'd try this XML configuration:
<http pattern="/styles/**" security="none"/>
<http pattern="/js/**" security="none"/>
Otherwise you should move JS and CSS under a folder called resources but this would imply modify every JSP or any front-end technology you are using to call these resources; the impact would be greater but, maybe, the solution would be cleaner
From a security point of view, the only requirement is just permitAll all the resources (js, images and styles) that you need.
You can do it with the following configuration:
<intercept-url pattern="/js/**" access="permitAll"/>
<intercept-url pattern="/images/**" access="permitAll"/>
<intercept-url pattern="/styles/**" access="permitAll"/>
Maybe you already are doing that, but if it is not the case, you can use the resource mapping mechanism that Spring MVC provides to serve static content.
You can configure it like this in your MVC configuration:
<mvc:resources mapping="/js/**" location="/js/" />
<mvc:resources mapping="/images/**" location="/images/" />
<mvc:resources mapping="/styles/**" location="/styles/" />
Then, you only need to point at the specific resource in your pages:
<link href="<c:url value="/style/main.css" />" rel="stylesheet" type="text/css" />
Try using:
<link rel="stylesheet" href="${pageContext.request.contextPath}/styles/campus.css" />
Try this, this is working fine for me. I ma using SPring-Security 3.2 version.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:security="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
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.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<security:http pattern="/css/**" security="none"/>
<security:http pattern="/login.jsp*" security="none"/>
<security:http auto-config="true" access-denied-page="/denied.jsp" servlet-api-provision="false">
<security:intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<security:form-login login-page="/login.jsp" authentication-failure-url="/login.jsp" default-target-url="/dashboard"/>
<security:logout delete-cookies="true" logout-success-url="/login.jsp" logout-url="/j_spring_security_logout" invalidate-session="true"/>
<security:session-management invalid-session-url="/login.jsp" session-authentication-error-url="/login.jsp" session-fixation-protection="newSession" />
</security:http>
</beans:beans>
To access the css on jsp or something, there are ways and one of them is like this:
First add this in JSP file:
<%# page isELIgnored="false"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
Second is to refer it like this:
<link href="<c:url value="/style/campus.css" />" rel="stylesheet" type="text/css" />

Spring Security 3.2.2 Logout Redirecting to Wrong Page

I have a logout button created which is set up and works, but it's redirecting to my invalid-session-url for some reason. Relevant bit of the security.xml:
<http use-expressions="true">
<form-login login-page="/login"
login-processing-url="/j_spring_security_check"
default-target-url="/view"
always-use-default-target="true"
authentication-failure-url="/login?redirect=login_error" />
<logout logout-success-url="/login?redirect=logout" delete-cookies="JSESSIONID"/>
<session-management invalid-session-url="/login?redirect=session_timeout" />
<intercept-url pattern="/login" access="isAnonymous()" />
<intercept-url pattern="/**" access="isAuthenticated()" />
</http>
Not sure why this is happening. I have my session-timeout in web.xml set to 5.
When you logout the first thing that Spring Security does is to invalidates the session, so the invalid-session-url is used. You can set invalidate-session="false" on the logout element or remove <session-management invalid-session-url="/login?redirect=session_timeout" />.

intercept-url pattern /** causing 404 error

I have searched here, google and springsource for this and could not find a solution that worked for me. I have the below spring-security.xml and when I use the pattern
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
This gives me a 404 error when it redirects to the login page. But this does not happen if I use
<intercept-url pattern="/index*" access="hasRole('ROLE_USER')" />
But obviously this does not secure the rest of the app.
I'm sure this is something simple I am overlooking but the closest thing I could find was this stack overflow question, Which I have already incorperated in my xml file below but still have the same issue. I have tried this without use-expressions="true" and I have tried switching the intercept-url's around (I'm not 100% but I am fairly sure that the /** pattern should be the last one as I believe urls are matched in the same order as declared)
Any advice/help would be great
spring-security.xml
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
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.3.xsd">
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/login" filters="none" access="permitAll" />
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<form-login login-page="/login" default-target-url="/welcome"
authentication-failure-url="/loginfailed" />
<logout logout-success-url="/logout" />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="username" password="password" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
Update
Just in case it is a factor I'm using Spring and Spring security 3.0.4.RELEASE
Answer
Following Kris's advice I changed
<intercept-url pattern="/login" filters="none" access="permitAll" />
to:
<intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" />
This caused a 500 Error due to the exception
SpelEvaluationException: EL1008E:(pos 0): Field or property
'IS_AUTHENTICATED_ANONYMOUSLY' cannot be found on object of
type'org.springframework.security.web.access.expression.WebSecurityExpressionRoot
I solved this by changing the IS_AUTHENTICATED_ANONYMOUSLY to isAnonymous()
<intercept-url pattern="/login" access="isAnonymous()" />
For completeness, here's the real reason this requires a change to isAnonymous().
The <http> element has an attribute use-expressions which defaults to true. In the default situation, you are required then to use "security expressions" instead of role names. If you wish to use only role names in access= declarations, you need to turn off expressions with
<http use-expressions="false"> ... </http>
Adds an AnonymousAuthenticationFilter to the stack and an AnonymousAuthenticationProvider. Required if you are using the IS_AUTHENTICATED_ANONYMOUSLY attribute.
spring secuirty
or use isAnonymous() instead.
Change this <intercept-url pattern="/login" filters="none" access="permitAll" />
to
<intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" />
The config looks fine to me. Could it be that the /login page is actually not there? The second config (with /index*) might have only worked, because then the request you made wasn't intercepted, and consequently didn't get redericted to the non-existent /login page. If it was a problem with the config, Spring Security would respond with 403 not 404.
Double-check without any Spring Security configured if the /login url works.

Read context param value in spring configuration xml

Added the following parameter in context.xml
<Parameter name="channel" value="any"
override="false"/>
I want to read the value of channel in spring configuration xml
<intercept-url pattern="/**" access="ROLE_USER" requires-channel="READ_VALUE_OF_CHANNEL_PARAMETER" />
READ_VALUE_OF_CHANNEL_PARAMETER needs to be replaced.
How to do it?
Found the answer
<intercept-url pattern="/**" access="ROLE_USER" requires-channel="#{contextParameters.channel}" />

Resources