Spring boot + spring security 实现 Rest 登录 ( json )

第一步,获取基本springboot项目

从 spring官网获取security+session+redis依赖的springboot项目
安装配置redis,修改配置文件,启动项目,拿到登录密码,用户名为user.
根据官方文档,配置demo项目,理解spring security的机制

第二步,添加自己的登录验证方式

添加session策略,让权限验证从session里获取token,而不是默认的cookie
重写自己的UserDetails,实现org.springframework.security.core.userdetails.UserDetails接口
重写自己的UserService,实现org.springframework.security.core.userdetails.UserDetailsService
接口,重写loadUserByUsername方法,从数据库根据username获取UserDetails
在WebSecuirtyConfig里加入配置:

/**
* Configure order web security with authentication manager build
*/
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(hanoverUserService).passwordEncoder(bcryptEncoder);
}

第三步,重写过滤器,修改form方式为标准的post

spring security的用户密码获取在
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
的attemptAuthentication方法里,我们需要新建一个过滤器,继承UsernamePasswordAuthenticationFilter过滤器,并且重写attemptAuthentication方法。
直接从body里获取json参数:

ObjectMapper mapper = new ObjectMapper();
Map result = null;
result = mapper.readValue(request.getReader(), Map.class);
String username = (String)result.get("username");
String password = (String)result.get("password");

然后再WebSecurityConfig里添加该filter:

http.addFilterBefore(customUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);

这样的话,就会把之前的form方式变为现在的json传参。

第四步,添加自己的successHandle和failureHandle,用标准restful返回

获取参数的方式修改了,验证的方式也修改了,现在就来修改返回结果的方式
新建RESTAuthenticationSuccessHandler继承SimpleUrlAuthenticationSuccessHandler
重写onAuthenticationSuccess方法,把标准的CommonData返回结果写入response,代码如下:

CommonData<Map> result = new CommonData<Map>();
Map<String, Object> tokenMap = new HashMap<String, Object>();
response.setStatus(HttpStatus.OK.value());
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
tokenMap.put("token", request.getSession().getId());
result.setData(tokenMap);
mapper.writeValue(response.getWriter(), result);

同样,新建RESTAuthenticationFailureHandler继承SimpleUrlAuthenticationFailureHandler
重写onAuthenticationFailure方法,把标准的commonData返回结果写入response:

BastDTOData result = new BastDTOData();
result.setSuccess(false);
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
mapper.writeValue(response.getWriter(), result);

第五步,解决跨域问题

解决完如上问题之后,在本地和postman上都可以正常用restful风格的访问方式请求登录,但是使用前端代码进行跨域访问的时候,会有跨域问题
在successHandle和failureHandle里,需要在header里进行如下操作:

final String origin = request.getHeader("origin");
if (StringUtils.isNotEmpty(origin))
{
response.setHeader("Access-Control-Allow-Origin", origin);
}
else
{
response.setHeader("Access-Control-Allow-Origin", "*");
}
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "OPTIONS,GET,PUT,POST,DELETE,HEAD");
response.setHeader("Access-Control-Allow-Headers",
"content-type,access-control-request-headers,access-control-request-method,accept,origin,authorization,x-requested-with,serviceName,locale");

其他资料

RESTful authentication using Spring Security on Spring Boot, and jQuery as a web client 链接

Spring Boot Security Application 链接

REST Authentication using Spring Security & Spring Session链接

Understanding CORS链接

发布了225 篇原创文章 · 获赞 385 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/qq_33709508/article/details/104352818