【Spring Security】安全框架学习(五)

2.3.3.3 登陆接口

接下我们需要自定义登陆接口,然后让SpringSecurity对这个接口放行。

2.3.2 准备工作 中我们提供了一个jwt工具类,里面有3种重载形式,详情参考之前的源码。如果要使用jwt工具类,jdk1.8以上的版本可能需要导入这三个包 jjwt-api, jjwt-impl, jwt-jackson,jdk1.8一般来说没必要导。

在接口中我们通过AuthenticationManager的authenticate方法来进行用户认证,所以需要在SecurityConfig中配置把AuthenticationManager注入容器。

认证成功的话要生成一个jwt,放入响应中返回。并且为了让用户下回请求时能通过jwt识别出具体的是哪个用户,我们需要把用户信息存入redis,可以把用户id作为key。

package service;

public interface LoginService {
    public ResponseResult login(User user);
}
package service.impl;

import ...
    
public class LoginService implements LoginService{
    
    @Autowired
    private AuthenticationManager authenticationManager;
    
    @Autowired
    private RedisCache redisCache;

    @Override
	public ResponseResult login(User user) {
		//AuthenticationManager authenticate进行用户认证
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationTokena(user.getUserName(),user.getPassword());
		Authentication authenticate = authenticationManager.authenticate(authenticationToken);

        //如果认证没通过,给出对应的提示
        if(Objects.isNull(authenticate)) {
            throw new RuntimeException("登陆失败");
        }
        
        //如果认证通过了。使用userId生成一个jwt,jwt存入ResponseResult返回
        LoginUser loginUser = (LoginUser) authenticate. getPrincipal();
        String userId = loginUser.getUser.getId().toString();
        String jwt = JwtUtil.createJWT(userId);
        Map<String,String> map = new HashMap()<>;
        map.put("token",jwt); 
        
        //把完整的用户信息存入redis,userId作为key
        redisCache.setCacheObject("login:"+userId,loginUser);
		return new ResponseResult(200,"登陆成功",map);
    }

}

这里的代码使用了redis,如果在前面的yaml文件中没有配置的话,这里要记得配置redis和添加对应的依赖,同时也要记得将redis启动。

package controller;

import...

@RestController
public class LoginController {
    
	@Autowired
	private LoginServcie loginServcie;
    
	@PostMapping("/user/login")
	public ResponseResult login(@RequestBody User user){
		return loginservcie.login(user);
    }
}

在这里,其实不用自定义登陆接口,实现认证签发jwt的,默认的认证拦截器,里面的认证成功处理器方法和认证失败处理器方法,是可以被替换的,自定义这两个方法,在那里面做就ok了。

一些问题的解决方案

①在测试工具中测试时返回空白:

​ 这里是空白的原因:重写void configure(AuthenticationManagerBuilder auth)方法。

②使用的虚拟机的redis:

​ 如果使用虚拟机的Redis,可能需要导入连接池依赖。

③报错403的原因:

​ 403是没有认证成功,说明用户名和密码与数据库不一致,有可能是密码不是bcype加密过的,需要再数据库中存储加密后的密码。或者没有权限,禁止访问,也就是说,你没有相应的权限或角色。

④无法访问云服务器的redis:

​ 检查linux是否关闭防火墙。

⑤接口测试工具报错:

​ 测试接口的有错误的,看看是不是requestBody选了text,应该是JSON。

end
  • 作者:dicraft(联系作者)
  • 更新时间:2022-08-27 20:47
  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 转载声明:如果是转载栈主转载的文章,请附上原文链接
  • 评论

    新增邮件回复功能,回复将会通过邮件形式提醒,请填写有效的邮件!