web-dev-qa-db-fra.com

Spring Security Access refusé après le post 403

J'ai presque tout essayé dans les autres articles à ce sujet, rien n'est lié à mon problème.

Si j'essaie de récupérer mon URL via GET (ex: chemin/utilisateurs/edit/1), tout fonctionne correctement et je suis redirigé vers la page de modification de l'utilisateur, mais si j'essaie d'accéder à cette page via POST, la sécurité de Spring refuse mon accès. à la page.

Les deux méthodes sont mappées dans ma classe de contrôleur.

@RequestMapping(value="/users/edit/{id}", method={RequestMethod.POST,RequestMethod.GET})
public ModelAndView login(ModelAndView model, @PathVariable("id") int id ) {
    model.addObject("user", this.userService.getUserById(id));
    model.setViewName("/users/add"); //add.jsp
    return model;
}

Mon formulaire que j'utilise après

<f:form method="post" action="/users/edit/${user.id}">
     <button type="submit">Edit</button>
</f:form>

Printemps security.xml

<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.2.xsd">

<!-- enable use-expressions -->
<http auto-config="true" use-expressions="true">
    <intercept-url pattern="/secure**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" />
    <intercept-url pattern="/secure/users**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" />

    <!-- access denied page -->
    <access-denied-handler error-page="/denied" />
    <form-login 
        login-page="/home" 
        default-target-url="/secure" 
        authentication-failure-url="/home?error" 
        username-parameter="inputEmail"
        password-parameter="inputPassword" />
    <logout logout-success-url="/home?logout"  />
    <!-- enable csrf protection -->
    <csrf/>
</http>

<!-- Select users and user_roles from database -->
<authentication-manager>
    <authentication-provider>
        <password-encoder hash="md5" /> 
        <jdbc-user-service data-source-ref="dataSource"
            users-by-username-query=
            "SELECT login, senha, ativo
               FROM usuarios 
              WHERE login = ?"
            authorities-by-username-query=
            "SELECT u.login, r.role
               FROM usuarios_roles r, usuarios u
              WHERE u.id = r.usuario_id
                AND u.login = ?" />
    </authentication-provider>
</authentication-manager>
10
Lucas Freitas

J'ai remarqué que vous utilisiez la protection csrf, qui protège par défaut tout verbe HTTP modifiant une ressource (par exemple, PUT, POST, DELETE, ...). Si vous utilisez la balise de formulaire de Spring, un jeton csrf doit être automatiquement inclus en tant qu'entrée masquée dans votre formulaire. Vous devriez vérifier la source dans votre navigateur pour vérifier que le jeton csrf est là, sinon vous aurez besoin de quelque chose comme ceci:

<input type="hidden"
    name="${_csrf.parameterName}"
    value="${_csrf.token}"/> 

Vous pouvez en savoir plus sur csrf protection/configuration in Référence de printemps.

17
ikumen

Vous pouvez simplement utiliser la balise <sec:csrfInput/> comme suit:

    <f:form method="post" action="/users/edit/${user.id}">
        <button type="submit">Edit</button>
        <sec:csrfInput/>
    </f:form>

Et s'il vous plaît assurez-vous d'importer des étiquettes de sécurité de printemps

<%@ taglib uri="http://www.springframework.org/security/tags" prefix="sec" %>
0
Ahmad Al-Kurdi