zeromemos
最好的学习方法就是输出所学的知识Spring Security权限校验 修改登入过滤器
需要修改过滤器,在登入请求成功后将权限数据存Redis里供后面的操作查询
原过滤器代码http://www.zeromemos.com/index/article/read/id/371.html
修改后如下
package com.atguigu.security.filter;
import com.alibaba.fastjson.JSON;
import com.atguigu.common.jwt.JwtHelper;
import com.atguigu.common.result.ResponseUtil;
import com.atguigu.common.result.Result;
import com.atguigu.common.result.ResultCodeEnum;
import com.atguigu.security.custom.CustomUser;
import com.atguigu.vo.system.LoginVo;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {
private RedisTemplate redisTemplate;
//构造方法
public TokenLoginFilter(AuthenticationManager authenticationManager,
RedisTemplate redisTemplate) {
this.setAuthenticationManager(authenticationManager);
//提交方式可以不仅仅是Post
this.setPostOnly(false);
//指定登录接口及提交方式,可以指定任意路径
this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/admin/system/index/login","POST"));
this.redisTemplate = redisTemplate;
}
/**
* 获取用户提交的用户名和密码进行登录认证
* @param req
* @param res
* @return
* @throws AuthenticationException
*/
@Override
public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res)
throws AuthenticationException {
try {
//用流的方式从请求里得到LoginVo登入对象
LoginVo loginVo = new ObjectMapper().readValue(req.getInputStream(), LoginVo.class);
//将用户名和密码封装成Authentication对象
Authentication authenticationToken = new UsernamePasswordAuthenticationToken(loginVo.getUsername(), loginVo.getPassword());
//调用authenticate()进行认证
return this.getAuthenticationManager().authenticate(authenticationToken);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 登录成功返回token
* @param request
* @param response
* @param chain
* @param auth
* @throws IOException
* @throws ServletException
*/
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
Authentication auth) throws IOException, ServletException {
//得到当前用户对象
CustomUser customUser = (CustomUser) auth.getPrincipal();
//传入ID和用户名生成token
String token = JwtHelper.createToken(customUser.getSysUser().getId(), customUser.getSysUser().getUsername());
//获取当前用户的权限数据放到Redis里,key:username value:权限数据
redisTemplate.opsForValue().set(customUser.getUsername(),
JSON.toJSONString(customUser.getAuthorities()));
Map<String, Object> map = new HashMap<>();
map.put("token", token);
ResponseUtil.out(response, Result.ok(map));
}
/**
* 登录失败
* @param request
* @param response
* @param e
* @throws IOException
* @throws ServletException
*/
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
AuthenticationException e) throws IOException, ServletException {
if(e.getCause() instanceof RuntimeException) {
ResponseUtil.out(response, Result.build(null, 204, e.getMessage()));
} else {
ResponseUtil.out(response, Result.build(null, ResultCodeEnum.LOGIN_ERROR));
}
}
}
评论区
关于我们
本站主要用于记录个人学习笔记,网站开发中,如需以前站内资料请加QQ群272473835索取。注册账号仅提供回帖功能,可不注册!