Java 如何使用 Spring Security / Spring MVC 处理表单登录
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4067736/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to process a form login using Spring Security / Spring MVC
提问by David Parks
Simple question, I just need a pointer in the right direction:
简单的问题,我只需要一个指向正确方向的指针:
I have a simple Spring MVC/Spring Security webapp. Initially I set up Spring Security so that the default login page shows and authenticates properly (I implemented the UserDetailsService
with the DaoAuthenticationProvider
to do this).
我有一个简单的 Spring MVC/Spring Security webapp。最初,我设置了 Spring Security,以便默认登录页面正确显示和验证(我UserDetailsService
使用DaoAuthenticationProvider
来实现此目的)。
Next step: replace the default spring login page with my login page and post the credentials.
下一步:用我的登录页面替换默认的 spring 登录页面并发布凭据。
But what do I do with the submitted login credentials?I assume I post the form to a controller, verify the credentials, but I'm not clear what the right step is after that. E.g.:
但是我如何处理提交的登录凭据?我假设我将表单发布到控制器,验证凭据,但我不清楚之后正确的步骤是什么。例如:
- Am I calling a method of AuthenticationManager?
- Do I need to define a bean for this?
- Is there an interface/service I need to implement like an AuthenticationEntryPoint or something?
- 我正在调用 AuthenticationManager 的方法吗?
- 我需要为此定义一个bean吗?
- 是否有我需要实现的接口/服务,例如 AuthenticationEntryPoint 之类的?
I've hit the docs 3 times over and don't quite follow them. I know this is dirt simple, so I just need to hear how the process should flow.
我已经阅读了 3 次文档,但并没有完全遵循它们。我知道这很简单,所以我只需要了解流程应该如何进行。
采纳答案by Neeme Praks
Spring Security reference documentationoutlines the basic processing flow in 5.4 Authentication in a Web Application. There is point #6:
Spring Security参考文档概述了5.4 Web 应用程序中的身份验证中的基本处理流程。有第 6 点:
Next the server will decide whether or not the presented credentials are valid. If they're valid, the next step will happen. If they're invalid, usually your browser will be asked to try again (so you return to step two above)....
Spring Security has distinct classes responsible for most of the steps described above. The main participants (in the order that they are used) are the ExceptionTranslationFilter, an AuthenticationEntryPoint and an “authentication mechanism”, which is responsible for calling the AuthenticationManager which we saw in the previous section.
接下来,服务器将决定所提供的凭据是否有效。如果它们有效,下一步就会发生。如果它们无效,通常会要求您的浏览器重试(因此您返回到上面的第二步)。...
Spring Security 有不同的类负责上述大部分步骤。主要参与者(按使用顺序)是 ExceptionTranslationFilter、一个 AuthenticationEntryPoint 和一个“身份验证机制”,它负责调用我们在上一节中看到的 AuthenticationManager。
I have to admit, the documentation here is a bit confusing so I will give you some more pointers - the "authentication mechanism" mentioned here is the thing you are after, it is responsible for processing the credentials that the browser is sending.
我不得不承认,这里的文档有点混乱,所以我会给你更多的指示——这里提到的“身份验证机制”是你所追求的,它负责处理浏览器发送的凭据。
As the details of attaching the credentials to HTTP request(s) vary greatly among different authentication methods (form data vs. plain headers vs. digest headers), there is no common "authentication mechanism" - instead, each method implements its own mechanism and in the case of web-based authentication, it is typically a special filterthat you have to configure in web.xml
.
由于将凭据附加到 HTTP 请求的详细信息在不同的身份验证方法(表单数据、普通标头与摘要标头)之间差异很大,因此没有通用的“身份验证机制” - 相反,每种方法都实现了自己的机制和在基于 Web 的身份验证的情况下,它通常是您必须在 中配置的特殊过滤器web.xml
。
In your case, you are most probably interested in UsernamePasswordAuthenticationFilter- this is used for processing basic form-based login information. The contract between your custom login form and the filter is the URL (where form is posted) + username and password field names:
在您的情况下,您很可能对UsernamePasswordAuthenticationFilter感兴趣- 这用于处理基于表单的基本登录信息。您的自定义登录表单和过滤器之间的约定是 URL(表单发布的位置)+ 用户名和密码字段名称:
The login form simply contains j_username and j_password input fields, and posts to the URL that is monitored by the filter (by default this is /j_spring_security_check).
登录表单仅包含 j_username 和 j_password 输入字段,并发布到过滤器监视的 URL(默认情况下为 /j_spring_security_check)。
回答by danny.lesnik
We are talking about the same problem more and less, this is my approachlet's see what people will say.
我们越来越少谈论同样的问题,这是我的方法,让我们看看人们会怎么说。
回答by David Parks
I'll add a clarifying answer for anyone reading this in the future:
我将为将来阅读本文的任何人添加一个澄清的答案:
When you define the tag in spring security it will handle the login for you, I'll go over how it works in detail (wish it were this detailed in the docs):
当您在 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>
The login-pageis the url of the login page. You should have a controller (or static HTML page) that serves this page, it's your pretty login form.
在登录页面是登录页面的URL。你应该有一个控制器(或静态 HTML 页面)来服务这个页面,它是你漂亮的登录表单。
The login-processing-urlis a URL which the form-login component handles. It's as if the form-login component implemented its own controller for this page. You should post your formto this page. You also need to know to name your username/password parameters "j_username" and "j_login"
所述登录加工-URL是其中表单登录组件处理的URL。就好像表单登录组件为此页面实现了自己的控制器。您应该将表单发布到此页面。您还需要知道将您的用户名/密码参数命名为“j_username”和“j_login”
Beyond this, and the rest of the reasonably obvious options above, you should have implemented a UserDetailsService
- that is, create a class and implement the interface UserDetailsService
which gets, and returns, a UserDetails
object (username/password) for a given username - and provide that UserDetails
object with the rest of the security configuration:
除此之外,以及上面其他相当明显的选项,您应该已经实现了UserDetailsService
- 也就是说,创建一个类并实现UserDetailsService
获取和返回UserDetails
给定用户名的对象(用户名/密码)的接口- 并提供UserDetails
具有其余安全配置的对象:
<security:authentication-manager>
<security:authentication-provider ref="daoAuthenticationProvider" />
</security:authentication-manager>
<bean id="daoAuthenticationProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider" >
<property name="userDetailsService" ref="myAuthorizationService" />
</bean>
回答by gunalmel
See the posting by limcin response to Ritesh's answer at Configuring Spring Security 3.x to have multiple entry pointsLook at the sections titled:
请参阅limc对Ritesh在将Spring Security 3.x 配置为具有多个入口点的回答的回复查看标题为的部分:
UPDATE 01-29-2011 - @Ritesh's technique
UPDATE - SOLUTION to @Ritesh's technique
更新 01-29-2011 - @Ritesh 的技术
更新 - @Ritesh 的技术解决方案
It is a concise, advanced good example of how you can customize the login process in Spring Security
这是一个简洁、高级的好例子,说明如何在 Spring Security 中自定义登录过程
回答by Alessandro Giannone
If you're using a JDBC accessible database, then you could use the following authentication-provider and avoid creating a custom one. It cuts down the code required to 9 lines of XML:
如果您使用的是 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>
You can then setup your dataSource as follows
然后,您可以按如下方式设置数据源
<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>
Have a look at this post: http://codehustler.org/blog/spring-security-tutorial-form-login/It covers everything you need to know about customising Spring Security form-login.
看看这篇文章:http: //codehustler.org/blog/spring-security-tutorial-form-login/它涵盖了关于定制 Spring Security 表单登录你需要知道的一切。
回答by Kunwar Babu
<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>
login-page is the login form URL login-processing-url is the url where login form is submitted. Spring will give a self call the authentication-manager mapped by you in security.xml file.
login-page 是登录表单 URL login-processing-url 是提交登录表单的 URL。Spring 会对您在 security.xml 文件中映射的身份验证管理器进行自我调用。
Process
过程
- You need to write a class that implements org.springframework.security.authentication.AuthenticationProvider with overriden method Authentication authenticate(Authentication authentication)
- Second class that extends org.springframework.security.core.userdetails.UserDetailsService with a overridden method loadUserByUsername(String username)
- The second class form where you can call your DAO and validate user with database fetching username and password.
- In Authentication authenticate(Authentication authentication) you will compare the password and return success failure your are done.
- 您需要编写一个实现 org.springframework.security.authentication.AuthenticationProvider 的类,并使用重写方法 Authentication authenticate(Authentication authentication)
- 使用重写方法 loadUserByUsername(String username) 扩展 org.springframework.security.core.userdetails.UserDetailsService 的第二个类
- 第二类表单,您可以在其中调用 DAO 并使用数据库获取用户名和密码验证用户。
- 在 Authentication authentication(Authentication authentication) 中,您将比较密码并返回成功失败。