javaGirl243
javaGirl243

Reputation: 99

Spring Security - logout and access control not working

So I have this in my spring config xml file.

<http auto-config="true" use-expressions="true">

    <intercept-url pattern="/welcome/*" access="hasRole('ADMIN')" />

    <!-- <intercept-url pattern="/login" requires-channel="https" /> -->

    <!-- access denied page -->
    <access-denied-handler error-page="/403" />

    <form-login login-page="/login" 
        default-target-url="/welcome"
        authentication-failure-url="/login?error" 
        username-parameter="emailId"
        password-parameter="pwd" />
    <logout logout-success-url="/login?logout"/>
</http>

The role is authenticated correctly at login. I have 2 questions:

  1. What's the difference between pattern="/welcome/*", pattern="/welcome*" and pattern="/welcome/**"? When the pattern="/welcome/*", the login is successful and the user sees the page. In both the other options, the 403 Access Denied page appears. The user does have 'ADMIN' privileges)
  2. How does Spring security process logout? I have the following code in my welcome.jsp file:

    <c:url value="/logout" var="logoutUrl" />
    <form action="${logoutUrl}" method="GET" id="logoutForm">
        <input type="hidden" name="${_csrf.parameterName}"
        value="${_csrf.token}" />
    </form>
    <script>
    function formSubmit() {
    document.getElementById("logoutForm").submit();
    }
    </script>
    
    <c:if test="${pageContext.request.userPrincipal.name != null}">
        <h2>
        User : ${pageContext.request.userPrincipal.name} | <a
        href="javascript:formSubmit()"> Logout</a>
        </h2>
    </c:if>
    

    and this in my controller:

    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public String logoutPage(HttpServletRequest request,     HttpServletResponse response) {
        Authentication auth =     SecurityContextHolder.getContext().getAuthentication();
        if (auth != null) {
            new SecurityContextLogoutHandler().logout(request, response, auth);
        }
        return "redirect:/login?logout";
    }
    

    The page redirects correctly and displays the "logout successful" page but if I change the URL to go to "/welcome" again, it shows me the page. Shouldn't it display the 403 - Access Denied page?

Upvotes: 0

Views: 702

Answers (1)

Yuri
Yuri

Reputation: 1814

About Ant Path matchers in Spring Security

The main role of using Ant-style syntax that you've mentioned is to resolve what exactly paths are valid.

The mapping matches URLs using the following rules:

  • ? matches one character
  • * matches zero or more characters
  • ** matches zero or more directories in a path

Regarding your cases:

  • /welcome/* - this could be valid for URLs like /welcome/hello or /welcome/#hello, /welcome/?abc=123
  • /welcome* - valid are /welcome?abc=123, /welcome#abc=123.
  • /welcome/** - valid case is /welcome/hello/bye?abc=123.

More on this could be found at Spring Documentation.

Logout action

I assume that you are using xml-configuration for security. Anyway this could be modified for usage of pure Java-configuration.

In app-security.xml should be something like this below:

<http use-expressions="true"
      disable-url-rewriting="true">

    <http-basic />

    <!-- other configurations -->

    <intercept-url pattern="/login**" access="isAnonymous()"/>
    <intercept-url pattern="/**" access="isAuthenticated()"/>

    <!-- other configurations -->
    <logout logout-url="/logout"
            logout-success-url="/login"/>
</http>

And somewhere in index.html file:

<a href="<c:url value="/logout" />" id="item-btn-logout">
    <i class="icon-off"></i> Logout
</a>

The most important part is URL: /logout.

Upvotes: 1

Related Questions