珠海单位网站建设,网站建设图片怎么动,百度指数怎么刷指数方法,揭阳seo快速排名jwt认证流程 SpringSecurity 认证过程 第一步#xff1a;
创建一个类实现UserDetailsService接口#xff0c;重写其中的方法
通过重写 public UserDetails loadUserByUsername(String username) 方法
从数据库校验用户输入的用户名 配置SecurityConfig
Bean注入 Passwor…jwt认证流程 SpringSecurity 认证过程 第一步
创建一个类实现UserDetailsService接口重写其中的方法
通过重写 public UserDetails loadUserByUsername(String username) 方法
从数据库校验用户输入的用户名 配置SecurityConfig
Bean注入 PasswordEncoder 通过BCryptPasswordEncoder();
Bean注入 DaoAuthenticationProvider
设置setUserDetailsService(userDetailsService); 走我们的UsersDetailsService
setPasswordEncoder(passwordEncoder());走我们注入的密码加密器 第二步
注入过滤器链 SecurityFilterChain
注入过滤器链忽略资源 WebSecurityCustomizer Configuration
public class SecurityConfig {Autowiredprivate UserDetailsService userDetailsService;Beanpublic PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}//注入UserDetailsServiceBeanpublic DaoAuthenticationProvider authenticationProvider(){DaoAuthenticationProvider auth new DaoAuthenticationProvider();auth.setUserDetailsService(userDetailsService);auth.setPasswordEncoder(passwordEncoder());return auth;}//注入认证管理器Beanpublic AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {return authenticationConfiguration.getAuthenticationManager();}//注入过滤连Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {//关闭csrf攻击防护http.csrf().disable();//配置认证请求所有请求都需要过滤http.authorizeRequests().anyRequest().authenticated();//关闭session会话http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);return http.build();}//注入过滤链忽略资源Beanpublic WebSecurityCustomizer securityCustomizer() throws Exception{return (web )-{web.ignoring().antMatchers(/user/login);};}
}
第三步
登录实现类 //认证管理器完成认证UsernamePasswordAuthenticationToken authenticationToken new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword());Authentication authenticate authenticationManager.authenticate(authenticationToken);if(Objects.isNull(authenticate)){throw new RuntimeException(用户名或密码错误);}//使用userid生成tokenUser loginUser (User) authenticate.getPrincipal();String userId loginUser.getId().toString();String token jwtUtils.generateToken(userId);//authenticate存入redisstringRedisTemplate.opsForValue().set(login:userId, JSON.toJSONString(loginUser));//把token响应给前端HashMapString,String map new HashMap();map.put(token,token);return new ResponseResult(200,登陆成功,map);
第四步
自己定义认证管理器jwtAuthenticationTokenFilter
最后把读取到的数据存入本地线程中
为什么放行因为放行之后有人处理
Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {Autowiredprivate StringRedisTemplate stringRedisTemplate;Autowiredprivate JwtUtils jwtUtils;Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {//获取tokenString token request.getHeader(token);if (!StringUtils.hasText(token)) {//放行filterChain.doFilter(request, response);//防止过滤链执行完在执行过滤器。return;}//解析tokenString userId;try {userId jwtUtils.getUserIdFromToken(token);} catch (Exception e) {e.printStackTrace();throw new RuntimeException(token非法);}//从redis中获取用户信息String redisKey login: userId;String json stringRedisTemplate.opsForValue().get(redisKey);User loginUser JSONObject.parseObject(json, User.class);if (Objects.isNull(loginUser)) {throw new RuntimeException(用户未登录);}//将用户信息存入SecurityContextHolder中//TODO 获取权限信息封装到Authenication中UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken new UsernamePasswordAuthenticationToken(loginUser,null,null);SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);//放行filterChain.doFilter(request,response);}
}
把我们的过滤器放入过滤器链
//配置认证过滤器http.addFilterAfter(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
因为jwtAuthenticationTokenFilter继承OncePerRequestFilter
为防止SpringBoot的FilterRegistrationBean执行OncePerRequestFilter过滤器
Configuration
public class WebConfig {Beanpublic FilterRegistrationBean filterRegistrationBean(JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter){FilterRegistrationBeanFilter filterFilterRegistrationBean new FilterRegistrationBean(jwtAuthenticationTokenFilter);filterFilterRegistrationBean.setEnabled(false);return filterFilterRegistrationBean;}
}第五步退出登录
从本地线程中获取数据直接删除最彻底的是前后端都删除 授权
在springsecurity配置类中开启注解
EnableWebSecurity //开启springSecurity框架
EnableGlobalMethodSecurity(prePostEnabled true)//开启权限注解开发
在controller上配置权限注解
例如
PreAuthorize(hasAuthority(test))
封装权限信息
注意实体类中的权限信息两个集合 /** 用户拥有权限* */TableField(exist false)private CollectionString menus;OverrideJSONField(serialize false)public Collection? extends GrantedAuthority getAuthorities() {CollectionGrantedAuthority collection new ArrayList();for (String str : menus){SimpleGrantedAuthority simpleGrantedAuthority new SimpleGrantedAuthority(str);collection.add(simpleGrantedAuthority);}return collection;}
在UserDetailServiceImpl中加入权限从数据库中获取多表连接这里是写死的
//返回user自动会和前台接收的密码比对这里不用比对密码CollectionString collection new ArrayList();collection.add(test);user.setMenus(collection);return user;
认证过滤器解析权限数据也加入权限信息
//将用户信息存入SecurityContextHolder中// 获取权限信息封装到Authenication中UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken new UsernamePasswordAuthenticationToken(loginUser,null,loginUser.getAuthorities());
自定义失败处理
如果是认证过程中出现的异常会被封装成AuthenticationException然后调用AuthenticationEntryPoint对象的方法去进行异常处理。
如果是授权过程中出现的异常会被封装成AccessDeniedException然后调用AccessDeniedHandler对象的方法去进行异常处理。
在SpringSecurity配置信息中注入 Autowiredprivate AuthenticationEntryPoint authenticationEntryPoint;Autowiredprivate AccessDeniedHandler accessDeniedHandler; http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint).accessDeniedHandler(accessDeniedHandler);
跨域问题解决
Configuration
public class CorsConfig implements WebMvcConfigurer {Overridepublic void addCorsMappings(CorsRegistry registry) {// 设置允许跨域的路径registry.addMapping(/**)// 设置允许跨域请求的域名.allowedOrigins(*)// 是否允许cookie.allowCredentials(true)// 设置允许的请求方式.allowedMethods(GET, POST, DELETE, PUT)// 设置允许的header属性.allowedHeaders(*)// 跨域允许时间.maxAge(3600);}
}
开启SpringSecurity的跨域访问 Overrideprotected void configure(HttpSecurity http) throws Exception {...//允许跨域http.cors();}