Java 如何使用SpringSecurity/SpringMVC处理表单登录

Java 如何使用SpringSecurity/SpringMVC处理表单登录,java,spring-mvc,spring-security,Java,Spring Mvc,Spring Security,简单的问题,我只需要一个指向正确方向的指针: 我有一个简单的SpringMVC/SpringSecurityWebApp。最初,我设置了Spring安全性,以便默认登录页面正确显示和验证(我使用DaoAuthenticationProvider实现了UserDetailsService) 下一步:用我的登录页面替换默认的spring登录页面,并发布凭证 但是我该如何处理提交的登录凭据呢?我假设我将表单发布到控制器,验证凭据,但我不清楚之后的正确步骤是什么。例如: 我正在调用Authentica

简单的问题,我只需要一个指向正确方向的指针:

我有一个简单的SpringMVC/SpringSecurityWebApp。最初,我设置了Spring安全性,以便默认登录页面正确显示和验证(我使用
DaoAuthenticationProvider
实现了
UserDetailsService

下一步:用我的登录页面替换默认的spring登录页面,并发布凭证

但是我该如何处理提交的登录凭据呢?我假设我将表单发布到控制器,验证凭据,但我不清楚之后的正确步骤是什么。例如:

  • 我正在调用AuthenticationManager的方法吗
  • 我需要为此定义一个bean吗
  • 我是否需要实现像AuthenticationEntryPoint之类的接口/服务

我已经把文档打了三遍了,但没有完全理解它们。我知道这非常简单,所以我只需要听听流程应该如何进行。

我们越来越少地讨论同一问题,让我们看看人们会怎么说。

Spring Security概述了中的基本处理流程。第六点:

接下来,服务器将决定提供的凭据是否有效。如果它们是有效的,下一步就会发生。如果它们无效,通常会要求您的浏览器重试(因此您返回到上面的第二步)

SpringSecurity有不同的类负责上述大多数步骤。主要参与者(按使用顺序)是ExceptionTranslationFilter、AuthenticationEntryPoint和“身份验证机制”,它负责调用我们在上一节中看到的AuthenticationManager

我必须承认,这里的文档有点混乱,因此我将给您更多的提示-这里提到的“身份验证机制””是您所追求的东西,它负责处理浏览器发送的凭据

由于将凭据附加到HTTP请求的详细信息在不同的身份验证方法(表单数据与普通头与摘要头)之间存在很大差异,因此没有通用的“身份验证机制””—相反,每种方法都实现其自己的机制,在基于web的身份验证情况下,它通常是您必须在
web.xml
中配置的特殊过滤器

在您的情况下,您可能最感兴趣的是-这用于处理基于表单的基本登录信息。自定义登录表单和筛选器之间的约定是URL(表单发布的位置)+用户名和密码字段名:


登录表单只包含j_用户名和j_密码输入字段,并发布到过滤器监控的URL(默认情况下,这是/j_spring_安全检查)。

我将为以后阅读此内容的任何人添加一个明确的答案:

当您在spring security中定义标记时,它将为您处理登录,我将详细介绍它的工作原理(希望在文档中有这样详细的说明):

请参阅以下部分中的帖子,以回应客户的回答:

更新01-29-2011-@Ritesh的技术
更新-解决@Ritesh的技术


这是一个简洁、高级的好例子,说明了如何在Spring Security中自定义登录过程。如果您使用的是JDBC可访问的数据库,那么您可以使用以下身份验证提供程序,并避免创建自定义的身份验证提供程序。它将所需的代码减少到9行XML:

<authentication-provider>
    <jdbc-user-service data-source-ref="dataSource" users-by-username-query="select username,password from users where username=?" authorities-by-username-query="select u.username, r.authority from users u, roles r where u.userid = r.userid and u.username =?" />
</authentication-provider>

它涵盖了您需要了解的有关定制Spring Security表单登录的所有信息。


<security:http auto-config="true">
  <security:form-login login-page="/login"
   login-processing-url="/postlogin"
    default-target-url="/myaccount"
     authentication-failure-url="/login?loginError=true" />
  <security:logout logout-url="/logout" />
</security:http>
登录页面是登录表单URL 登录处理url是提交登录表单的url。Spring将对您在security.xml文件中映射的身份验证管理器进行自调用

过程

  • 您需要编写一个类来实现org.springframework.security.authentication.AuthenticationProvider和重写的方法authentication(身份验证)
  • 第二个类,使用重写的方法loadUserByUsername(字符串用户名)扩展org.springframework.security.core.userdetails.UserDetailsService
  • 第二类表单,您可以在其中调用DAO并使用数据库获取用户名和密码验证用户
  • 在“身份验证”(Authentication Authentication)中,您将比较密码并返回成功与失败

  • 您在使用Spring Security吗?我在表单登录上迷路了,但是使用Spring Security提供的基本默认登录页面(Spring框架中的一个独立包),您需要实现UserDetails服务,而这些文档特别反对在会话中存储任何用户信息(它们应该存储在由SecurityContextHolder处理的UserDetails对象中)。您可以通过SecurityContextHolder访问所有内容,并确定经过身份验证的用户是否具有您在UserDetails对象中为其定义的特定角色。实际上,我目前没有使用任何Spring安全框架,但我可能认为这是个好主意。我没有在HTTP会话上存储任何内容,因为据我所知,它不是线程安全。我将它存储在会话级别。我还没有决定是否值得实现Spring安全性,我想听听专家们的意见。Spring安全性很好,也不太难实现。对我来说(我和你处于几乎完全相同的场景中)这似乎是合乎逻辑的。你可能会像学习额外的框架一样为自己做这件事而大惊小怪,你只需要提前花更多的时间,而不是从长远来看。在这件事完成后,你就可以很容易地应用各种各样的工具了
    <authentication-provider>
        <jdbc-user-service data-source-ref="dataSource" users-by-username-query="select username,password from users where username=?" authorities-by-username-query="select u.username, r.authority from users u, roles r where u.userid = r.userid and u.username =?" />
    </authentication-provider>
    
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/DB_NAME" />
        <property name="username" value="root" />
        <property name="password" value="password" />
    </bean>
    
    <security:http auto-config="true">
      <security:form-login login-page="/login"
       login-processing-url="/postlogin"
        default-target-url="/myaccount"
         authentication-failure-url="/login?loginError=true" />
      <security:logout logout-url="/logout" />
    </security:http>