当前位置: 首页 > news >正文

学网站开发需要多久网站优化人员通常会将目标关键词放在网站首页中的

学网站开发需要多久,网站优化人员通常会将目标关键词放在网站首页中的,网站如何做微信支付,wordpress主题开发导航制作一、初步理解 SpringSecurity的原理其实就是一个过滤器链,内部包含了提供各种功能的过滤器。 当前系统中SpringSecurity过滤器链中有哪些过滤器及它们的顺序。 核心过滤器: (认证)UsernamePasswordAuthenticationFilter:负责处理…

一、初步理解

SpringSecurity的原理其实就是一个过滤器链,内部包含了提供各种功能的过滤器。

当前系统中SpringSecurity过滤器链中有哪些过滤器及它们的顺序。

核心过滤器:

  • (认证)UsernamePasswordAuthenticationFilter:负责处理我们在登陆页面填写了用户名密码后的登陆请求
  • ExceptionTranslationFilter:处理过滤器链中抛出的任何AccessDeniedException和 AuthenticationException 
  • (授权)FilterSecurityInterceptor:负责权限校验的过滤器

二、Token(Jwt)登录校验流程

三、具体认证授权细节

下图是UsernamePasswordAuthenticationFilter处理用户名、密码,然后将用户名、密码、权限信息封装到Authentication对象中,再放到SecurityContextHolder中。

Authentication接口: 它的实现类,表示当前访问系统的用户,封装了用户相关信息。

AuthenticationManager接口:定义了认证Authentication的方法

UserDetailsService接口:加载用户特定数据的核心接口。里面定义了一个根据用户名查询用户信息的 方法。

UserDetails接口:提供核心用户信息。通过UserDetailsService根据用户名获取处理的用户信息要封装 成UserDetails对象返回。然后将这些信息封装到Authentication对象中。

认证

  1. 当用户登录时,前端将用户输入的用户名、密码信息传输到后台,后台用一个类对象将其封装起来,通常使用的是UsernamePasswordAuthenticationToken这个类。
  2. 程序负责验证这个类对象。验证方法是调用Service根据username从数据库中取用户信息到实体类的实例中,比较两者的密码,如果密码正确就成功登陆,同时把包含着用户的用户名、密码、所具有的权限等信息(用户id、昵称、是否管理员)的类对象放到SecurityContextHolder(安全上下文容器,类似Session)中去。
  3. 用户访问一个资源的时候,首先判断是否是受限资源。如果是的话还要判断当前是否未登录,没有的话就跳到登录页面。
  4. 如果用户已经登录,访问一个受限资源的时候,程序要根据url去数据库中取出该资源所对应的所有可以访问的角色,然后拿着当前用户的所有角色一一对比,判断用户是否可以访问(这里就是和权限相关)。

授权

  1. 在SpringSecurity中,会使用默认的FilterSecurityInterceptor来进行权限校验。在FilterSecurityInterceptor中会从SecurityContextHolder获取其中的Authentication,然后获取其中的权限信息。当前用户是否拥有访问当前资源所需的权限。
  2. 所以我们在项目中只需要把当前登录用户的权限信息也存入Authentication。然后设置我们的资源所需要的权限即可。

自定义登录认证接口:①调用ProviderManager的方法进行认证;②如果认证通过生成jwt;③把用户信息存入redis中

自定义权限信息查询:在UserDetailsService这个实现类中去查询数据库

四、自定义权限查询

修改UsernamePasswordAuthenticationFilter上图最右边的授权部分。

 1.自定义登陆接口

@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@PostMapping("/login")public R login(@RequestBody User user) {String jwt = userService.login(user);if (StringUtils.hasLength(jwt)) {return R.ok().message("登陆成功").data("token", jwt);}return R.error().message("登陆失败");}
}

 2.配置数据库校验登录用户

从之前的分析我们可以知道,我们可以自定义一个UserDetailsService,让SpringSecurity使用我们的 UserDetailsService。我们自己的UserDetailsService可以从数据库中查询用户名和密码。

创建一个类实现UserDetailsService接口,重写loadUserByUsername方法

@Service
public class UserDetailsServiceImpl implements UserDetailsService {@Autowiredprivate UserMapper userMapper;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//查询用户信息QueryWrapper<User> queryWrapper=new QueryWrapper<>();queryWrapper.eq("user_name",username);User user = userMapper.selectOne(queryWrapper);//如果没有查询到用户,就抛出异常if(Objects.isNull(user)){throw  new RuntimeException("用户名或密码错误");}//TODO 查询用户对应的权限信息细节见SpringSecurity(二)——授权实现//如果有,把数据封装成UserDetails对象返回return new LoginUser(user);}
}

五、Jwt认证过滤器(自定义过滤器)

(1)在接口中我们通过AuthenticationManager的authenticate方法来进行用户认证,所以需要在 SecurityConfig中配置把AuthenticationManager注入容器

@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig{/*** 登录时需要调用AuthenticationManager.authenticate执行一次校验*/@Beanpublic AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {return config.getAuthenticationManager();}
}

 (2)登录的业务逻辑层实现类

第一次登录,生成jwt存入redis

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {@Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Overridepublic String login(User user) {//1.封装Authentication对象 ,密码校验,自动完成UsernamePasswordAuthenticationToken authentication =new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword());//2.进行校验Authentication authenticate = authenticationManager.authenticate(authentication);//3.如果authenticate为空if (Objects.isNull(authenticate)) {throw new RuntimeException("登录失败"); //TODO 登录失败}//4.得到用户信息LoginUser loginUser = (LoginUser) authenticate.getPrincipal();//生成jwt,使用fastjson的方法,把对象转成字符串String loginUserString = JSON.toJSONString(loginUser);//调用JWT工具类,生成jwt令牌String jwt = JwtUtils.createJWT(loginUserString, null);//5.把生成的jwt存到redisString tokenKey = "token_" + jwt;stringRedisTemplate.opsForValue().set(tokenKey, jwt, JwtUtils.JWT_TTL / 1000);Map<String, Object> map = new HashMap<>();map.put("token", jwt);map.put("username", loginUser.getUsername());return jwt;}
}

(3)jwt认证校验过滤器

我们需要自定义一个过滤器,这个过滤器会去获取请求头中的token,对token进行解析取出其中的 userid。 使用userid去redis中获取对应的LoginUser对象。

然后封装Authentication对象存入SecurityContextHolder

/*** token验证过滤器   //每一个servlet请求,只会执行一次*/
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {@Autowiredprivate LoginFailureHandler loginFailureHandler;@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,FilterChain filterChain)throws ServletException, IOException {try {//1.获取当前请求的url地址String url = request.getRequestURI();//如果当前请求不是登录请求,则需要进行token验证if (!url.equals("/user/login")) {//2.验证tokenthis.validateToken(request);}} catch (AuthenticationException e) {System.out.println(e);loginFailureHandler.onAuthenticationFailure(request, response, e);}//3.登录请求不需要验证tokendoFilter(request, response, filterChain);}/*** 验证token*/private void validateToken(HttpServletRequest request) throws AuthenticationException {//1.获取tokenString token = request.getHeader("Authorization");//如果请求头部没有获取到token,则从请求的参数中进行获取if (ObjectUtils.isEmpty(token)) {token = request.getParameter("Authorization");}if (ObjectUtils.isEmpty(token)) {throw new CustomerAuthenticationException("token不存在");}//2.redis进行校验String redisStr = stringRedisTemplate.opsForValue().get("token_" + token);if(ObjectUtils.isEmpty(redisStr)) {throw new CustomerAuthenticationException("token已过期");}//3.解析tokenClaims claims = null;try {claims = JwtUtils.parseJWT(token);} catch (Exception e) {throw new CustomerAuthenticationException("token解析失败");}//4.获取到用户信息String loginUserString = claims.getSubject();//把字符串转成loginUser对象LoginUser loginUser = JSON.parseObject(loginUserString, LoginUser.class);//创建身份验证对象UsernamePasswordAuthenticationToken authenticationToken =new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());//5.设置到Spring Security上下文SecurityContextHolder.getContext().setAuthentication(authenticationToken);}
}

(4)把jwt过滤器注册到springsecurity过滤器链中

放在UsernamePasswordAuthenticationFilter前面

@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig{//自定义jwt校验过滤器@Autowiredprivate JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {//配置关闭csrf机制http.csrf(csrf -> csrf.disable());//登陆失败处理器http.formLogin(configurer -> {configurer.failureHandler(loginFailureHandler);});http.sessionManagement(configurer ->// STATELESS(无状态): 表示应用程序是无状态的,不会创建会话。configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS));//请求拦截方式http.authorizeHttpRequests(auth -> auth.requestMatchers("/user/login").permitAll().anyRequest().authenticated());//!!!!!注册jwt过滤器!!!!!!!http.addFilterBefore(jwtAuthenticationTokenFilter,      UsernamePasswordAuthenticationFilter.class);//异常处理器http.exceptionHandling(configurer -> {configurer.accessDeniedHandler(customerAccessDeniedHandler);configurer.authenticationEntryPoint(anonymousAuthenticationHandler);});return http.build();   //允许跨域}/*** 登录时需要调用AuthenticationManager.authenticate执行一次校验*/@Beanpublic AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {return config.getAuthenticationManager();}
}
http://www.hkea.cn/news/716727/

相关文章:

  • 辽宁建设工程信息网业绩认定武汉网站优化公司
  • 莱芜都市人才网上海网站seo公司
  • 广州做鞋的网站怎么让某个关键词排名上去
  • 温州平阳县网站建设兼职东莞网络推广哪家公司奿
  • 做单页网站价格微信朋友圈广告在哪里做
  • 濮阳家电网站建设一般开车用什么导航最好
  • html5 图片展示网站大作设计网站
  • 河北正规网站建设比较百度一下你就知道官页
  • 企业网站建设哪家服务好福州网站关键词推广
  • 惠州悦商做网站软件开发一般需要多少钱
  • 做衣服外单网站优化大师官方正版下载
  • 专门做酒店的网站百度排行
  • 上海做手机网站建设盐城网站优化
  • html论坛模板东营seo整站优化
  • 天津网站建设582345网址导航桌面版
  • 东莞纸箱厂东莞网站建设经典模板网站建设
  • 贺州同城购物网站建设中国网站排名100
  • 黄骅港旅游景点爱站网seo工具包
  • 网站 图文混编提高网站搜索排名
  • 北京怀柔网站制作教育机构
  • 网站建设费 大创友链交换平台
  • o2o商城网站系统开发微信群拉人的营销方法
  • 帝国cms做淘宝客网站网页设计用什么软件
  • 营销型网站建设的优缺点视频优化软件
  • 珠海响应式网站建设推广公司网络营销发展方案策划书
  • 中国人自己的空间站每日英语新闻
  • 教师可以做网站吗seo常用工具包括
  • 武山建设局网站什么是seo
  • 做文案需要用到的网站全网模板建站系统
  • 苏州乡村旅游网站建设策划书网站建设百度推广