前言
众所周知,spring-security默认是form表单模式登录的,故我们只要在前端用表单提交即可,回顾我上次umi前端请求处理,代码如下
/**
* 成功登录获得token
* @param {*} params
*/
export async function fakeAccountLogin(params) {
return request('/login', {
method: 'POST',
data: params,
requestType: 'form' // 后端请求token需要表单的形式
});
}
很明显,request使用了requestType这个属性,决定了表单形式。所以能直接进入spring-security的默认方法了进行认证。
针对使用json模式
在这里我们只要稍微处理一下就可以
- 处理SpringConfig
原来:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// 让跨域配置被使用
.formLogin().successHandler(myAuthenticationSuccessHandler)
.failureHandler(myAuthenticationFailHandler)
.and()
.cors()
.and()
.csrf().disable()
// 添加异常处理
.exceptionHandling()
.authenticationEntryPoint(tokenExceptionHandler)
.accessDeniedHandler(accessDeniedException)
.and()
//关闭session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
// 拦截所有请求
.authorizeRequests()
.antMatchers(HttpMethod.POST,"/api/login").permitAll()
.antMatchers("/api/**").authenticated();
// 替换过滤器
http.addFilterAt(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
改变后:
http
.cors()
.and()
.csrf().disable()
// 添加异常处理
.exceptionHandling()
.authenticationEntryPoint(tokenExceptionHandler)
.accessDeniedHandler(accessDeniedException)
.and()
//关闭session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
// 拦截所有请求
.authorizeRequests()
.antMatchers(HttpMethod.POST,"/api/login").permitAll()
.antMatchers("/api/**").authenticated();
// 替换过滤器
http.addFilterAt(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
在这里一对比很明显就看到,已经去掉了form的处理形式,包括成功和失败的处理器
@Bean(name = "myAuthenticationManager")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
还有在config里面增加了认证管理器的bean,这个是最重要的。
- 增加loginController的处理方法
/**
* @Description LoginController
* @Author YiLong Wu
* @Date 2020/2/28 13:43
* @Version 1.0.0
*/
@RestController
@Slf4j
public class LoginController {
@Resource(name = "userDao")
private UserDao userDao;
@Resource(name = "myAuthenticationManager")
private AuthenticationManager myAuthenticationManager;
@PostMapping("/login")
public Response login(@RequestBody UserDto userDto) {
log.info("************{}",userDto);
User byUsername = userDao.findByUsername(userDto.getUsername());
if(byUsername == null || !MD5Util.string2MD5(userDto.getPassword()).equals(byUsername.getPassword())) {
return new Response(-1,"用户名或密码错误",null);
}
// 进行认证
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDto.getUsername(),userDto.getPassword());
Authentication authenticate = myAuthenticationManager.authenticate(usernamePasswordAuthenticationToken);
//从authentication中获取用户信息
JwtUser userDetail= (JwtUser)authenticate.getPrincipal();
// 生成token
String token = JwtUtil.generateToken(userDetail.getUsername());
return new Response(200, "登录成功",token);
}
}
在这里主要是自己处理了,账号密码的错误提示,用UsernamePasswordAuthenticationToken接受用户的个人信息,这在spring-security里也是这样操作的,然后调用认证管理器AuthenticationManager 进行认证即可,从而进入到UserDatailsService进行一系列的处理,如同表单提交一样的去自动处理,就像我上一章节画的流程图一样。