一、前言
对于浏览器请求与非浏览器请求服务器一般都有不同的响应,对于未认证的用户请求,在浏览器与非浏览器发出,spring security 怎么实现不同响应呢?
二、实现
自定义json返回对象:
package com.xh.sercurity.support;
//定制的返回对象
public class SimpleResponse {
public SimpleResponse (Object content) {
this.content = content;
}
private Object content;
public Object getContent() {
return content;
}
public void setContent(Object content) {
this.content = content;
}
}
自定义controller处理不同的请求:
package com.xh.sercurity;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import com.xh.sercurity.support.SimpleResponse;
/**
* 浏览器环境下与安全相关的服务
*/
@RestController
public class BrowserSecurityController {//extends SocialController {
private Logger logger = LoggerFactory.getLogger(getClass());
// 请求缓存 spring security 跳转登录请求之前 把用户请求 缓存到RequestCache中
private RequestCache requestCache = new HttpSessionRequestCache();
// spring 跳转工具
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
/**
* 当需要身份认证时,跳转到这里
* 处理身份认证请求
*/
@ResponseStatus(code = HttpStatus.UNAUTHORIZED) // 返回 401 未授权 状态码
@RequestMapping("/authentication/require")
public SimpleResponse requireAuthentication(HttpServletRequest request, HttpServletResponse response)
throws IOException {
// 获取之前缓存的请求 savedRequest
SavedRequest savedRequest = requestCache.getRequest(request, response);
if (savedRequest != null) {
String targetUrl = savedRequest.getRedirectUrl();
logger.info("引发跳转的请求是:" + targetUrl);
if (StringUtils.endsWithIgnoreCase(targetUrl, ".html")) {
// spring 重定向
redirectStrategy.sendRedirect(request, response, "/myLogin.html");
}
}
return new SimpleResponse("访问的服务需要身份认证,请引导用户到登录页");
}
}
在安全认证的config BrowserSecurityConfig
中加入对应自定义controller路径, 处理不同类型的,让自定义controller处理不同的请求。
package com.xh.sercurity.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder () {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// http.httpBasic()// httpBasic 登录
http.formLogin()// 表单登录 来身份认证
.loginPage("/authentication/require")// 自定义登录页面
.loginProcessingUrl("/authentication/form")// 自定义登录路径
.and()
.authorizeRequests()// 对请求授权
// error 127.0.0.1 将您重定向的次数过多
.antMatchers("/myLogin.html", "/authentication/require",
"/authentication/form").permitAll()// 这些页面不需要身份认证,其他请求需要认证
.anyRequest() // 任何请求
.authenticated()//; // 都需要身份认证
.and()
.csrf().disable();// 禁用跨站攻击
}
}