I have a problem with Spring Security. It looks like this:
I change some data in a formular
I leave the computer for some time (enough to timeout the active session)
I come back to the computer
I click a "save" button in the webapp
Now - the data IS saved to the database, and then the app logs me out telling that my session has timed out. This behavior is improper, how to make sure that I am completely logged out after defined or default time, without any possibility to save data after the timeout?
My security-context.xml looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<import resource="spring-database.xml" />
<security:http pattern="/login" security="none" />
<security:http pattern="/loginfailed" security="none" />
<security:http pattern="/403" security="none" />
<security:http auto-config="true">
<security:intercept-url pattern="/*" access="ROLE_ADMIN" />
<security:form-login login-page="/login"
default-target-url="/" authentication-failure-url="/loginfailed" />
<security:logout logout-success-url="/login" />
<security:access-denied-handler
error-page="/403" />
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:jdbc-user-service
data-source-ref="dataSource"
users-by-username-query="select username,password, enabled from users where username= ?"
authorities-by-username-query="select username,role from user_roles where username= ?" />
</security:authentication-provider>
</security:authentication-manager>
</beans>
You are missing an xml attribute in your <security:logout tag. Just add invalidate-session="true" in this tag. Through this way in every case of an invalid Session the user will be forced to re-login. You may read more information about this feature of Spring Secutity in this thread.
Below you may find a part of your XML which includes the aforementioned attribute.
...
<security:http auto-config="true">
<security:intercept-url pattern="/*" access="ROLE_ADMIN" />
<security:form-login login-page="/login"
default-target-url="/" authentication-failure-url="/loginfailed" />
<security:logout logout-success-url="/login" invalidate-session="true"/>
<security:access-denied-handler
error-page="/403" />
</security:http>
...
Related
Spring security how do admin perform every action which comes after (/admin/**) just using 1 intercept url
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.2.xsd">
<!-- enable use-expressions -->
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/user**" access="permitAll" />
<!-- access denied page -->
<access-denied-handler error-page="/noaccess" />
<form-login login-page="/login" authentication-failure-url="/loginfailed" authentication-success-handler-ref="customSuccessHandler"
username-parameter="username" password-parameter="password" />
<logout logout-success-url="/logout" />
<!-- enable csrf protection -->
<csrf />
</http>
<authentication-manager>
<authentication-provider user-service-ref="loginService" />
</authentication-manager>
<beans:bean id="customSuccessHandler" class="com.slp.pro.handler.CustomSuccessHandler" />
</beans:beans>
I am pretty new in Spring Security and I have the following problem.
I have this controller method that handle request toward the /riepilogoCentrale resource
#RequestMapping(value = "/riepilogoCentrale", method = RequestMethod.GET)
public String riepilogoUtenteCentrale(HttpServletRequest request, Model model, Locale locale) {
System.out.println("INTO riepilogoUtenteCentrale()");
return "centrale/riepilogoCentrale";
}
My problem is that this resource (so the related rendered page) have to be accessible to everyone (also the not logged user) and as it is actually configured Spring Security if I try to access to this resource as visitor (not logged user) Spring redirects me to the log in page.
This is my Spring Security configuration file (named spring-security.xml):
<?xml version="1.0" encoding="UTF-8"?>
<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-4.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd">
<http pattern="/resources/**" security="none"/>
<http auto-config="true" use-expressions="true" authentication-manager-ref="authenticationManager">
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/registrati" access="permitAll" />
<intercept-url pattern="/salvaRegistrazione" access="permitAll" />
<intercept-url pattern="/captcha.html" access="permitAll" />
<intercept-url pattern="/**" access="isAuthenticated()" />
<logout logout-success-url="/login" logout-url="/logout" />
<form-login login-page="/login"
authentication-failure-url="/login?error=true"
default-target-url="/"
username-parameter="nomeUtente"
password-parameter="password"
login-processing-url="/j_spring_security_check"/>
<csrf disabled="true"/>
</http>
<authentication-manager id="authenticationManager" >
<authentication-provider>
<jdbc-user-service data-source-ref="datasource"
users-by-username-query="select des_usr_par, des_psw_par,true from TID001_ANAGPARTECIPA where des_usr_par =?"
authorities-by-username-query="select des_usr_par, prg_par from TID001_ANAGPARTECIPA where des_usr_par = ? "/>
</authentication-provider>
</authentication-manager>
</beans:beans>
So, how can I exclude the /riepilogoCentrale from the Spring Security management and make it accessible also to the not logged users ?
You're already doing this for some of your resources; for example:
<intercept-url pattern="/salvaRegistrazione" access="permitAll" />
I would imagine that you'd add another intercept-url value including /riepilogoCentrale as the pattern, and implement other business logic inside of your controller based on whether or not the user is authenticated.
You are already excluding some resources.
<http pattern="/resources/**" security="none"/>
Just add the same entry with your riepilogoCentrale-resource.
I have project secured via Spring security. I need to determine whether the user, who just accessed to JSP is already logged in. I've read some articles, posts here and documentation and tried to implement it with this code:
<sec:authorize ifAnyGranted="ROLE_ANONYMOUS">
USER NOT LOGGED IN
<td>Login</td>
</sec:authorize>
<sec:authorize ifNotGranted="ROLE_ANONYMOUS">
USER LOGGED IN
<td>Logout</td>
</sec:authorize>
Nevertheless I always get "USER LOGGED IN" and I can't realize why.. This is my security context
<beans xmlns:security="http://www.springframework.org/schema/security"
xmlns="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.1.xsd">
<security:http pattern="/resources/**" security="none"/>
<security:http pattern="/login*" security="none" auto-config="true"/>
<security:http pattern="/denied" security="none"/>
<security:http auto-config="true" access-denied-page="/denied" servlet-api-provision="false">
<security:intercept-url pattern="/login*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<security:intercept-url pattern="/edit/**" access="ROLE_EDIT"/>
<security:intercept-url pattern="/admin/**" access="ROLE_ADMIN"/>
<security:intercept-url pattern="/**" access="ROLE_USER"/>
<security:form-login login-page="/login" authentication-failure-url="/denied"
default-target-url="/"/>
<security:logout logout-success-url="/login" />
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="adam" password="adampassword" authorities="ROLE_USER"/>
<security:user name="jane" password="janepassword" authorities="ROLE_USER, ROLE_ADMIN"/>
<security:user name="sue" password="suepassword" authorities="ROLE_USER, ROLE_EDIT"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
I'd appreciate any help :)
If a page is accesible to anyone, as set in your secruity context, you can conditionally display content like so :
<sec:authorize var="loggedIn" access="isAuthenticated()"/>
and using fairly standard jstl you can then :
<c:choose>
<c:when test="${loggedIn}">
<td>Logout</td>
A tad of googling tells me ifnotgranted is deprecated
I am adding Spring Security to one Spring project.
The architecture of the system is REST and user can access to different resources.
I would like to give access to personal information to administrators and users that are owners of this information.
I have started simple: filtering user profile like this:
In my service layer I wanted to use method annotations and include method parameters..
#PreAuthorize("hasRole('ROLE_ADMIN') or principal.userId == #id")
public Usuario getUser(int id) throws DAOException {
...
}
But this is not working at all. Any user can see all profiles (admins and all users also) when this URL is requested (Web layer):
#RequestMapping(value="/user/{uid}", method=RequestMethod.GET)
public ModelAndView getUser(#PathVariable int uid) throws DAOException {
userDAO = new UsuarioJPADAO();
userService.setUsuarioDAO(userDAO);
return new ModelAndView("user", "user", userService.getUser(uid));
}
Here is my security.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- Security Annotations -->
<global-method-security
pre-post-annotations="enabled"/>
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/css/**" access="permitAll" />
<intercept-url pattern="/images/**" access="permitAll" />
<intercept-url pattern="/js/**" access="permitAll" />
<intercept-url pattern="/favicon.ico" access="permitAll" />
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/users" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/users/page/*" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/customers" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/employees" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/search/*" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/*" access="hasAnyRole('ROLE_ADMIN, ROLE_EMPLOYEE, ROLE_PARTNER, ROLE_USER')" />
<intercept-url pattern="/*/*" access="hasAnyRole('ROLE_USER, ROLE_ADMIN')" />
<intercept-url pattern="/*/*/*" access="hasAnyRole('ROLE_USER, ROLE_ADMIN')" />
<intercept-url pattern="/*/*/*/*" access="hasAnyRole('ROLE_USER, ROLE_ADMIN')" />
<intercept-url pattern="/*/*/*/*/*" access="hasAnyRole('ROLE_USER, ROLE_ADMIN')" />
<intercept-url pattern="/*/*/*/*/*/*" access="hasAnyRole('ROLE_USER, ROLE_ADMIN')" />
<intercept-url pattern="/*/*/*/*/*/*/*" access="hasAnyRole('ROLE_USER, ROLE_ADMIN')" />
<form-login login-page="/login" login-processing-url="/doLogin"
authentication-failure-url="/login?error"
username-parameter="username" password-parameter="password"
default-target-url="/default" />
<logout invalidate-session="true" logout-success-url="/login?logout" logout-url="/logout"/>
</http>
<authentication-manager>
<authentication-provider user-service-ref="UsuarioService">
</authentication-provider>
</authentication-manager>
I have checked Spring Security 3.1 book and apparently my configuration is as book suggests. I have read other Stack Overflow posts (here and here) but I had no luck.
Update: Added application-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<context:annotation-config />
<context:component-scan base-package="com.pe.fs" />
<mvc:annotation-driven />
<mvc:resources mapping="/**" location="/" />
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
</mvc:interceptors>
<!-- DataSource -->
<bean id="jpaDataSource" class="oracle.jdbc.pool.OracleDataSource"
destroy-method="close"
p:driverType="oracle.jdbc.OracleDriver"
p:user="**********"
p:password="**********"
p:uRL="jdbc:oracle:thin:#localhost:1521:XE"
/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml"></property>
<property name="persistenceUnitName" value="freesunPU" />
<property name="dataSource" ref="jpaDataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<property name="showSql" value="false" />
</bean>
</property>
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory" />
<tx:annotation-driven mode="aspectj"/>
<context:load-time-weaver aspectj-weaving="autodetect" />
Update: I have added spring-security-aspects to POM and no changes. Other changes suggested in answers have been tested with but annotations such #PreAuthorize are still not working. Cna this be a problem between contexts? Can be the usage of aspectJ the reason?
What am I doing wrong?
Finally I found solution.
In SO I found some usefull answers. See here and here.
I moved global-method-security to application-context.xml which is the context of my services.
<security:global-method-security
mode="aspectj"
secured-annotations="enabled"
jsr250-annotations="disabled"
pre-post-annotations="enabled"/>
Where mode="aspectj" as Javadoc says:
...can be used to specify that AspectJ should be used instead of the
default Spring AOP. If set, secured classes must be woven with the
AnnotationSecurityAspect from the spring-security-aspects module.
Of course, I have added to POM spring-security-aspects:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-aspects</artifactId>
<version>3.1.3.RELEASE</version>
</dependency>
Add new interface:
public interface UserService extends UserDetailsService {
Usuario getUser(int id) throws DAOException
}
Implement it in your user service and try again. Spring will be able add requested authorization checks using JDK proxies.
As another option you can configure Spring to use some more heavyweight libraries like Javassist or even AspectJ.In this case interface will be not necessary.
EDIT. Make sure that global-method-security is declared in the same spring context with your user service bean.
The alternative way to make it work is to add the following code in your security.xml
<intercept-url pattern="/user/**" access="hasRole('ROLE_ADMIN')" />
It will ensure that only admin can access the resources starting with pattern /user/.
Why would I get the basic auth prompt when I go to /preregistered/* ? I thought the below configuration would only make basic auth apply when /services/** url path was matched. I'm using spring-security 3.1.0.M1
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
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/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="dc" />
<global-method-security />
<http security="none" pattern="/javax.faces.resource/**" />
<http security="none" pattern="/services/rest-api/1.0/public/**" />
<http pattern="/services/**" create-session="stateless">
<intercept-url pattern="/**" access="ROLE_USER" />
<http-basic />
</http>
<http access-denied-page="/auth/denied.html">
<intercept-url
pattern="/**/*.xhtml"
access="ROLE_NONE_GETS_ACCESS" />
<intercept-url
pattern="/preregistered/*"
access="ROLE_ANONYMOUS,ROLE_USER"/>
<intercept-url
pattern="/auth/*"
access="ROLE_ANONYMOUS,ROLE_USER"/>
<intercept-url
pattern="/preregistered/*"
access="ROLE_ANONYMOUS,ROLE_USER"/>
<intercept-url
pattern="/registered/*"
access="ROLE_USER"
requires-channel="http"/>
<intercept-url
pattern="/secured/*"
access="ROLE_USER"
requires-channel="https"/>
<form-login
login-processing-url="/j_spring_security_check.html"
login-page="/auth/login.html"
default-target-url="/registered/home.html"
authentication-failure-url="/auth/login.html" />
<logout invalidate-session="true"
logout-url="/auth/logout.html"
success-handler-ref="DCLogoutSuccessHandler"/>
<anonymous username="guest" granted-authority="ROLE_ANONYMOUS"/>
<custom-filter after="FORM_LOGIN_FILTER" ref="xmlAuthenticationFilter" />
<session-management session-fixation-protection="none"/>
</http>
<authentication-manager alias="am">
<authentication-provider user-service-ref="userManager">
<password-encoder ref="passwordEncoder" />
</authentication-provider>
<authentication-provider ref="xmlAuthenticationProvider" />
</authentication-manager>
</beans:beans>
Are you trying to reach an .xhtml under /preregistered ?
If you try to reach http://yoururl.com/preregistered/something.xhtml.
Your intercept-url definition:
<intercept-url
pattern="/**/*.xhtml"
access="ROLE_NONE_GETS_ACCESS" />
will intercept it.