为简化处理,该方法关闭csrf 但该文基于文章http://blog.csdn.net/makefriend7/article/details/53490184点击打开链接 之后编写,如无说明,找不到的类都在前文中
基于认证的处理比较简单。
首先是我们的核心类SecurityConfig 代码如下
@Configuration
@EnableWebSecurity//启用Web安全
@ComponentScan
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
@Autowired
private MySavedRequestAwareAuthenticationSuccessHandler authenticationSuccessHandler;
这个函数主要说明登陆框的样式,地址等等(有默认登陆框)
@Override
protected void configure(HttpSecurity http) throws Exception {
// ant通配符说明
//? 匹配任何单字符
// * 匹配0或者任意数量的字符
// ** 匹配0或者更多的目录
http.formLogin()
.successHandler(authenticationSuccessHandler)
.failureHandler(new SimpleUrlAuthenticationFailureHandler()).and()
.exceptionHandling().authenticationEntryPoint(restAuthenticationEntryPoint).and()
.authorizeRequests()
.antMatchers("/login","/myresource/**").permitAll()
.antMatchers("/system1/**").hasRole("USER1")
.antMatchers("/system2/**").hasRole("USER2")
.anyRequest().authenticated().and()
.csrf().disable();
///这个函数主要说明需要认证的用户,密码,以及权限,如何使用库或者其他任何文件进行认证,在下一篇文章中介绍
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user1").password("password1").roles("USER1").and()
.withUser("user2").password("password2").roles("USER2");
}
}
可以看到,这里主要要实现两个类。MySavedRequestAwareAuthenticationSuccessHandler类,代表正确登陆之后的处理, RestAuthenticationEntryPoint代表登陆失败之后的处理,
MySavedRequestAwareAuthenticationSuccessHandler代码如下
import javax.servlet.ServletException;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.io.PrintWriter;
@Component
public class MySavedRequestAwareAuthenticationSuccessHandler
extends SimpleUrlAuthenticationSuccessHandler {
private final static Logger logger = LoggerFactory.getLogger(MySavedRequestAwareAuthenticationSuccessHandler.class);
private RequestCache requestCache = new HttpSessionRequestCache();
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws ServletException, IOException {
logger.info("认证成功");
SavedRequest savedRequest = requestCache.getRequest(request, response);
//将实体对象转换为JSON Object转换
JSONObject responseJSONObject = new JSONObject();
responseJSONObject.put("info","successful login");
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = null;
try {
out = response.getWriter();
out.append(responseJSONObject.toString());
logger.debug("返回是\n");
logger.debug(responseJSONObject.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
}
if (savedRequest == null) {
clearAuthenticationAttributes(request);
return;
}
String targetUrlParam = getTargetUrlParameter();
if (isAlwaysUseDefaultTargetUrl() ||
(targetUrlParam != null &&
StringUtils.hasText(request.getParameter(targetUrlParam)))) {
requestCache.removeRequest(request, response);
clearAuthenticationAttributes(request);
return;
}
clearAuthenticationAttributes(request);
}
public void setRequestCache(RequestCache requestCache) {
this.requestCache = requestCache;
}
}
失败的处理如下
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
//密码输入错误进入这里
@Component( "restAuthenticationEntryPoint" )
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
private final static Logger logger = LoggerFactory.getLogger(RestAuthenticationEntryPoint.class);
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException ) throws IOException {
logger.info("I am not correct password");
JSONObject responseJSONObject = new JSONObject();
responseJSONObject.put("result","Unauthorized" );
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = null;
try {
out = response.getWriter();
out.append(responseJSONObject.toString());
logger.debug("返回是\n");
logger.debug(responseJSONObject.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
}
}
}
剩下的那就是我们的入口
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@RestController
@EnableWebMvc
public class BaseController {
private final static Logger logger = LoggerFactory.getLogger(BaseController.class);
@RequestMapping(value = "/system1/fun1", produces = "application/json")
public String login2(HttpServletRequest request, HttpSession session) {
logger.info("I am system1/fun1 ");
return "I am system1/fun1 return";
}
@RequestMapping(value = "/system2/fun2", produces = "application/json")
public String login3(HttpServletRequest request, HttpSession session) {
logger.info("system2/fun2 ");
return "system2/fun2";
}
@RequestMapping(value = "/myresource/resource1", produces = "application/json")
public String resource1(HttpServletRequest request, HttpSession session) {
logger.info("I am resource1");
return "I am resource1 return";
}
}
QML端的客户代码也很简单。修改myCsrf函数如下
function myLoginWithNoCsrf()
{
console.log("begin system fun1");
var url1 = "http://127.0.0.1:8080/system1/fun1";
var tmp1 = JSON;
tmp1.username = "user1"
tmp1.password = "password1";
var mycontent = JSON.stringify(tmp1);
myhttp.open("POST", url1, false); //简单化处理。都采用同步的方式
myhttp.setRequestHeader("Content-type", "application/json");
myhttp.setRequestHeader("Content-length", mycontent.length);
myhttp.setRequestHeader("Connection", "Keep-Alive");
myhttp.send(mycontent);
//结果是非法的请求源
console.log("begin test myresource/resource1");
url1 = "http://127.0.0.1:8080/myresource/resource1";
myhttp.open("POST", url1, false); //简单化处理。都采用同步的方式
myhttp.setRequestHeader("Content-type", "application/json");
myhttp.setRequestHeader("Content-length", mycontent.length);
myhttp.setRequestHeader("Connection", "Keep-Alive");
myhttp.send(mycontent);
//资源类可以成功获得请求
console.log("begin mylogin");
mycontent="username=user1&password=password1&submit=Login";
url1 = "http://127.0.0.1:8080/login";
myhttp.open("POST", url1, false); //简单化处理。都采用同步的方式
myhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
myhttp.setRequestHeader("Content-length", mycontent.length);
myhttp.setRequestHeader("Connection", "Keep-Alive");
myhttp.send(mycontent);
console.log("begin fun1 again");
url1 = "http://127.0.0.1:8080/system1/fun1";
myhttp.open("POST", url1, false); //简单化处理。都采用同步的方式
myhttp.setRequestHeader("Content-type", "application/json");
myhttp.setRequestHeader("Content-length", mycontent.length);
myhttp.setRequestHeader("Connection", "Keep-Alive");
myhttp.send(mycontent);
console.log("begin fun2 ");
url1 = "http://127.0.0.1:8080/system2/fun2";
myhttp.open("POST", url1, false); //简单化处理。都采用同步的方式
myhttp.setRequestHeader("Content-type", "application/json");
myhttp.setRequestHeader("Content-length", mycontent.length);
myhttp.setRequestHeader("Connection", "Keep-Alive");
myhttp.send(mycontent);
console.log("begin mylogin");
mycontent="username=user2&password=password2&submit=Login";
url1 = "http://127.0.0.1:8080/login";
myhttp.open("POST", url1, false); //简单化处理。都采用同步的方式
myhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
myhttp.setRequestHeader("Content-length", mycontent.length);
myhttp.setRequestHeader("Connection", "Keep-Alive");
myhttp.send(mycontent);
console.log("begin fun1 again 2");
url1 = "http://127.0.0.1:8080/system1/fun1";
myhttp.open("POST", url1, false); //简单化处理。都采用同步的方式
myhttp.setRequestHeader("Content-type", "application/json");
myhttp.setRequestHeader("Content-length", mycontent.length);
myhttp.setRequestHeader("Connection", "Keep-Alive");
myhttp.send(mycontent);
console.log("begin fun2 again");
url1 = "http://127.0.0.1:8080/system2/fun2";
myhttp.open("POST", url1, false); //简单化处理。都采用同步的方式
myhttp.setRequestHeader("Content-type", "application/json");
myhttp.setRequestHeader("Content-length", mycontent.length);
myhttp.setRequestHeader("Connection", "Keep-Alive");
myhttp.send(mycontent);
}