Announcement Announcement Module
No announcement yet.
Converting remember me user to fully authenticated by re-entering password Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Converting remember me user to fully authenticated by re-entering password


    I've just started using Spring Security (3.1.1) in a web app with form based login and so far so good.
    I now need to convert a remember me user to a fully authenticated user (by asking them to re-enter their password). They should then be re-directed to the page requiring full authentication.
    It seems like something that would not be uncommon but I couldn't see anything in the forums on this.
    The default behaviour of the ExceptionTranslationFilter is to throw an AccessDeniedException if a remember me user tries to access a resource requiring full authentication.
    I can easily implement an AccessDeniedHandler and forward them to the existing login page but I'd like to use a separate login page where they just need to enter a password. In addition, the ExceptionTranslationFilter doesn't save the request in the request cache as it does for AuthenticationException or AccessDeniedException (anonymous user) so they can't be automatically re-directed following the login.
    Is there a standard way to do this or any ideas for the best way?

    Thanks for any help!

  • #2
    I suggest the reference guide. Use the expressions/roles to check is one is fully authenticated if not then a different exception should be thrown by the implementation and the ExceptionTranslationFilter will pick it up and send the user to the login page.


    • #3
      Thanks for the quick reply!

      Yes - I'm trying to find something helpful for this scenario in the reference guide.

      I can use the expressions/roles to check if they are fully authenticated but I wasn't sure where do you suggest I do this.
      I was doing it in the AccessDeniedHandler but I think it is too late here for what I am after - I've missed the saving of the request and invocation of the entry point etc. that is done within ExceptionTranslationFilter (the sendStartAuthentication method).

      I believe that the exception would need to be a subclass of AuthenticationException to be picked up by the (private) ExceptionTranslationException.handleSpringSecurity Exception method and trigger the saving of the request etc. But where would I do this? In a new DecisionManager? The current behaviour is that the AffirmativeBased decision manager throws the AccessDeniedException when checking the "fullyAuthenticated" requirement.

      Thanks for you help and any clarification.


      • #4
        You don't have to modify/extend any classes (as suggested read the reference guide) you simply CONFIGURE something nothing more/nothing less. Simply add it to your access part of the url stuff (which probably is now only based on role and should include the isFullyAuthenticated).

        Below is without expressions, somethinig along this lines should be enough.
          <security:intercept-url access="IS_AUTHENTICATED_FULLY,ROLE_USER" />


        • #5

          Yes - I've read the reference guide. And I understand configuration etc. I already have access for the relevant URLs set as "fullyAuthenticated" (I'm using expressions).
          I'm not sure you understood my original post. I have a user who returns to the site who has the remember me cookie. He is fine on the site (and on any URL which has "authenticated" access). However, when he goes to a URL with "fullyAuthenticated" access the framework will throw an AccessDeniedException and forward to the AccessDeniedHandler (or HTTP 403 by default).

          Rather than this behaviour what I am after is another login form where he can enter a password to "upgrade" from "authenticated" to "fullyAuthenticated" and automatically be forwarded to the URL protected with "fullyAuthenticate" access.

          I.e. a way to "configure" Spring Security to enable this.


          • #6
            I understand what you want but you haven't provided all the information... So post your configuration...


            • #7
              Managing to get to close to what I'm after with the configuration I've pasted below. I needed to include 2 http tags to enable the 2 different login pages (normal login and a re-authentication log-in), and I needed to add a custom decision manager for the secure pages (needing fullyAuthenticated access) that would throw an InsufficientAuthenticationException if the voter denied access but was a remember me user.

              <http pattern="/secure*" use-expressions="true" access-decision-manager-ref="myDecisionManager">  
                      <intercept-url pattern="/secure*" access="fullyAuthenticated"/>
                      <form-login login-page="/reauthenticate" 
                                  login-processing-url="/j_reauthenticate" />
              <beans:bean class="test.decisionmanager.MyAccessDecisionManager" id="myDecisionManager">
                    <beans:property name="decisionVoters">
                               <beans:ref bean="webExpressionVoter"/>
              <beans:bean class="" id="webExpressionVoter"/>
              <http use-expressions="true">
                       <intercept-url pattern="/login*" access="permitAll"/>
                      <intercept-url pattern="/logout*" access="authenticated"/>
                      <intercept-url pattern="/profile*" access="authenticated"/>
                      <intercept-url pattern="/*"/>
                      <form-login login-page="/login"  default-target-url="/profile"  authentication-failure-url="/loginfailed" />
                      <logout invalidate-session="true" logout-url="/logout" logout-success-url="/loggedout" />
              <authentication-manager> ....
              The MyDecisionManager is identical to the default AffirmativeBased except for the chunk of code below. It means that the InsufficientAuthenticationException is thrown and thus the ExceptionTranslationFilter will store the request and re-direct to the re-authenticate login without any changes;

              if (deny > 0) {
                          // CHANGED HERE - ADDED isRememberMe CHECK AND NEW EXCEPTION
                          if (authenticationTrustResolver.isRememberMe(authentication)) {
                              throw new InsufficientAuthenticationException("Full authentication is required to access this resource");
                          } else {
                              throw new AccessDeniedException(messages.getMessage("AbstractAccessDecisionManager.accessDenied",
                                  "Access is denied"));
              Last edited by spilledBeverage; Aug 22nd, 2012, 03:53 AM. Reason: Code formatting