简体   繁体   中英

Spring mvc / security : excluding the login page from spring security

I am using spring mvc + security to build a simple web app and currently having issues with the login. I am not able to exclude the login page from the spring security if i want to secure /** (everything basically). This is how my config look like:

spring.security.xml

    <http pattern="/login" security="none"/>
    <http pattern="/view_register.htm" security="none"/>
    <http>
        <intercept-url pattern="/**" access="ROLE_USER" />
        <form-login login-page="/login" default-target-url="/game" authentication-failure-url="/failedlogin" />
        <logout logout-success-url="/login" />
</http>

LoginController

@Controller
public class LoginLogoutController {

  @RequestMapping(value="/login", method = RequestMethod.GET)
  public String login(ModelMap model) {

    return "login";
  }

  @RequestMapping(value="/failedlogin", method = RequestMethod.GET)
  public String loginerror(ModelMap model) {

    model.addAttribute("error", "true");
    return "login";
  }

}

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>Login Page</title>
<style>
.errorblock {
    color: #ff0000;
    background-color: #ffEEEE;
    border: 3px solid #ff0000;
    padding: 8px;
    margin: 16px;
}
</style>
</head>
<body onload='document.f.j_username.focus();'>
    <h3>Login with Username and Password (Custom Page)</h3>

    <c:if test="${not empty error}">
        <div class="errorblock">
            Your login attempt was not successful, try again.<br /> Caused :
            ${sessionScope["SPRING_SECURITY_LAST_EXCEPTION"].message}
        </div>
    </c:if>

    <form name='f' action="<c:url value='j_spring_security_check' />"
        method='POST'>

        <table>
            <tr>
                <td>User:</td>
                <td><input type='text' name='j_username' value=''>
                </td>
            </tr>
            <tr>
                <td>Password:</td>
                <td><input type='password' name='j_password' />
                </td>
            </tr>
            <tr>
                <td colspan='2'><input name="submit" type="submit"
                    value="submit" />
                </td>
            </tr>
            <tr>
                <td>Don't have an account yet.</td>
                <td> <a href="<c:url value="view_register.htm" />" > Register here</a>
                </td>
            </tr>
        </table>

    </form>
</body>
</html>

I want to secure the whole app and exlude the login and the registration page. With my current config the whole security behaves very strangly. If i enter wrong credentials the

 @RequestMapping(value="/login", method = RequestMethod.GET)
  public String login(ModelMap model) {

is called and from the other hand if i enter the correct username/pass the login failed controller method is called.

Found out that if i modify the

 <intercept-url pattern="/**" access="ROLE_USER" />

to

<intercept-url pattern="/game*" access="ROLE_USER" />

and remove the

<http pattern="/login" security="none"/>

everything is working as expected. Its very strange and can't really figure out why this is happening.

EDIT

Just created a tiny version of my sample project (maven) and uploaded to: fileswap . Any help or suggestion will be really cool as i am still confused.

Try to insert these lines:

<intercept-url pattern="/login/**" access="ROLE_ANONYMOUS,ROLE_USER" />
<intercept-url pattern="/failedlogin/**" access="ROLE_ANONYMOUS,ROLE_USER" />
<intercept-url pattern="/view_register/**" access="ROLE_ANONYMOUS,ROLE_USER" />

after <http> , and add auto-config="true" inside <http> :

<http auto-config="true">

    <intercept-url pattern="/login/**" access="ROLE_ANONYMOUS,ROLE_USER" />
    <intercept-url pattern="/failedlogin/**" access="ROLE_ANONYMOUS,ROLE_USER" />
    <intercept-url pattern="/view_register/**" access="ROLE_ANONYMOUS,ROLE_USER" />

    <intercept-url pattern="/**" access="ROLE_USER" />

    <form-login login-page="/login" default-target-url="/game" authentication-failure-url="/failedlogin" />
    <logout logout-success-url="/login" />
</http>

and remove:

<http pattern="/login" security="none"/>

I do not know what this line is for, but it should work without it.

See the Spring Security Reference for details on anonymous authentication (the important thing to understand is that if an anonymous user can access a page, it does not automatically mean that an authenticated user can access it too).

BWT, ROLE_ANONYMOUS is a built-in role, but ROLE_USER is not, as explained here . You need to make sure ROLE_USER is assigned to the user.

This answer explains why patterns should end with /** .

Try using this configuration which allows anonymous access to these urls:

<http>
        <intercept-url pattern="/**" access="ROLE_USER" />
        <intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
        <intercept-url pattern="/view_register.htm" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
        <form-login login-page="/login" default-target-url="/game" authentication-failure-url="/failedlogin" />
        <logout logout-success-url="/login" />
</http>

When you specify the following:

<intercept-url pattern="/game*" access="ROLE_USER" />

Only URLs like ~/game* will be protected, leaving all other URLs unprotected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM