文章目录
- 0. 视频参考
- 1. 项目整合SpringSecurity
- 1. SecurityConfig
- 2. 登录成功
- 3. 登录失败
- 4. 查库认证
- 1. 全局异常
- 2. spring security认证
- 1. JWT认证过滤器
- 2. JWT认证异常处理
- 3. logout
- 3. spring security鉴权
- 1. 代码速览
- 4. 前端实现"记住密码功能"
- 0. 先查找cookie中是否有记录
- 1. js-cookie
- 2. jsencrypt
- 5. 动态路由和导航
- 6. 用户 - 角色 - 菜单
- 1. 用户角色授权
1. 项目整合SpringSecurity
1. SecurityConfig
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
- 密码加密
2. 登录成功
- 注入到SecurityConfig中
// 生成jwt token
String token=JwtUtils.genJwtToken(username);
3. 登录失败
- 注入到SecurityConfig中
- 设置报错
String message=e.getMessage();
// 判断异常 这里属于验证异常
if(e instanceof BadCredentialsException){
message="用户名或者密码错误!";
}
// 除验证异常 都统一返回
outputStream.write(JSONUtil.toJsonStr(R.error(message)).getBytes("UTF-8"));
4. 查库认证
- 注入到SecurityConfig中
- 注入到JwtAuthenticationFilter中 【权限信息】
1. 全局异常
- Json格式的异常。
import com.java1234.entity.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 全局异常处理 统一返回一个格式
*/
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = RuntimeException.class)
public R handler(RuntimeException e){
// 日志输出
log.error("运行时异常:----------------{}", e.getMessage());
System.out.println("运行时异常:");
return R.error(e.getMessage());
}
}
2. spring security认证
- JWT
1. JWT认证过滤器
- 注入到SecurityConfig中
2. JWT认证异常处理
- 注入到SecurityConfig中
import cn.hutool.json.JSONUtil;
import com.java1234.entity.R;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* jwt认证异常处理
*/
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
httpServletResponse.setContentType("application/json;charset=UTF-8");
ServletOutputStream outputStream = httpServletResponse.getOutputStream();
outputStream.write(JSONUtil.toJsonStr(R.error(HttpServletResponse.SC_UNAUTHORIZED,"认证失败,请登录!")).getBytes("UTF-8"));
outputStream.flush();
outputStream.close();
}
}
3. logout
import cn.hutool.json.JSONUtil;
import com.java1234.entity.R;
import com.java1234.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 自定义退出处理
*/
@Component
public class JwtLogoutSuccessHandler implements LogoutSuccessHandler {
@Autowired
private SysUserService sysUserService;
@Override
public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
httpServletResponse.setContentType("application/json;charset=UTF-8");
ServletOutputStream outputStream = httpServletResponse.getOutputStream();
outputStream.write(JSONUtil.toJsonStr(R.ok("退出成功")).getBytes("UTF-8"));
outputStream.flush();
outputStream.close();
}
}
3. spring security鉴权
1. 代码速览
- MyUserDetailServiceImpl
- 在设置角色权限之后 在接口上面加权限
- 只有admin才能访问接口
- 有这个权限才能访问
/**
* 添加或者修改
* @param sysUser
* @return
*/
@PostMapping("/save")
// 设置权限
@PreAuthorize("hasAuthority('system:user:add')"+"||"+"hasAuthority('system:user:edit')")
public R save(@RequestBody @Valid SysUser sysUser){
if(sysUser.getId()==null || sysUser.getId()==-1){
sysUser.setCreateTime(new Date());
sysUser.setPassword(bCryptPasswordEncoder.encode(sysUser.getPassword()));
sysUserService.save(sysUser);
}else{
sysUser.setUpdateTime(new Date());
sysUserService.updateById(sysUser);
}
return R.ok();
}
- SysUserServiceImpl
- getUserAuthorityInfo
4. 前端实现"记住密码功能"
<el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
- 密码需要加密
0. 先查找cookie中是否有记录
- 封装方法
function getCookie() {
const username = Cookies.get("username");
const password = Cookies.get("password");
const rememberMe = Cookies.get("rememberMe");
loginForm.value = {
username: username === undefined ? loginForm.value.username : username,
password: password === undefined ? loginForm.value.password : decrypt(password),
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
};
}
1. js-cookie
- install
2. jsencrypt
- 私钥解密
- 公钥加密
5. 动态路由和导航
6. 用户 - 角色 - 菜单
1. 用户角色授权
/**
* 用户角色授权
* @param userId
* @param roleIds
* @return
*/
@Transactional
@PostMapping("/grantRole/{userId}")
@PreAuthorize("hasAuthority('system:user:role')")
public R grantRole(@PathVariable("userId") Long userId,@RequestBody Long[] roleIds){
List<SysUserRole> userRoleList=new ArrayList<>();
Arrays.stream(roleIds).forEach(r -> {
SysUserRole sysUserRole = new SysUserRole();
sysUserRole.setRoleId(r);
sysUserRole.setUserId(userId);
userRoleList.add(sysUserRole);
});
sysUserRoleService.remove(new QueryWrapper<SysUserRole>().eq("user_id",userId));
sysUserRoleService.saveBatch(userRoleList);
redisUtil.removeByPrex(Constant.AUTHORITY_KEY);
return R.ok();
}