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

本文介绍如何自定义登录接口并使用JWT进行用户身份验证的过程。包括如何配置Spring Security来支持JWT认证,以及如何利用Redis缓存用户信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 controllerimport...

@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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值