使用 Ajax 使用 Spring security 登录
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20538619/
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
Login with Spring security using Ajax
提问by Umesh Awasthi
I am trying to work on Ajax based login system using Spring Security and it was working fine, till I got with another requirement where I need to configure authentication-success-handler, so as I can do some post processing once user is authenticated by Spring security.
我正在尝试使用 Spring Security 在基于 Ajax 的登录系统上工作,它工作正常,直到我遇到另一个需要配置的要求authentication-success-handler,以便在用户通过 Spring Security 身份验证后进行一些后期处理。
Earlier I was not using <form-login/>for showing Login page.My Login section is a drop down and part of header section which is common for entire application.
早些时候我没有<form-login/>用于显示登录页面。我的登录部分是一个下拉列表,是整个应用程序常见的标题部分的一部分。
This is how I am trying to configure Spring security
这就是我尝试配置 Spring 安全性的方式
<http pattern="/customer/**" auto-config="true" use-expressions="true" authentication-manager-ref="customerAuthenticationManager">
<!--<http pattern="/customer/**" auto-config="true" use-expressions="true">-->
<intercept-url pattern="/customer/logon.html*" access="permitAll" />
<intercept-url pattern="/customer/denied.html" access="permitAll"/>
<intercept-url pattern="/customer" access="hasRole('AUTH_CUSTOMER')" />
<intercept-url pattern="/customer/" access="hasRole('AUTH_CUSTOMER')" />
<intercept-url pattern="/customer/*.html" access="hasRole('AUTH_CUSTOMER')" />
<intercept-url pattern="/customer/*/*.html" access="hasRole('AUTH_CUSTOMER')" />
<form-login login-processing-url="/customer/logon.html" login-page="/shop/home.html"
authentication-success-handler-ref="webshopAuthenticationSuccessHandler" />
<logout invalidate-session="true"
logout-success-url="/customer/home.html"
logout-url="/customer/j_spring_security_logout" />
<access-denied-handler error-page="/customer/denied.html"/>
</http>
With these configuration, when ever I am clicking on login button with correct credentials, i am getting HTTP 302 error
使用这些配置,当我点击具有正确凭据的登录按钮时,我收到 HTTP 302 错误
http://localhost:8080/shop/customer/logon.html 302 found
Not sure what exactly I am doing wrong?
不确定我到底做错了什么?
<form id="login" method="post" accept-charset="UTF-8">
<input id="userName" type="text" name="userName" size="30" />
<button type="submit" class="btn">Login</button>
</form>
Ajax Code
阿贾克斯代码
var data = $(this).serializeObject();
$.ajax({
'type': 'POST',
'url': "<c:url value="/customer/logon.html"/>",
'contentType': 'application/json',
'data': JSON.stringify(data),
'dataType': 'json',
....
}}:
Login Section
登录部分
Authentication authenticationToken = new UsernamePasswordAuthenticationToken(customer.getUserName(), customer.getPassword());
try {
Authentication authentication = customerAuthenticationManager.authenticate(authenticationToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
resp.setStatus(AjaxResponse.RESPONSE_STATUS_SUCCESS);
} catch (AuthenticationException ex) {
resp.setStatus(AjaxResponse.RESPONSE_STATUS_FAIURE);
}
Any inputs? With all my efforts, I am still getting 302 and with above configuration, even my logon.htmlcontroller is not getting called.
任何输入?经过我所有的努力,我仍然得到 302 和上述配置,甚至我的logon.html控制器也没有被调用。
My main issue is when I am enabling Spring security using
我的主要问题是当我使用
<form-login login-processing-url="/customer/logon.html" login-page="/shop/home.html"
authentication-success-handler-ref="webshopAuthenticationSuccessHandler" />
I am getting 302from logon.htmland even logon.htmlController is not being triggered (placed debugger on it)
我302从logon.html,甚至logon.html没有触发控制器(在其上放置调试器)
回答by M. Deinum
First you don't need a controller, spring security handles all this for you. So drop the controller.
首先,您不需要控制器,spring security 会为您处理所有这些。所以放下控制器。
The current problem is due to your JSON based post. This is handled by the normal filter which handles login, but it doesn't see a j_usernameand j_passwordfield and as such will redirect (the 302) to the login page (in your case /shop/home.html) asking for those fields.
当前的问题是由于您的基于 JSON 的帖子。这是由处理登录的普通过滤器处理的,但它没有看到j_usernameandj_password字段,因此将重定向(302)到登录页面(在您的情况下/shop/home.html)要求这些字段。
Basically you are posting the data as JSON whereas it simply should be just an ajaxified form post. This allows you to write a simple AuthenticationSuccessHandlerwhich simply returns a 401 or a 200 status-code (and maybe a body) when things are ok.
基本上,您将数据作为 JSON 发布,而它应该只是一个 ajaxified 表单发布。这允许您编写一个简单AuthenticationSuccessHandler的代码,当一切正常时,它只返回 401 或 200 状态代码(可能还有一个正文)。
Changing your ajax submit to something like this should make things work.
将您的 ajax 提交更改为这样的事情应该会使事情起作用。
var data = $(this).serializeObject();
$.ajax({
'type': $(this).action,
'url': $(this).target,
'data': data
}):
This should create a ajax form post. Might be that you need a call to preventDefault()in the surrounding method to stop the form from actual posting.
这应该创建一个 ajax 表单帖子。可能是您需要调用preventDefault()周围的方法来阻止表单实际发布。
回答by Angular University
With the login form that is currently posted it cannot work, as a form like this is needed:
对于当前发布的登录表单,它无法工作,因为需要这样的表单:
<body>
<form action="/j_spring_security_check" method="POST">
<label for="username">User Name:</label>
<input id="username" name="j_username" type="text"/>
<label for="password">Password:</label>
<input id="password" name="j_password" type="password"/>
<input type="submit" value="Log In"/>
</form>
</body>
The post needs to be done j_spring_security_check, and username and password need to be suplied in fields j_username and j_password, otherwise it won't work.
post需要做j_spring_security_check,j_username和j_password字段需要提供用户名和密码,否则将无法运行。
I think you are getting a redirect to a login page.
我认为您正在重定向到登录页面。
You can see where the redirect is going with the chrome debugger or firebug if using firefox.
如果使用 firefox,您可以使用 chrome 调试器或 firebug 查看重定向的去向。
To approach this first get the rest of the config working with the default login page generated by spring security, by removing login-page="/customer/logon.html".
要解决这个问题,首先通过删除 login-page="/customer/logon.html" 使其余的配置与 Spring Security 生成的默认登录页面一起工作。
Once this works you can add back the custom login page, but it needs to have the elements above.
完成此操作后,您可以重新添加自定义登录页面,但它需要具有上述元素。
Also I believe you are trying to post a JSTL tag via ajax to the server? If it's true it won't work, otherwise can you edit the question.
此外,我相信您正在尝试通过 ajax 将 JSTL 标记发布到服务器?如果是真的,它将不起作用,否则您可以编辑问题。
Try it step by step by first using the default login page, then with an ajax request with hardcoded values just for testing and then when this works with a custom login page.
首先使用默认登录页面逐步尝试,然后使用带有硬编码值的 ajax 请求,仅用于测试,然后当它与自定义登录页面一起使用时。
回答by Ravi Kumar
response code 302 is not an error indication. It's a way of performing a redirection. as you have not shared your webshopAuthenticationSuccessHandler code.
响应代码 302 不是错误指示。这是一种执行重定向的方式。因为您还没有分享您的 webshopAuthenticationSuccessHandler 代码。
But i am pretty much sure you are redirecting the request to some specified resource after processing some certain condition. so just check your header and get the URL of redirection. and then redirect with javascript code.
但是我非常确定您在处理某些特定条件后将请求重定向到某个指定的资源。所以只需检查您的标题并获取重定向的 URL。然后使用 javascript 代码重定向。
An HTTP response with this status code will additionally provide a URL in the Location header field.
带有此状态代码的 HTTP 响应将另外在 Location 标头字段中提供一个 URL。
For an example -
举个例子——
Client request:
客户要求:
GET /index.html HTTP/1.1
获取 /index.html HTTP/1.1
Host: www.example.com
主机:www.example.com
Server response:
服务器响应:
HTTP/1.1 302 Found
发现 HTTP/1.1 302
Location: http://www.iana.org/domains/example/
位置:http: //www.iana.org/domains/example/
so along with this error code you are getting http://www.iana.org/domains/example/url where your authenticationSuccessHandler want you to redirect so redirect it through javascript code.
因此,连同此错误代码,您将获得http://www.iana.org/domains/example/url,其中 authenticationSuccessHandler 希望您重定向,因此请通过 javascript 代码重定向。

