【问题标题】:The app don´t work well with spring-security该应用程序不适用于 spring-security
【发布时间】:2013-05-27 22:41:58
【问题描述】:

我请求使用 spring 和 spring-security 框架。为了学习,我正在开发一个应用程序。 到目前为止,我已经开发了没有 spring-security 的应用程序,以通过登录表单向用户验证。当用户介绍您的用户名和密码时,我的应用程序会转到控制器,使用“post”方法,在那里我验证您的 id(用户名和密码),我使用 Validator 类

现在我已经介绍了 spring-security 以获得更高的安全性,但是当用户介绍您的 ids(用户名和密码)时,如果没有重定向到方法获取,应用程序永远不会重定向到控制器的方法 post

接下来是源代码

表单的jsp文件为:

...
<form:form name="f" commandName="usuario" action="j_spring_security_check" method="POST" >
    <table align="center">
        <tr>
                <td><form:errors path="errorUsuario" cssClass="error"/></td>
            </tr>
    </table>
    <table border="0" cellpadding="2" cellspacing="3">
    <tbody>
             <tr>
                    <td><span id="letra">Usuario</span></td>
                    <td><form:input path="nombreUsuario" name='j_username' id="fondo-gris"/></td>
                 <td><form:errors path="nombreUsuario" cssClass="error"/></td>
        </tr>
        <tr>
                  <td><span id="letra">Password</span></td>
                  <td><form:password path="clave" name='j_password' id="fondo-gris"/></td>
               <td><form:errors path="clave" cssClass="error"/></td>
        </tr>
        <tr>   
                   <td colspan="3"><center><input id="botonInciar" type="submit" name="guardar" value="Iniciar Sesión"/></center></td>
        </tr>
    </tbody>
    </table>
</form:form>
...

这个页面的控制器是:

...
@RequestMapping(value = "/index", method = RequestMethod.GET)
    public String login(Model modelo) throws Exception {

        logger.info("LogginController --> login: ha entrado en el método GET");

        Usuario usuario = new Usuario();

        modelo.addAttribute("usuario", usuario);

        logger.info("LogginController --> login: los resultados del usuario son, userName: " + usuario.getNombreUsuario());

        return "index";
    }

    /**
     * Recoge los parámetros y redireccionamos donde necesitamos
     * @param usuario El usuario que intenta acceder al sistema
     * @param result Resultado del acceso
     * @param status Estado de lasesión
     * @return Retornamos la redirección a la página donde debe de ir tras la validación
     */
   @RequestMapping(value = "/index", method = RequestMethod.POST)
   public String processSubmitLogin(@ModelAttribute("usuario") Usuario usuario, BindingResult result, SessionStatus status) {

    logger.info("LogginController --> processSubmitLogin: ha entrado en el método POST");

    UsuarioLoggin ul = new UsuarioLoggin(usuario, usuarioService);
    new LogginValidator().validate(ul, result);

        if (result.hasErrors()) {
            return "index";
        } else {
            status.setComplete();
            return "redirect:/ok.htm";
        }
    }
...

spring-security的配置文件为:securityApplicationContext.xml:

...
<security:http auto-config="true" use-expressions="true">
        <security:intercept-url pattern="/index" access="permitAll"/>
        <security:intercept-url pattern="/*" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')"/>
        <security:form-login login-page="/index"/>
    </security:http>

    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider>
            <security:jdbc-user-service data-source-ref="dataSource"/>
        </security:authentication-provider>
    </security:authentication-manager>
...

PS:测试和测试..我看到如果删除了jsp文件的标签:“j_spring_security_check”,应用程序发现到现在,但是如果我在用户推送数据时离开它,应用程序一直在控制器的“get”方法中

谢谢。

【问题讨论】:

    标签: spring spring-mvc spring-security


    【解决方案1】:

    Spring Security 引入了一组过滤器来拦截某些请求。默认情况下,Spring Security 会拦截j_spring_security_check 的请求并为你处理认证。

    因此,您将永远不会看到 Spring MVC 处理您所期望的 POST 请求,原因如下:

    1. 你永远不会POSTing 到/index - 从我上面看到的,用户将GET /index 并将表单提交给j_spring_security_check。从来没有POST/index
    2. 您永远不想让 Spring MVC 处理身份验证请求 - 这是使用安全框架的好处;您的 MVC 代码不必处理身份验证或授权。

    您需要执行以下操作,而不是上面的代码:

    1. 从您的 MVC 代码中删除 processSubmitLogin() 方法,因为它不再需要。
    2. 将来自 processSubmitLogin() 的任何自定义处理添加到您的 Spring Security 配置中,以获得相同的用户体验。

    processSubmitLogin() 做了 3 件事:实际验证用户身份(现在通过 Spring Security 完成),在发生错误时转发到 index,并在成功时重定向到 ok.htm。最后两个在 Spring Security 中配置如下:

    <security:http auto-config="true" use-expressions="true">
        ...
        <security:form-login 
            login-page="/index"
            authentication-failure-url="index"
            default-target-url="/ok.htm"
            always-use-default-target="true"/>
    </security:http>
    

    使用 Spring Security 时,上述配置应与您的自定义登录页面匹配。有关上述内容的更多信息,请参阅form-login namespace

    【讨论】:

      【解决方案2】:

      感谢您回答我。 我不明白你写给我的一切,也就是说,当你说: 1. 从 MVC 代码中删除 processSubmitLogin() 方法,因为它不再需要。你指的是什么?与此类似:

      新建jsp文件

       ... 
         <form name="f" action="j_spring_security_check" method="post" >
             <table border="0" cellpadding="2" cellspacing="3">
                <tbody>
                   <tr>
                  <td><span id="letra">Usuario</span></td>
                  <td><input type="text" name="j_username" id="fondo-gris"/></td>
                   </tr>
                   <tr>
                  <td><span id="letra">Password</span></td>
                  <td><input type="password" name="j_password" id="fondo-gris"/></td>
                   </tr>
                   <tr>   
                  <td colspan="3"><center><input id="botonInciar" type="submit" name="guardar" value="Iniciar Sesión"/></center></td>
               </tr>
                </tbody>
              </table>
           </form>
      ...
      

      新控制器.java

      /**
           * Método que sirve para visualizar la página principal de la aplicación
           * @param modelo
           * @return Un String con el nombre de la página
           * @throws Exception
           */
          @RequestMapping(value = "/index", method = RequestMethod.GET)
          //@RequestMapping(method = RequestMethod.GET)
          public String login(Model modelo) throws Exception {
              //modelo.addAttribute("tituloUsuario", "Listado de Usuarios");
      
              logger.info("LogginController --> login: ha entrado en el método GET");
      
              Usuario usuario = new Usuario();
      
              modelo.addAttribute("usuario", usuario);
      
              logger.info("LogginController --> login: los resultados del usuario son, userName: " + usuario.getNombreUsuario());
      
              //return "/principal/loguear";
              return "index";
          }
      

      新的spring-security:securityApplicationContext.xml:

      <security:http auto-config="true" use-expressions="true">
              <security:intercept-url pattern="/index" access="permitAll"/>
              <security:intercept-url pattern="/*" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')"/>
              <security:form-login login-page="/index"
                                   default-target-url="/principal/usuarios/form.htm"
                                   always-use-default-target="true"
                                   authentication-failure-url="/index"/>
      
          </security:http>
      
          <security:authentication-manager alias="authenticationManager">
              <security:authentication-provider>
                  <security:jdbc-user-service data-source-ref="dataSource"/>
              </security:authentication-provider>
          </security:authentication-manager>
      

      如果我这样做,当用户输入错误的数据时,浏览器不会显示信息,即不正确的用户名/密码组合

      数据如何在浏览器中显示?

      谢谢

      【讨论】:

        猜你喜欢
        • 2019-07-12
        • 2018-03-16
        • 2017-10-30
        • 2021-03-25
        • 2015-11-03
        • 2015-10-02
        • 1970-01-01
        • 2014-11-29
        • 2020-12-02
        相关资源
        最近更新 更多