I'm developing a website using spring security and I have a page that is unsecure, "product/58" where I have the following form:
<form:form name="offerForm" id="offer" modelAttribute="offerProposal" action="/product/make/offer/" method="post" enctype="multipart/form-data">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<form:input path="minPrice"/>
</form:form>
The problem is if I do the login and I open the page (I'm a authenticated user), submit the form the spring security redirects me to denied controller and in the log shows:
2018-03-22 19:09:42,679 DEBUG [user1_308 (21C272993EC9D1BD7085533415452657)] [https://localhost:8443/standard/resources/js/slick/ajax-loader.gif] [org.springframework.security.web.context.HttpSessionSecurityContextRepository] Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl#4193b3e0: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken#4193b3e0: Principal: com.projectx.standard.services.user.model.CustomUserDetails#58c7c40: Username: user1; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#2cd90: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 7A5CB3F014A45BB6632A3503A7B23D02; Granted Authorities: ROLE_USER'
2018-03-22 19:09:42,680 DEBUG [user1_308 (21C272993EC9D1BD7085533415452657)] [https://localhost:8443/standard/resources/js/slick/ajax-loader.gif] [org.springframework.security.web.csrf.CsrfFilter] Invalid CSRF token found for https://localhost:8443/standard/product/make/offer/
2018-03-22 19:09:42,747 INFO [user1_308 (21C272993EC9D1BD7085533415452657)] [https://localhost:8443/standard/resources/js/slick/ajax-loader.gif] [com.projectx.standard.app.interceptor.LogInterceptor] [Start request] - ************* URL https://localhost:8443/standard/accessDenied/ *************
The spring security configuration is as follows:
<?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.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.2.xsd">
<http pattern="/resources/css" security="none" />
<http pattern="/resources/images" security="none" />
<http pattern="/resources/js" security="none" />
<global-method-security secured-annotations="enabled" />
<beans:bean id="ajaxAwareLoginUrlAuthenticationEntryPoint" class="com.projectx.standard.app.handler.AjaxAwareLoginUrlAuthenticationEntryPoint">
<beans:constructor-arg value="/login/" />
</beans:bean>
<http use-expressions="true" disable-url-rewriting="true" entry-point-ref="ajaxAwareLoginUrlAuthenticationEntryPoint">
<access-denied-handler error-page="/accessDenied/" />
<session-management>
<concurrency-control expired-url="/login/" />
</session-management>
<logout logout-success-url="/" invalidate-session="true" logout-url="/logout" />
<intercept-url pattern="/favicon.ico" access="permitAll"
requires-channel="https" />
<intercept-url pattern="/robots.txt" access="permitAll"
requires-channel="https" />
<intercept-url pattern="/product/make/offer/*" access="hasRole('ROLE_USER')" />
<intercept-url pattern="/**" access="permitAll"
requires-channel="https" />
<!-- Set the login page and what to do if login fails -->
<form-login login-page="/login/"
authentication-failure-handler-ref="customAuthenticationFailureHandler"
authentication-success-handler-ref="customAuthenticationSuccessHandler"
username-parameter="j_username"
password-parameter="j_password"
login-processing-url="/j_spring_security_check"
always-use-default-target="false" />
<remember-me data-source-ref="dataSource"
remember-me-parameter="_spring_security_remember_me"
remember-me-cookie="SPRING_SECURITY_REMEMBER_ME_COOKIE" />
</http>
<beans:bean id="customAuthenticationSuccessHandler"
class="com.projectx.standard.app.handler.CustomAuthenticationSuccessHandler" />
<beans:bean id="customAuthenticationFailureHandler"
class="com.projectx.standard.app.handler.CustomAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/login/?error=true" />
</beans:bean>
<!-- Use a BCryptPasswordEncoder encoder since the user's passwords are
stored as BCryptPasswordEncoder in the database -->
<beans:bean id="passwordEncoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />
<authentication-manager>
<authentication-provider user-service-ref="loginService">
<password-encoder ref="passwordEncoder" />
</authentication-provider>
</authentication-manager>
</beans:beans>
This looks like CSRF but the form as the token. What I can do to fix this?
Thanks
I figure it out... If I added ?${_csrf.parameterName}=${_csrf.token} to the form action then everything works.
I don't know if it is the best approach, but it works!
Related
I am using a custom implemented SSO in my app which is using Spring.
(Recently I was upgrading my app to Spring 5.2.5 and Java 11.)
At final stage of that SSO process, a URL like below is posted which bypasses authentication/login page and opens main page.
http://localhost:8181/MyApp/j_spring_security_check?tokenId=999a1ec9-d92a-4a5e-a7ec-a8985c421000
But instead of opening main page it directs me to
access-denied-handler error-page="/ui/ordinary/noauthorization.xhtml"
But when I look at Spring debug logs, I realize that permitAll is matched. No access denied occured.
How can I find out what is really happening here? Why does not it proceed to main page or CustomAuthenticationFilter.attemptAuthentication method not called (overriding UsernamePasswordAuthenticationFilter)?
[2020-09-02 01:39:04,782][DEBUG] Checking match of request : '/j_spring_security_check'; against '/noauthorization.xhtml' - org.springframework.security.web.util.matcher.AntPathRequestMatcher.matches(AntPathRequestMatcher.java:177)
[2020-09-02 01:39:04,782][DEBUG] Checking match of request : '/j_spring_security_check'; against '/login' - org.springframework.security.web.util.matcher.AntPathRequestMatcher.matches(AntPathRequestMatcher.java:177)
[2020-09-02 01:39:04,782][DEBUG] Checking match of request : '/j_spring_security_check'; against '/j_spring_security_check' - org.springframework.security.web.util.matcher.AntPathRequestMatcher.matches(AntPathRequestMatcher.java:177)
[2020-09-02 01:39:04,782][DEBUG] Secure object: FilterInvocation: URL: /j_spring_security_check?tokenId=3e004f91-1aec-4f98-bc5c-1f49b69c209a; Attributes: [permitAll] - org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:219)
[2020-09-02 01:39:04,782][DEBUG] Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken#ca1ab61a: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#ffff6a82: RemoteIpAddress: 127.0.0.1; SessionId: node08gmgybqdzxi6l88ent9iokp01; Granted Authorities: ROLE_ANONYMOUS - org.springframework.security.access.intercept.AbstractSecurityInterceptor.authenticateIfRequired(AbstractSecurityInterceptor.java:348)
[2020-09-02 01:39:04,782][DEBUG] Voter: org.springframework.security.web.access.expression.WebExpressionVoter#75a450d1, returned: 1 - org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:66)
[2020-09-02 01:39:04,782][DEBUG] Authorization successful - org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:243)
[2020-09-02 01:39:04,782][DEBUG] RunAsManager did not change Authentication object - org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:256)
[2020-09-02 01:39:04,782][DEBUG] /j_spring_security_check?tokenId=3e004f91-1aec-4f98-bc5c-1f49b69c209a reached end of additional filter chain; proceeding with original chain org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:313)
[2020-09-02 01:39:04,791][DEBUG] Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#b7199c7 - org.springframework.security.web.header.writers.HstsHeaderWriter.writeHeaders(HstsHeaderWriter.java:169)
[2020-09-02 01:39:04,791][DEBUG] SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession. - org.springframework.security.web.context.HttpSessionSecurityContextRepository$SaveToSessionResponseWrapper.saveContext(HttpSessionSecurityContextRepository.java:351)
[2020-09-02 01:39:04,791][DEBUG] Chain processed normally - org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120)
[2020-09-02 01:39:04,792][DEBUG] SecurityContextHolder now cleared, as request processing completed - org.springframework.security.web.context.SecurityContextPersistenceFilter.
I have made many changes to xml after posting question but as far as I remember,
my securityContext.xml was like below:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans default-lazy-init="true"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xmlns="http://www.springframework.org/schema/security"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p" xmlns:task="http://www.springframework.org/schema/task"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
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.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.myapp.authentication" />
<http auto-config='true' use-expressions="true" entry-point-ref="myAuthenticationEntryPoint">
<custom-filter ref="customAuthenticationFilter" position="PRE_AUTH_FILTER"/>
<intercept-url pattern="/css/**" access="permitAll" />
<intercept-url pattern="/images/**" access="permitAll" />
<intercept-url pattern="/templates/**" access="isAuthenticated()" />
.
.
<intercept-url pattern="/ui/ordinary" access="denyAll" />
<intercept-url pattern="/ui/ordinary/" access="denyAll" />
.
.
<intercept-url pattern="/ui/ordinary/**"
access="hasAnyRole('ROLE_ORDINARY','ROLE_ADMINISTRATOR','ROLE_ROOT')" />
<intercept-url pattern="/ui/**" access="isAuthenticated()" />
<intercept-url pattern="/login.xhtml" access="permitAll" />
<intercept-url pattern="/j_spring_security_check" access="permitAll" />
<intercept-url pattern="/noauthorization.xhtml" access="permitAll" />
<intercept-url pattern="/**" access="denyAll" />
<form-login login-page='/login.xhtml'
username-parameter="j_username"
password-parameter="j_password"
login-processing-url="/j_spring_security_check"
authentication-failure-url="/login.xhtml"
always-use-default-target="false"
default-target-url="/ui/ordinary/list.xhtml" />
<access-denied-handler error-page="/ui/ordinary/noauthorization.xhtml" />
<logout logout-url="/j_spring_security_logout" logout-success-url="/login.xhtml?logout" delete-cookies="JSESSIONID" />
<csrf disabled="true" />
<session-management invalid-session-url="/login.xhtml"/>
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="customSpringAuthentication" />
</authentication-manager>
<beans:bean id="customAuthenticationFilter"
class="com.mayapp.authentication.CustomAuthenticationFilter" p:postOnly="false" p:authenticationManager-ref="authenticationManager">
<beans:property name="authenticationManager" ref="authenticationManager"/>
<beans:property name="authenticationFailureHandler" ref="failureHandler"/>
<beans:property name="authenticationSuccessHandler" ref="successHandler"/>
<beans:property name="sessionAuthenticationStrategy" ref="sessionFixationAttackHandler"/>
</beans:bean>
<beans:bean id="successHandler"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/ui/ordinary/list.xhtml"/>
</beans:bean>
<beans:bean id="failureHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/login.xhtml?login_error=true"/>
</beans:bean>
<beans:bean id="customSpringAuthentication" class="com.mayapp.authentication.CustomSpringAuthentication"/>
<beans:bean id="myAuthenticationEntryPoint" class="com.mayapp.authentication.CustomAuthenticationEntryPoint">
<!-- beans:property name="loginFormUrl" value="/login.xhtml" /-->
<beans:constructor-arg value="/login.xhtml"/>
</beans:bean>
<beans:bean id="sessionFixationAttackHandler" class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy"/>
</beans:beans>
After numerious experiments, I was able to solve the problem.
I removed
<intercept-url pattern="/j_spring_security_check" access="permitAll" />
And the most important thing solving it was adding "setRequiresAuthenticationRequestMatcher" in my token filter's constructor as below:
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
public CustomAuthenticationFilter() {
super();
// Because by default value of postOnly is true in UsernamePasswordAuthenticationFilter
super.setPostOnly(false);
super.setRequiresAuthenticationRequestMatcher( new AntPathRequestMatcher("/j_spring_security_check","GET") );
}
#Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
.
.
}
}
Thank to all guys who kindly asked me for more details to help me. I am appreciated
I am using spring 4 and hibernate 5.
Below is the xml config for my spring security.
I have this line:
<intercept-url pattern="/android/download" access="permitAll" />
When i tried access from SOAPUI, all i get is
Authentication request failed: com.test.common.JwtTokenMissingException: No token found in request headers. Please login again!
com.test.common.JwtTokenMissingException: No token found in request headers. Please login again!
Is there something wrong with my config file? I do not wish to set to security="none" as i want it to go through spring security.
Could it be the order in which the authenication is done in my CustomAuthenticationFilter class?
XML file for spring security:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.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.xsd">
<sec:http auto-config="false" create-session="stateless" entry-point-ref="customEntryPoint" use-expressions="true">
<intercept-url pattern="/admin/**" access="hasRole('ADMIN') or hasRole('MANAGER') or hasRole('SUPERVISOR')" />
<intercept-url pattern="/agent/**" access="isFullyAuthenticated()" />
<intercept-url pattern="/analysis/**" access="hasRole('ADMIN') or hasRole('MANAGER') or hasRole('SUPERVISOR') or hasRole('IC') or hasRole('OPS')" />
<intercept-url pattern="/android/download" access="permitAll" />
<intercept-url pattern="/android/**" access="hasRole('ADMIN') or hasRole('SNF_AGENT')" />
<intercept-url pattern="/audit/**" access="hasRole('ADMIN')" />
<intercept-url pattern="/auth/logout" access="isFullyAuthenticated()" />
<intercept-url pattern="/external/**" access="hasRole('ADMIN') or hasRole('MANAGER') or hasRole('SUPERVISOR') or hasRole('SV_IC') or hasRole('IC') " />
<intercept-url pattern="/index.xhtml" access="hasRole('ADMIN') or hasRole('MANAGER') or hasRole('SUPERVISOR')" />
<intercept-url pattern="/misc/**" access="isFullyAuthenticated()" />
<intercept-url pattern="/mission/missions/search" access="isFullyAuthenticated()" />
<intercept-url pattern="/mission/**" access="hasRole('ADMIN') or hasRole('MANAGER') or hasRole('SUPERVISOR') or hasRole('SV_IC')" />
<intercept-url pattern="/report/**" access="hasRole('ADMIN') or hasRole('MANAGER') or hasRole('SUPERVISOR')" />
<intercept-url pattern="/request/**" access="hasRole('ADMIN') or hasRole('MANAGER') or hasRole('SUPERVISOR') or hasRole('IC') or hasRole('OPS')" />
<intercept-url pattern="/target/**" access="hasRole('ADMIN') or hasRole('MANAGER') or hasRole('SUPERVISOR') or hasRole('IC')" />
<intercept-url pattern="/trawling/**" access="hasRole('ADMIN') or hasRole('MANAGER') or hasRole('SUPERVISOR')" />
<intercept-url pattern="/**" access="denyAll" />
<sec:custom-filter ref="customAuthenticationFilter"
before="PRE_AUTH_FILTER" />
<sec:csrf disabled="true" />
</sec:http>
<sec:authentication-manager alias="authenticationManager">
<authentication-provider ref="customAuthenticationProvider" />
</sec:authentication-manager>
<beans:bean id="customAuthenticationFilter"
class="com.test.common.CustomAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="authenticationSuccessHandler"
ref="customSuccessHandler" />
</beans:bean>
<beans:bean id="customSuccessHandler" class="com.test.common.CustomSuccessHandler" />
</beans:beans>
/**EDITED **/
I missed out this portion of code for CustomAuthenticationFilter class:
#Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
{
String header = request.getHeader(this.tokenHeader);
if (request.getServletPath().contains(".xhtml"))
{
header = (String) request.getSession().getAttribute("token");
}
if (header == null || !header.startsWith(PropertiesUtil.TOKEN_HEADER))
{
throw new JwtTokenMissingException(msgProperty.getProperty(MessageUtil.ERR_AUTH_NO_TOKEN));
}
String authToken = header.substring(PropertiesUtil.TOKEN_HEADER.length());
JwtAuthenticationToken authRequest = new JwtAuthenticationToken(authToken);
return getAuthenticationManager().authenticate(authRequest);
}
permitAll means that any authentication, even AnonymousAuthenticationToken is allowed, however your request never makes it that far. You have a custom filter, I assume it is derived from AbstractAuthenticationProcessingFilter, and since the filter throws an exception when the header is missing, you request never makes it to the AuthenticationManager!
There are several ways to solve this, here are two.
Create another filterchain <sec:http...> for endpoints that do not require a token, and use AnonymousAuthenticationFilter for this filter chain.
Return AnonymousAuthenticationToken from your filter if the JWT header is missing.
Hope this helps.
In my application i want to have separate spring security implementation based on url patterns.
Eg. /rest/ ** will have its own authentication provider(basic auth) and
/web/ ** will have its own authentication provider(form login).
please find below configuration i have done
<?xml version="1.0"?>
<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.xsd">
<!-- config for rest services using basic auth-->
<http pattern="/rest/**">
<intercept-url pattern="/MyAppRestServices" access="permitAll" />
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<http-basic />
</http>
<!-- AUTHENTICATION MANAGER FOR CUSTOM AUTHENTICATION PROVIDER -->
<authentication-manager alias="authenticationManager">
<authentication-provider ref="customAuthenticationProvider" />
</authentication-manager>
<!-- config for web using form login-->
<http pattern="/web/**">
<intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')" />
<form-login/>
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="admin" password="nimda" authorities="ROLE_ADMIN" />
</user-service>
</authentication-provider>
</authentication-manager>
In above config first config is working fine ie restservice with basic auth but web with form login config is not working. its not even intercepting the url ?
Please let me know whats wrong with above config ?
Kindly refer below working configuration for web authentication::
<?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.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<http pattern="/css/**" security="none" />
<http pattern="/images/**" security="none" />
<http pattern="/js/**" security="none" />
<http auto-config="false" authentication-manager-ref="dev" use-expressions="true" disable-url-rewriting="true">
<intercept-url pattern="/admin/login" access="permitAll" />
<intercept-url pattern="/admin/*" access="isAuthenticated()" />
<form-login
login-page="/admin/login"
default-target-url="/admin/workbench"
username-parameter="username"
password-parameter="password"
authentication-failure-url="/admin/login"
/>
<logout logout-success-url="/admin/login" logout-url="/j_spring_security_logout" invalidate-session="true" delete-cookies="JSESSIONID" />
</http>
<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
<!-- STATIC USER -->
<authentication-manager id="dev" alias="authenticationManager">
<authentication-provider>
<user-service>
<user name="abc" password="pwd" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
I have following spring security configuration, How do i change to it login to work based on http GET instead of POST, so that login url will be something like:
*http://localhost/myapp/j_security_check?j_username=test&j_password=test*
This is my configuration xml file
<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.1.xsd">
<http access-denied-page="/WEB-INF/pages/accessdenied.jsp" auto-config="true" use-expressions="true">
<intercept-url pattern="/admin" access="hasRole('ROLE_ADMIN')" method="GET"/>
<intercept-url pattern="/user" access="hasRole('ROLE_USER')"/>
<form-login
always-use-default-target="true"
authentication-failure-url="/loginfailed"
default-target-url="/landing"
login-page="/login" />
<logout
invalidate-session="true"
logout-success-url="/login?logout" />
<form-login
login-page="/login"
default-target-url="/welcome"
authentication-failure-url="/login?error"
username-parameter="username"
password-parameter="password" />
<logout logout-success-url="/login?logout" /> -->
</http>
<beans:bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsService" ></beans:property>
</beans:bean>
<beans:bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager" >
<beans:property name="providers">
<beans:list>
<beans:ref local="daoAuthenticationProvider"/>
</beans:list>
</beans:property>
</beans:bean>
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService">
</authentication-provider>
</authentication-manager>'
</beans:beans>
For more information, If you want to send your form with method post through spring security. You need to add this token to your form.
<input type="hidden" name="${_csrf.parameterName}"
value="${_csrf.token}" />
I have implemented spring security for login to my web portal. It works fine except for one issue. I have set session timeout to 5 min. Once timeout happpens and then user click any URL, it gets redirected to logout page.
But when user re autheticates, user directly lands on the last access page instead of home page which is default target URL.
Spring security file is as below:
<?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.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<http auto-config="true">
<intercept-url pattern="/index.jsp" access="ROLE_ADMIN,ROLE_USER" />
<intercept-url pattern="/home.html" access="ROLE_ADMIN,ROLE_USER" />
<intercept-url pattern="/mdm/accessToken.html" access="ROLE_USER" />
<intercept-url pattern="/mdm/enroll.html" access="ROLE_USER" />
<intercept-url pattern="/mdm/installApp.html" access="ROLE_USER" />
<intercept-url pattern="/mdm/checkStatus.html" access="ROLE_USER" />
<intercept-url pattern="/mdm/searchDevice.html" access="ROLE_USER" />
<intercept-url pattern="/admin/*" access="ROLE_ADMIN" />
<intercept-url pattern="/account/*" access="ROLE_ADMIN" />
<intercept-url pattern="/user/*" access="ROLE_USER" />
<form-login login-page="/login.html" default-target-url="/home.html"
authentication-failure-url="/loginfailed.html" />
<logout logout-url="/logout.html" logout-success-url="/logoutSuccess.html" invalidate-session="true" />
<anonymous username="guest" granted-authority="ROLE_GUEST" />
<session-management>
<concurrency-control max-sessions="1" />
</session-management>
<session-management invalid-session-url="/logout.html" />
</http>
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select USER as username, password, 'true' as enabled from TBL_USER_MASTER where user=?"
authorities-by-username-query="select um.USER as username , rm.ROLE_NAME as authorities from TBL_USER_MASTER um,TBL_ROLE_MASTER rm
where um.USER=? and um.role_id=rm.role_id" />
<password-encoder hash="md5"/>
</authentication-provider>
</authentication-manager>
</beans:beans>
Add the always-use-default-target attribute to your form-login tag.
<form-login always-use-default-target="true" />
If set to true, the user will always start at the value given by default-target-url, regardless of how they arrived at the login page. Maps to the alwaysUseDefaultTargetUrl property of UsernamePasswordAuthenticationFilter. Default value is false.
In Grails, this setting solves the problem in Config.groovy
grails.plugin.springsecurity.successHandler.alwaysUseDefault = true