403 - Access is denied after authenticating - spring-security

Greetings!
When I try authenticating against my existing db I'm getting authenticated but I get the 403 page. If I just tried a wrong password I get 'wrong credentials' message as expected.
I tried authenticating per sample app included with SpringSecurity and that worked fine.
security-context.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-2.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-2.0.1.xsd">
<global-method-security secured-annotations="enabled"></global-method-security>
<http auto-config="true" >
<intercept-url pattern="/admin/**" access="ROLE_TEST" />
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<form-login
login-page="/login/index.jsp"
default-target-url="/admin/test.jsp"
authentication-failure-url="/login/index.jsp?login_error=1" />
</http>
<authentication-provider user-service-ref="jdbcUserService">
<password-encoder ref="passwordEncoder">
<salt-source system-wide="n103df"/>
</password-encoder>
</authentication-provider>
<beans:bean id="jdbcUserService" class="org.springframework.security.userdetails.jdbc.JdbcDaoImpl">
<beans:property name="rolePrefix" value="" />
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="enableAuthorities" value="true"/>
<beans:property name="enableGroups" value="false"/>
<beans:property name="authoritiesByUsernameQuery" value="SELECT username,authority FROM authorities WHERE username = ?" />
<beans:property name="usersByUsernameQuery" value="SELECT username,password,enabled as enabled FROM users WHERE username = ?" />
<beans:property name="groupAuthoritiesByUsernameQuery" value="" />
</beans:bean>
<beans:bean id="passwordEncoder" class="org.springframework.security.providers.encoding.Md5PasswordEncoder"/>
Will appreciate any help :-)
Thanks in advance!

If you are getting a 403 code, it means that the user does not have the required roles. So, athentication is not the problem, is authorization.
The only way to know what is going on is to put logging level to debug, there should be more info. Post it here.
Does your roles have the 'ROLE_' prefix?

... figured it out. Despite having ROLE_TEST specified in the config file and the same in the 'authority' column of the db, Spring-Sec was expecting ROLE_SUPERVISOR:
[DEBUG,AbstractSecurityInterceptor,http-8084-7] Secure object: FilterInvocation: URL: /admin/test.jsp; ConfigAttributes: [ROLE_TEST]
[DEBUG,AbstractSecurityInterceptor,http-8084-7] Previously Authenticated: org.springframework.security.providers.UsernamePasswordAuthenticationToken#af840ed7: Principal: org.springframework.security.userdetails.User#3ec100: Username: testUser; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_SUPERVISOR; Password: [PROTECTED]; Authenticated: true; Details: org.springframework.security.ui.WebAuthenticationDetails#1c07a: RemoteIpAddress: 127.0.0.1; SessionId: 350B260FAFDDBF04D5CB4AAAB7B8A441; Granted Authorities: ROLE_SUPERVISOR
[DEBUG,ExceptionTranslationFilter,http-8084-7] Access is denied (user is not anonymous); delegating to AccessDeniedHandler
org.springframework.security.AccessDeniedException: Access is denied
at org.springframework.security.vote.AffirmativeBased.decide(AffirmativeBased.java:68)
... now I'm curious, how come?
So after changing ROLE_TEST to ROLE_SUPERVISOR in the config file all worked as expected.

Related

jdbc is not working in spring security

I am developing a simple struts2 login using spring security
and everything working properly.But when i use jdbc to load users and their corresponding roles,it always showing my custom invalid user page.There is no error showing and i dont know what is wrong.
My applicationcontext-security.xml
<global-method-security secured-annotations="enabled" />
<http auto-config="true">
<intercept-url pattern="/admin.action" access="ROLE_ADMIN" />
<intercept-url pattern="/user" access="ROLE_USER" />
<access-denied-handler error-page="/WEB-INF/Content/403.jsp" />
<form-login login-page="/WEB-INF/Content/login.jsp"
default-target-url="/admin.action"
always-use-default-target="true"
authentication-failure-url="/login.action?error=true"
/>
<logout logout-url="/login.action?logout=1" />
</http>
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select username,password from users where username=?"
authorities-by-username-query="select u.username, ur.authority from users u, user_roles ur where u.username = ur.username and u.username=?"
/>
</authentication-provider>
</authentication-manager>
my dataAccessContext.xml is
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/Boban"/>
<property name="username" value="root"/>
<property name="password" value="veradis"/>
</bean>
When i directly give user,password and authority it works.I searched a lot in google and found similar errors,but nothing works.I Checked the sql query and it works perfectly.I am stuck with this program.Any help will be greatly appreciated.
I believe that the query for login missing one field enabled
Try something like this:
"select username,password, enabled from users where username=?"

Spring Rest Authentication with a response

I have setup a security context meant for REST. The configuration is as
<!-- authentication manager and password hashing -->
<authentication-manager alias="authenticationManager">
<authentication-provider ref="daoAuthenticationProvider" />
</authentication-manager>
<beans:bean id="daoAuthenticationProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsService" />
<beans:property name="passwordEncoder" ref="passwordEncoder" />
</beans:bean>
<beans:bean id="userDetailsService" name="userAuthenticationProvider"
class="com.myapp.auth.AuthenticationUserDetailsGetter" />
<beans:bean id="passwordEncoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
</beans:bean>
<global-method-security pre-post-annotations="enabled" />
<!-- web services -->
<http use-expressions="true" pattern="/rest/**"
disable-url-rewriting="true" entry-point-ref="restAuthenticationEntryPoint">
<custom-filter ref="restProcessingFilter" position="FORM_LOGIN_FILTER" />
<intercept-url pattern="/rest/login" access="permitAll"/>
<intercept-url pattern="/rest/**" access="isAuthenticated()" />
<logout delete-cookies="JSESSIONID" />
</http>
<beans:bean id="restProcessingFilter" class="com.myapp.auth.RestUsernamePasswordAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="filterProcessesUrl" value="/rest/login" />
</beans:bean>
And I overrided the UsernamePasswordAuthenticationFilter as
#Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) {
Authentication authentication = null;
String username = request.getParameter("j_username");
String password = request.getParameter("j_password");
boolean valid = authService.authenticate(username, password);
if (valid) {
User user = updateLocalUserInfo(username);
authentication = new UsernamePasswordAuthenticationToken(user,
null, AuthorityUtils.createAuthorityList("USER"));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
return authentication;
}
The above authentication is working fine when I tried it with
RestClient restClient = new RestClient();
String result = restClient.login("hq", "a1234567"); // RestTemplate.postForObject
The only thing left is the result from the authentication post (atm, result is null). How can I configure my security configuration in order to retrieve some result ? A flag or session ID will suffice.
I think best bet here would be AuthenticationSuccessHandler.
As this will only kick in if the authentication was successful.
You can generate some sort of UUID and set that in your response directly. I have used very similar approach for ReST Auth and have not hit any problems yet.
For detailed implementation guide please refer : https://stackoverflow.com/a/23930186/876142
Update for comment #1 :
You can get response just like any normal ReST request.
This is how I am sending back my Token as JSON
String tokenJsonResponse = new ObjectMapper().writeValueAsString(authResponse);
httpResponse.addHeader("Content-Type", "application/json");
httpResponse.getWriter().print(tokenJsonResponse);
Assuming you know how to use RestTemplate, rest is trivial.

"Access is denied (user is not anonymous)" with spring-security-oauth2

I'm new to Spring Security and Oauth, and I'm trying to set up a simple example protecting the access to resources in path "/api" with Oauth2. I'm using spring-security-oauth2-1.0.0.RC2. After some time dealing with configuration, I'm able to get tokens, but when I try to send requests to "/api" resources, I'm facing two questions:
Initially, I'm sending authorization header with "OAuth2" prefix, but spring-security-oauth2 seems to need headers with "Bearer" prefix in the tokens to find them. What's the difference between these tokens?
After Spring validated the token, I'm getting a security error: "ExceptionTranslationFilter - Access is denied (user is not anonymous)" and I'm stuck with this problem. Since I'm using InMemory token store, I have to login each time to authorize client, then I'm getting this error. Here is the spring configuration:
<http pattern="/api/**" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager" xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false" />
<intercept-url pattern="/api/**" access="ROLE_CLIENT,SCOPE_READ" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<http disable-url-rewriting="true" xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/**" access="ROLE_USER" />
<!--intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" /-->
<form-login/>
<logout logout-success-url="/index.jsp" logout-url="/logout" />
</http>
<bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="O2Server" />
</bean>
<bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager" />
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased" xmlns="http://www.springframework.org/schema/beans">
<constructor-arg>
<list>
<bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
<bean class="org.springframework.security.access.vote.RoleVoter" />
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</list>
</constructor-arg>
</bean>
<authentication-manager id="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider>
<user-service>
<user name="test" password="test" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
<bean id="clientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails" />
</bean>
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore" />
<property name="supportRefreshToken" value="true" />
<property name="clientDetailsService" ref="clientDetails"/>
</bean>
<bean id="userApprovalHandler" class="org.o2server.security.O2ServerUserApprovalHandler">
<property name="tokenServices" ref="tokenServices" />
</bean>
<oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices" user-approval-handler-ref="userApprovalHandler">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<oauth:password />
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter" resource-id="O2Server" token-services-ref="tokenServices" />
<oauth:client-details-service id="clientDetails">
<oauth:client client-id="O2Client" resource-ids="O2Server" authorized-grant-types="authorization_code,refresh_token,implicit"
authorities="ROLE_CLIENT" scope="read,write" secret="secret" />
</oauth:client-details-service>
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
This is the log from the server:
11:58:30.366 [DEBUG] FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /api/user/; Attributes: [ROLE_CLIENT, SCOPE_READ]
11:58:30.366 [DEBUG] FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.oauth2.provider.OAuth2Authentication#48a94464: Principal: org.springframework.security.core.userdetails.User#346448: Username: paul; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails#43794494; Granted Authorities: ROLE_USER
11:58:30.366 [DEBUG] UnanimousBased - Voter: org.springframework.security.oauth2.provider.vote.ScopeVoter#4e857327, returned: 0
11:58:30.366 [DEBUG] UnanimousBased - Voter: org.springframework.security.access.vote.RoleVoter#1b4b2db7, returned: -1
11:58:30.367 [DEBUG] ExceptionTranslationFilter - Access is denied (user is not anonymous); delegating to AccessDeniedHandler <org.springframework.security.access.AccessDeniedException: Access is denied>org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.UnanimousBased.decide(UnanimousBased.java:90)
Please, could you give me some advice?
Thank you in advance.
I have never used oauth plugin but from reading debug output I can say that RoleVoter returned -1, which means access was denied by DecisionVoter. I see that you granted only ROLE_USER to principal which is trying to access url /api/user/, which is secured by [ROLE_CLIENT, SCOPE_READ] and that's the reason why access was denied.
Either grant ROLE_CLIENT and SCOPE_READ to principal or change <intercept-url pattern="/api/**" access="ROLE_CLIENT,SCOPE_READ" />.
As Xaerxess said, you should change your intercept-url access property to ROLE_USER.
<intercept-url pattern="/api/**" access="ROLE_CLIENT,SCOPE_READ" />
to
<intercept-url pattern="/api/**" access="ROLE_USER,SCOPE_READ" />
The access property controls the role of the user (which the client acts on behalf of).
The documentation of the authorities (ROLE_CLIENT) property of tag <oauth:client> states:
Authorities that are granted to the client (comma-separated). Distinct
from the authorities granted to the user on behalf of whom the client
is acting.
Also, according to user Dave Syer:
If you didn't change Tonr, it is not acting as a client, it is acting
on behalf of a user (who will not have the required ROLE_CLIENT), so
it is expected that you would get a 403. If you want to make an
assertion about the request from tonr being from a client with a
specific role (without changing the app) you can use an expression,
e.g. "oauthClientHasRole('ROLE_CLIENT') and hasScope('trust')".
Source:
http://forum.springsource.org/showthread.php?125468-confusing-between-ROLE_USER-ROLE_CLIENT

How to show logged in user details on non-secured JSP page after login via Spring Security and CAS?

I have a simple web app example. Some unsecured pages and some secured pages.
Login is via Spring Security and CAS. Application is mostly working OK - users get directed to CAS login page when requesting a secured resource, login works, and user gets redirected back to the secure page they requested. User will have various authentication properties - available to be checked with Spring Security taglib : http://www.springframework.org/security/tags - eg:
Authentication class :
class org.springframework.security.web.
authentication.preauth.PreAuthenticatedAuthenticationToken
Authentication authorities : [ROLE_ADMIN]
Authentication name : admin-user
Authentication authenticated : true
Authentication principal :
org.springframework.security.core.userdetails.User#bf0d4bda:
Username: admin-user;
Password: [PROTECTED];
Enabled: true;
AccountNonExpired: true;
credentialsNonExpired: true;
AccountNonLocked: true;
Granted Authorities: ROLE_ADMIN
However, once that logged-in user visits a non-secured page, then they appear to be seen as having none of these credentials. Instead, they are see as
Authentication class : class
org.springframework.security.authentication.AnonymousAuthenticationToken
Authentication authorities : [ROLE_ANONYMOUS]
Authentication name : anonymousUser
Authentication authenticated : true
Authentication principal : anonymousUser
So, this makes it impossible to use the security taglib to show or hide page items on the unsecured pages based on whether or not the user is logged in - eg, can't show a logout button if the user is already logged in:
<sec:authorize access="isAuthenticated()" >
<a href='<c:url value="/j_spring_security_logout" />'>logout</a>
</sec:authorize>
or show login button if not logged in:
<sec:authorize access="not isAuthenticated()" >
<a href='<c:url value="/secure/home" />'>login</a>
</sec:authorize>
Logged in user always shows as not authenticated in these pages even when logged in. So always sees the login button, and never the logout. When going back to a secured page, there is no problem. This is not fatal to my app - but the same principle makes it impossible for me to customise the non-secured pages with content only appropriate to logged in users (menus, messages, etc).
Is this normal behaviour with Spring Security + CAS? Or is there a way to make it work as you would expect? Perhaps I have misconfigured the filter chains?
One more thing - I have exeprimented with looking at SPRING_SECURITY_CONTEXT in the session. At first I thought this would work - this gets popluated with Granted Authorities = ROLE_ADMIN on the unsecured pages. So, I thought I could use that to detect if a user was logged in and had the correct authority. However, SPRING_SECURITY_CONTEXT does not get popluated on the very first secured page that gets loaded on the return from CAS - only on subsequent page loads.
You have to tell to the Spring session manager that there is actually a session for the user and that Spring has to maintain it.
<http use-expressions="true"
auto-config="true"
lowercase-comparisons="true"
disable-url-rewriting="true"
access-denied-page="/accessDenied.jsf"
entry-point-ref="casAuthenticationFilterEntryPoint">
[..]
<custom-filter ref="concurrencyFilter" position="CONCURRENT_SESSION_FILTER" />
<custom-filter ref="casAuthenticationFilter" position="CAS_FILTER" />
<logout invalidate-session="true"
logout-success-url="${cas.url}/logout?service=${local.url}/workspace/" />
</http>
That's a part of the security filter chain, that we implemented, the important is the concurrencyFilter that is defined below and the casAuthenticationFilter
<beans:bean id="casAuthenticationFilter"
class="org.springframework.security.cas.web.CasAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="authenticationSuccessHandler" ref="authenticationSuccessHandler" />
<beans:property name="authenticationFailureHandler" ref="authenticationFailureHandler" />
<beans:property name="sessionAuthenticationStrategy" ref="sas" />
</beans:bean>
<beans:bean id="sas"
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<beans:constructor-arg name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="migrateSessionAttributes" value="true" />
<beans:property name="exceptionIfMaximumExceeded" value="true" />
<beans:property name="alwaysCreateSession" value="true" />
<beans:property name="maximumSessions" value="20" />
</beans:bean>
<beans:bean id="sessionRegistry"
class="org.springframework.security.core.session.SessionRegistryImpl" />
<beans:bean id="concurrencyFilter"
class="org.springframework.security.web.session.ConcurrentSessionFilter">
<beans:property name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="expiredUrl" value="/sessionExpired.jsf" />
</beans:bean>
I hope that helps, and is complete. I've to leave now, but if you need more just ask

Simple Spring <remember-me/> ... help please

All I want, is a simple remember-me. I read http://static.springsource.org/spring-security/site/docs/3.0.x/reference/remember-me.html
What I have done so far:
Created my own UserDetailsService to work with Hibernate / JPA. My impl. does not consider any remember-me stuff
Considered configuration through appContext <security:remember-me key="89dqj219dn910lsAc12" user-service-ref="jpaUserDetailsService" token-validity-seconds="864000"/>
Checked, that the cookie SPRING_SECURITY_REMEMBER_ME_COOKIE is really set
Logged in to the secured site and it works
When I restart my browser, I keep getting an error:
org.springframework.security.access.AccessDeniedException: Access is denied
Authentication object as a String: org.springframework.security.authentication.RememberMeAuthenticationToken#9ab72a70: Principal: de.myapp.businessobjects.AppUser#61f68b18: Username: myad; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; PersonalInformation: 65537; ; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_USER
And here is my secContext.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:security="http://www.springframework.org/schema/security"
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:global-method-security pre-post-annotations="enabled">
</security:global-method-security>
<security:http use-expressions="true" access-denied-page="/accessDenied">
<security:form-login
login-page="/login"
login-processing-url="/loginProcess"
default-target-url="/intro"
authentication-failure-url="/login?login_error=1"
/>
<security:logout
logout-url="/logout"
logout-success-url="/logoutSuccess"/>
<security:intercept-url pattern="/**" access="permitAll"/>
<security:intercept-url pattern="/login" access="permitAll"/>
<security:intercept-url pattern="/styles/**" access="permitAll"/>
<security:intercept-url pattern="/scripts/**" access="permitAll"/>
<security:remember-me key="89dqj219dn910lsAc12" user-service-ref="jpaUserDetailsService"
token-validity-seconds="864000"/>
</security:http>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="jpaUserDetailsService">
<security:password-encoder hash="sha">
</security:password-encoder>
</security:authentication-provider>
</security:authentication-manager>
<bean id="rememberMeFilter" class=
"org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<property name="rememberMeServices" ref="rememberMeServices"/>
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
<bean id="rememberMeServices" class=
"org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="jpaUserDetailsService"/>
<property name="key" value="89dqj219dn910lsAc12"/>
</bean>
<bean id="rememberMeAuthenticationProvider" class=
"org.springframework.security.authentication.RememberMeAuthenticationProvider">
<property name="key" value="89dqj219dn910lsAc12"/>
</bean>
</beans>
and finally some debug trace
03:45:14.598 [7225609#qtp-10131947-7] DEBUG o.s.w.b.a.s.HandlerMethodInvoker - Invoking request handler method: public java.lang.String de.myapp.controller.bstController.showbstpage(java.lang.String,javax.servlet.http.HttpServletResponse)
03:45:14.598 [7225609#qtp-10131947-7] DEBUG o.s.s.a.i.a.MethodSecurityInterceptor - Secure object: ReflectiveMethodInvocation: public java.lang.String de.myapp.controller.bstController.showbstpage(java.lang.String,javax.servlet.http.HttpServletResponse); target is of class [de.myapp.controller.bstController]; Attributes: [[authorize: 'isFullyAuthenticated() and #username == principal.username', filter: 'null', filterTarget: 'null']]
03:45:14.598 [7225609#qtp-10131947-7] DEBUG o.s.s.a.i.a.MethodSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.RememberMeAuthenticationToken#9ab72a70: Principal: de.myapp.businessobjects.AppUser#61f68b18: Username: myad; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; PersonalInformation: 65537; ; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_USER
03:45:14.599 [7225609#qtp-10131947-7] DEBUG o.s.c.c.s.GenericConversionService - Converting value false of [TypeDescriptor java.lang.Boolean] to [TypeDescriptor java.lang.Boolean]
03:45:14.599 [7225609#qtp-10131947-7] TRACE o.s.c.c.s.GenericConversionService - Matched cached converter NO_OP
03:45:14.599 [7225609#qtp-10131947-7] DEBUG o.s.c.c.s.GenericConversionService - Converted to false
03:45:14.599 [7225609#qtp-10131947-7] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter#a866a9, returned: -1
03:45:14.599 [7225609#qtp-10131947-7] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.RoleVoter#1ebf305, returned: 0
03:45:14.599 [7225609#qtp-10131947-7] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.AuthenticatedVoter#19ffd6f, returned: 0
I really don't know where to continue debugging. What have I missed? Do I have to create my own implementation of remember-me?
I would really appreciate a working sample application that demonstrates the default implementation of springs remember-me...
-------- EDIT -----------
I have just compiled and run the remember-me reference app by springsecurity itself: the spring-security\samples\tutorial account app AND the contact app. Actually, I have exactly the same problem?!?. I have tried firefox, opera and ie ... I am shattered ...
It looks like remember-me authentication was working fine in your application, since you obtain a valid authentication token from the remember-me cookie.
However, the log output indicates that there is a method access control annotation on a controller method bstController.showbstpage which requires "full" authentication, from the expression isFullyAuthenticated() and #username == principal.username. Remember-me doesn't qualify as full authentication, hence the expression rejects the current authentication.
As an aside the intercept-url elements are wrongly ordered since /** is at the top and will be applied to all requests, making the others redundant.
Also, it wouldn't be possible to get the same issue with the sample applications, since they don't require full authentication for any operation, so you must have had some other issue there.
When you login, is the "password" field on your UserDetails object being set to non-null / non-empty value? In my application, the actual authentication is delegated off to another system and I don't store the user-submitted password on my UserDetails object. I couldn't get the RememberMe cookie to work until I set the password property to a value. In my case, I simply defaulted the property to the word "password" just so it wouldn't be null/empty string.
I don't know if that's anything like your scenario, but this drove me crazy until I figured it out.

Resources