前置博客:JWT工具类
数据库:
@Slf4j @Component public class JwtAccessDeniedHandler implements AccessDeniedHandler { @Override public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws ServletException { log.info("用户访问没有授权资源:{}", e.getMessage()); response.setContentType("application/json;charset=utf-8"); response.setCharacterEncoding("utf-8"); try (PrintWriter out = response.getWriter();) { Result result = ResultUtil.fail("用户访问未授权资源").setCode(HttpServletResponse.SC_UNAUTHORIZED); out.write(JsonUtil.obj2String(result)); out.flush(); } catch (IOException exception) { log.error(e.getMessage()); e.printStackTrace(); } } }第二步:访问受限资源时未登录或未携带正确token时返回信息的EntryPoint
@Slf4j @Component public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws ServletException, IOException { log.info("登录失败or用户访问资源没有携带正确的token:{}", e.getMessage()); response.setContentType("application/json;charset=utf-8"); response.setCharacterEncoding("utf-8"); try (PrintWriter out = response.getWriter();) { Result result = ResultUtil.fail("用户访问资源没有携带正确的token").setCode(HttpServletResponse.SC_UNAUTHORIZED); out.write(JsonUtil.obj2String(result)); out.flush(); } catch (IOException exception) { log.error(e.getMessage()); e.printStackTrace(); } } }第三步:定义JWT认证过滤器
@Slf4j @Component public class JwtAuthenticationFilter extends OncePerRequestFilter { @Resource private JwtUtil jwtUtil; @Resource private UserDetailsServiceImpl userDetailsService; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { String token = request.getHeader(jwtUtil.getHeader()); log.info("header token:{}", token); //如果请求头中有token,则进行解析,并且设置认证信息 if (token != null && token.trim().length() > 0) { //根据token获取用户名 String username = jwtUtil.getSubjectFromToken(token); // 验证username,如果验证合法则保存到SecurityContextHolder if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { UserDetails userDetails = userDetailsService.loadUserByUsername(username); // JWT验证通过,使用Spring Security 管理 if (jwtUtil.validateToken(token, userDetails)) { //加载用户、角色、权限信息 UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, null, userDetails.getAuthorities()); authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(authentication); } } } //如果请求头中没有Authorization信息则直接放行 chain.doFilter(request, response); } }第四步:自定义UserDetailsService
@Service public class UserDetailsServiceImpl implements UserDetailsService { @Resource private UserService userService; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { MenuItemAuth menuItemAuth = userService.getAuthoritiesPermissions(username); System.out.println(JsonUtil.obj2String(menuItemAuth)); UserDetails userDetails = org.springframework.security.core.userdetails.User.withUsername(username) .password(menuItemAuth.getPassword()) .authorities(menuItemAuth.getAuth().split(",")) .build(); //UserDetails userDetails = new org.springframework.security.core.userdetails.User(username, passwordEncoder.encode("1234"), // AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_vip,user:list,user:update")); return userDetails; } }
相关的代码如下所示:
MenuItem.java
@Getter @Setter @Builder @ToString @AllArgsConstructor @NoArgsConstructor public class MenuItem { private Integer id; private String name; private String code; private Integer pid; }
MenuItemAuth.java
@Getter @Setter @ToString @Builder @AllArgsConstructor @NoArgsConstructor public class MenuItemAuth { List第五步:定义SpringSecurity配置类
@Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) public class SpringSecurityJwtConfig extends WebSecurityConfigurerAdapter { @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Resource private JwtAccessDeniedHandler jwtAccessDeniedHandler; @Resource private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; @Resource private JwtAuthenticationFilter jwtAuthenticationFilter; @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); // 禁用session http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); http.authorizeRequests() //login 不拦截 .antMatchers("/user/login").permitAll() .antMatchers("/user/login0").permitAll() .antMatchers("/init/redis").permitAll() .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() .antMatchers("/").permitAll() .anyRequest().authenticated(); //用户访问没有授权资源 http.exceptionHandling().accessDeniedHandler(jwtAccessDeniedHandler); //授权错误信息处理 //用户访问资源没有携带正确的token http.exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint); // 使用自己定义的拦截机制验证请求是否正确,拦截jwt http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); } }Controller
@RestController @RequestMapping("/authority") public class AuthorityController { @PostMapping("/login") public Result login(@RequestBody User user) { // 登陆验证 UsernamePasswordAuthenticationToken token0 = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()); Authentication authentication = authenticationManager.authenticate(token0); SecurityContextHolder.getContext().setAuthentication(authentication); //生成token,返回给客户端 MenuItemAuth menuItemAuth = userService.getAuthoritiesPermissions(user.getUsername()); UserDetails userDetails = org.springframework.security.core.userdetails.User.withUsername(user.getUsername()) .password(menuItemAuth.getPassword()) .authorities(menuItemAuth.getAuth().split(",")) .build(); String token = jwtUtil.generateToken(userDetails, user1.getId() + ""); return ResultUtil.success().setData("token", token); } @GetMapping("/fun1") @PreAuthorize("hasRole("vip")") public Result fun1() { return ResultUtil.success("fun1"); } @GetMapping("/fun2") @PreAuthorize("hasRole("admin")") public Result fun2() { return ResultUtil.success("fun2"); } @GetMapping("/fun3") @PreAuthorize("hasAuthority("user:list")") public Result fun3() { return ResultUtil.success("fun3"); } @GetMapping("/fun4") @PreAuthorize("hasAuthority("user:delete")") public Result fun4() { return ResultUtil.success("fun4"); } }
相关代码
@Service @CacheConfig(cacheManager = "cacheManager") public class UserServiceImpl extends ServiceImplimplements UserService { @Resource RedisService userRedisServiceImpl; @Resource private RoleService roleService; @Resource private UserPermissionService userPermissionService; @Resource private PermissionService permissionService; @Resource private RolePermissionService rolePermissionService; @Override public MenuItemAuth getAuthoritiesPermissions(String username) { List
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)