春季安全阿贾克斯登陆 [英] Spring Security Ajax login
问题描述
我已经实现了我的项目中此安全proccess: Spring Security的3 - MVC集成教程(第二部分)
我的问题是,我需要把它变成一个基于Ajax的登录。
我需要什么做的,为了使这个XML满意,只是返回字符串/ JSON的客户端?
据我所知,这个问题可能会在表单登录
标记。
< XML版本=1.0编码=UTF-8&GT?;
<豆类:豆类的xmlns =http://www.springframework.org/schema/security
的xmlns:豆=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.0.xsd">
<! - 这是我们配置Spring - 安全 - >
< HTTP自动配置=真正的使用-EX pressions =真正的禁止访问的页面=/管理/认证/拒绝>
<拦截-URL模式=/管理/认证/登录访问=permitAll/>
<拦截-URL模式=/管理/主/ admin的访问=hasRole('ROLE_ADMIN')/>
<拦截-URL模式=/管理/主/常见的访问=hasRole('ROLE_USER')/>
<形式登陆
登录页=/管理/认证/注册
认证失败-URL =/管理/认证/注册?错误=真
默认目标URL =/管理/主/通用/>
<注销
无效会话=真
注销-成功-URL =/管理/认证/注册
注销-URL =/管理/认证/注销/>
< / HTTP>
< - !声明一个认证管理器使用一个自定义的UserDetailsService - >
<认证经理>
<身份验证提供用户服务REF =customUserDetailsService>
<密码-CN codeR REF =passwordEn codeR/>
< /验证提供者>
< /认证经理>
&所述;! - 使用的Md5烯codeR因为用户的口令存储作为被Md5在数据库中 - >
<豆类:绿豆类=org.springframework.security.authentication.encoding.Md5PasswordEn codeRID =passwordEn codeR/>
<! - 定制服务,而春季将检索用户及其相应的访问级别 - >
<豆类:绿豆的id =customUserDetailsService级=com.affiliates.service.CustomUserDetailsService/>
< /豆类:豆类>
这是旧的文章,但它仍然出现为结果的最前面一个春天的安全的Ajax登陆,所以我想我会分享我的解。它遵循春季安全标准,并为pretty的简单的设置,关键是要拥有2 < HTTP>
在安全配置元素,一个是REST / Ajax和一个用于应用程序(普通的HTML页面)的其余部分。该顺序< HTTP>
的出现是非常重要的,它已经从更具体的去比较通用网址,就像<网址截距>
元素在< HTTP>
第1步:设置两个单独的< HTTP>
的
< XML版本=1.0编码=UTF-8&GT?;
<豆类:豆类的xmlns =http://www.springframework.org/schema/security
的xmlns:P =http://www.springframework.org/schema/p
的xmlns:豆=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.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<! - 一个共享的缓存请求需要多个HTTP元素 - >
<豆类:绿豆的id =requestCache级=org.springframework.security.web.savedrequest.HttpSessionRequestCache/>
<! - 从静态资源删除安全,避免经过安全过滤器链 - >
< HTTP模式=/资源/ **安全=无/>
<! - HTTP配置为REST服务(AJAX接口)
================================================== = - >
< HTTP自动配置=真正的使用-EX pressions =真模式=/ REST / **>
< - !登录配置
登录处理-URL =此URL/ REST /安全性/登录处理前端AJAX请求进行身份验证POST
登录页=/ REST /安全性/登录页是指身份验证要求
认证失败-URL =/ REST /安全/认证故障是指身份验证失败,坏的凭证或其他安全例外
默认目标URL =/ REST /安全性/默认的目标前端AJAX请求都在这里成功验证后重定向
- >
<形式登陆
登录处理-URL =/ REST /安全性/登录处理
登录页=/ REST /安全性/登录页面
认证失败-URL =/ REST /安全/认证失败
默认目标URL =/ REST /安全性/默认的目标
始终使用默认目标=真/>
<注销注销-URL =/ REST /安全/注销-URL/>
<! - REST服务可以在这里保证,将与JSON而不是HTML回应 - >
<拦截-URL模式=/ REST /日历/ **访问=hasRole('ROLE_USER')/>
<! - 其他REST拦截,网址放在这里 - >
<! - 它具有捕获所有终端 - >
<拦截-URL模式=/ REST / **访问=isAuthenticated()/>
&所述;! - 参照共享请求缓存 - >
<请求缓存REF =requestCache/>
< / HTTP>
<! - HTTP配置为普通的HTML页面
================================================== = - >
< HTTP自动配置=真正的使用-EX pressions =真正的>
<形式登陆
登录处理-URL =/安全/ j_spring_security_check
登录页=/登陆
认证失败-URL =/登录login_error = T?/>
<注销注销-URL =/安全/ j_spring_security_logout/>
<拦截-URL模式=/日历/ **访问=hasRole('ROLE_USER')/>
<! - 其他拦截,网址放在这里 - >
< - !我的应用程序的情况下,HTML配置以允许所有用户和需要HTTPS结束
它始终是一个好主意,发送类似的密码通过HTTPS敏感信息 - >
<拦截-URL模式=/ **访问=permitAll要求渠道=HTTPS/>
&所述;! - 参照共享请求缓存 - >
<请求缓存REF =requestCache/>
< / HTTP>
<! - 认证管理器等配置下面去 - >
< /豆类:豆类>
第2步:REST验证控制器
进口org.springframework.http.HttpHeaders;
进口org.springframework.http.HttpStatus;
进口org.springframework.http.ResponseEntity;
进口org.springframework.security.core.Authentication;
进口org.springframework.security.core.context.SecurityContextHolder;
进口org.springframework.stereotype.Controller;
进口org.springframework.web.bind.annotation.RequestMapping;
进口org.springframework.web.bind.annotation.RequestMethod;
进口flexjson.JSONSerializer;
@Controller
@RequestMapping(值=/ REST /安全)
公共类RestAuthenticationController {
公共HttpHeaders getJsonHeaders(){
HttpHeaders标题=新HttpHeaders();
headers.add(内容类型,应用/ JSON);
返回头;
}
@RequestMapping(值=/登录页,方法= RequestMethod.GET)
公共ResponseEntity<字符串> apiLoginPage(){
返回新ResponseEntity<字符串>(getJsonHeaders(),HttpStatus.UNAUTHORIZED);
}
@RequestMapping(值=/认证失败,方法= RequestMethod.GET)
公共ResponseEntity<字符串> apiAuthenticationFailure(){
//返回HttpStatus.OK,让您的前端知道完成的请求(没有401,它会导致你回去重新登录,循环不好)
//包含一些消息code来表示失败的登录
返回新ResponseEntity<字符串>({\成功\:假的,\消息\:\认证失败\},getJsonHeaders(),HttpStatus.OK);
}
@RequestMapping(值=/默认的目标,法= RequestMethod.GET)
公共ResponseEntity<字符串> apiDefaultTarget(){
验证验证= SecurityContextHolder.getContext()getAuthentication()。
//排除/包括任何字段,你需要
。字符串userJson =新JSONSerializer()不包括(*。密码,*类。)序列化(认证)。
返回新ResponseEntity<字符串>(userJson,getJsonHeaders(),HttpStatus.OK);
}
}
第三步:提交AJAX的形式和处理响应,需要jQuery的当作ajaxForm库
<形式的行动=/ REST /安全性/登录处理的方法=POST>
...
< /形式GT;
$('表')。当作ajaxForm({
成功:函数(响应,状态文本,XHR,$形式){
的console.log(响应);
如果(响应== NULL || response.username == NULL){
警报(验证失败);
} 其他 {
//响应JSON版本的Spring的身份验证
警报(认证成功);
}
},
错误:函数(响应,状态文本,错误,$形式){
如果(响应=零和放大器;!&安培; response.message ==认证失败){
警报(验证失败);
}
}
});
I have implemented this security proccess in my project: Spring Security 3 - MVC Integration Tutorial (Part 2).
My problem is that I need to turn it into an Ajax-based login.
What do I need to do in order to make this XML suitable with just returning string/JSON to the client?
I understand that the problem might be in the form-login
tag.
<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd">
<!-- This is where we configure Spring-Security -->
<http auto-config="true" use-expressions="true" access-denied-page="/Management/auth/denied" >
<intercept-url pattern="/Management/auth/login" access="permitAll"/>
<intercept-url pattern="/Management/main/admin" access="hasRole('ROLE_ADMIN')"/>
<intercept-url pattern="/Management/main/common" access="hasRole('ROLE_USER')"/>
<form-login
login-page="/Management/auth/login"
authentication-failure-url="/Management/auth/login?error=true"
default-target-url="/Management/main/common"/>
<logout
invalidate-session="true"
logout-success-url="/Management/auth/login"
logout-url="/Management/auth/logout"/>
</http>
<!-- Declare an authentication-manager to use a custom userDetailsService -->
<authentication-manager>
<authentication-provider user-service-ref="customUserDetailsService">
<password-encoder ref="passwordEncoder"/>
</authentication-provider>
</authentication-manager>
<!-- Use a Md5 encoder since the user's passwords are stored as Md5 in the database -->
<beans:bean class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" id="passwordEncoder"/>
<!-- A custom service where Spring will retrieve users and their corresponding access levels -->
<beans:bean id="customUserDetailsService" class="com.affiliates.service.CustomUserDetailsService"/>
</beans:beans>
This is an old post, but it still comes up as one of the top results for "spring security ajax login," so I figured I'd share my solution. It follows Spring Security standards and is pretty simple to setup, the trick is to have 2 <http>
elements in your security configuration, one for REST/Ajax and one for the rest of the app (regular HTML pages). The order in which <http>
's appear is important, it has to go from more specific to more generic URLs, just like <url-intercept>
elements inside of a <http>
.
Step 1: Setup Two Separate <http>
's
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:p="http://www.springframework.org/schema/p"
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.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- a shared request cache is required for multiple http elements -->
<beans:bean id="requestCache" class="org.springframework.security.web.savedrequest.HttpSessionRequestCache" />
<!-- remove security from static resources to avoid going through the security filter chain -->
<http pattern="/resources/**" security="none" />
<!-- http config for REST services (AJAX interface)
=================================================== -->
<http auto-config="true" use-expressions="true" pattern="/rest/**">
<!-- login configuration
login-processing-url="/rest/security/login-processing" front-end AJAX requests for authentication POST to this URL
login-page="/rest/security/login-page" means "authentication is required"
authentication-failure-url="/rest/security/authentication-failure" means "authentication failed, bad credentials or other security exception"
default-target-url="/rest/security/default-target" front-end AJAX requests are redirected here after success authentication
-->
<form-login
login-processing-url="/rest/security/login-processing"
login-page="/rest/security/login-page"
authentication-failure-url="/rest/security/authentication-failure"
default-target-url="/rest/security/default-target"
always-use-default-target="true" />
<logout logout-url="/rest/security/logout-url" />
<!-- REST services can be secured here, will respond with JSON instead of HTML -->
<intercept-url pattern="/rest/calendar/**" access="hasRole('ROLE_USER')" />
<!-- other REST intercept-urls go here -->
<!-- end it with a catch all -->
<intercept-url pattern="/rest/**" access="isAuthenticated()" />
<!-- reference to the shared request cache -->
<request-cache ref="requestCache"/>
</http>
<!-- http config for regular HTML pages
=================================================== -->
<http auto-config="true" use-expressions="true">
<form-login
login-processing-url="/security/j_spring_security_check"
login-page="/login"
authentication-failure-url="/login?login_error=t" />
<logout logout-url="/security/j_spring_security_logout" />
<intercept-url pattern="/calendar/**" access="hasRole('ROLE_USER')" />
<!-- other intercept-urls go here -->
<!-- in my app's case, the HTML config ends with permitting all users and requiring HTTPS
it is always a good idea to send sensitive information like passwords over HTTPS -->
<intercept-url pattern="/**" access="permitAll" requires-channel="https" />
<!-- reference to the shared request cache -->
<request-cache ref="requestCache"/>
</http>
<!-- authentication manager and other configuration go below -->
</beans:beans>
Step 2: REST Authentication Controller
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import flexjson.JSONSerializer;
@Controller
@RequestMapping(value = "/rest/security")
public class RestAuthenticationController {
public HttpHeaders getJsonHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
return headers;
}
@RequestMapping(value="/login-page", method = RequestMethod.GET)
public ResponseEntity<String> apiLoginPage() {
return new ResponseEntity<String>(getJsonHeaders(), HttpStatus.UNAUTHORIZED);
}
@RequestMapping(value="/authentication-failure", method = RequestMethod.GET)
public ResponseEntity<String> apiAuthenticationFailure() {
// return HttpStatus.OK to let your front-end know the request completed (no 401, it will cause you to go back to login again, loops, not good)
// include some message code to indicate unsuccessful login
return new ResponseEntity<String>("{\"success\" : false, \"message\" : \"authentication-failure\"}", getJsonHeaders(), HttpStatus.OK);
}
@RequestMapping(value="/default-target", method = RequestMethod.GET)
public ResponseEntity<String> apiDefaultTarget() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
// exclude/include whatever fields you need
String userJson = new JSONSerializer().exclude("*.class", "*.password").serialize(authentication);
return new ResponseEntity<String>(userJson, getJsonHeaders(), HttpStatus.OK);
}
}
Step 3: Submit AJAX form and process the response, required jQuery's ajaxForm library
<form action="/rest/security/login-processing" method="POST">
...
</form>
$('form').ajaxForm({
success: function(response, statusText, xhr, $form) {
console.log(response);
if(response == null || response.username == null) {
alert("authentication failure");
} else {
// response is JSON version of the Spring's Authentication
alert("authentication success");
}
},
error: function(response, statusText, error, $form) {
if(response != null && response.message == "authentication-failure") {
alert("authentication failure");
}
}
});
这篇关于春季安全阿贾克斯登陆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!