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

网站开发设计需求html网站模板免费

网站开发设计需求,html网站模板免费,飞色网站商城怎么做,今日油价92汽油价格最新消息SpringSecurity简介 spring Security是什么? Spring Security 是一个强大且高度可定制的身份验证和访问控制框架,用于保护基于Spring的应用程序。它是Spring项目的一部分,旨在为企业级系统提供全面的安全性解决方案。 一个简单的授权和校验…

 SpringSecurity简介

spring Security是什么?

Spring Security 是一个强大且高度可定制的身份验证和访问控制框架,用于保护基于Spring的应用程序。它是Spring项目的一部分,旨在为企业级系统提供全面的安全性解决方案。

一个简单的授权和校验流程

检验流程

总流程 

SpringSecurity使用

认证 

对应依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>

在自定义检验的时候,主要就是实现UserDetailsService接口,重写loadUserByUserName方法,在该方法中就是去检验账号和密码的准确性。(一般都是进行数据库的查询校验,默认的密码格式就是 ·{}密码·)

前后端分离项目登录流程

1.在springSecurity中我们的需要设置密文的配置,在项目中大多都是使 BCryptPasswordEncoder类来做密码的加密。

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}}

2.创建对应的login接口和service

Controller 

@RestController
@RequestMapping("/user")
public class LoginController {@AutowiredLoginService loginService;@PostMapping("/login")public ResponseResult login(@RequestBody User user) {return loginService.login(user);}
}

Service

@Service
public class LoginServiceImpl implements LoginService {@Autowiredprivate AuthenticationManager authenticationManager;@AutowiredRedisCache redisCache;@Overridepublic ResponseResult login(User user) {//authenticationManager authenticate进行用户验证UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword());Authentication authenticate = authenticationManager.authenticate(authenticationToken);//执行我们对饮的认证方法,在该方法中会返回LoginUser类型的数据//如果没有通过通过直接抛异常if(ObjectUtil.isEmpty(authenticate)) {throw new RuntimeException("登录失败");}//如果成功直接生成token,将其也map返回LoginUser loginUser = (LoginUser)authenticate.getPrincipal();String jwt = JwtUtil.createJWT(loginUser.getUser().getId().toString());Map<String, String> data = new HashMap<>();data.put("token", jwt);redisCache.setCacheObject(loginUser.getUser().getId().toString(), user);//返回tokenreturn new ResponseResult(200, "登录成功", data);}
}

因为AuthenticationManager默认不在ioc中,我们需要将其配置到ioc中,并且配置对应的校验规则。在里面就包括 无效校验的接口(比如:登录接口)和其他一些前后端分离的配置。

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}//将AuthenticationManager配置到ioc中@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}//配置权限规则,主要就睡要放行登录接口,不然登录接口都会被了解,以及其他不要的前后端分离的配置@Overrideprotected void configure(HttpSecurity http) throws Exception {http//由于是前后端分离项目,所以要关闭csrf.csrf().disable()//由于是前后端分离项目,所以session是失效的,我们就不通过Session获取SecurityContext.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()//指定让spring security放行登录接口的规则.authorizeRequests()// 对于登录接口 anonymous表示允许匿名访问.antMatchers("/user/login").anonymous()// 除上面外的所有请求全部需要鉴权认证.anyRequest().authenticated();}
}

进行测试,校验成功。

前后端分离项目校验流程

1.创建一个校验过滤器

@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {@AutowiredRedisCache redisCache;@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {//获取token,token会存在header中String token = request.getHeader("token");if(StrUtil.isEmpty(token)) {//由后续的拦截器进行拦截filterChain.doFilter(request, response);//后续会返回回来,需要return,不然会执行下面的语句return ;}//解析tokenString userId;try {Claims claims = JwtUtil.parseJWT(token);userId = claims.getSubject();if(StringUtil.isNullOrEmpty(userId)) {throw new RuntimeException("token解析失败");}} catch (Exception e) {throw new RuntimeException(e);}//从redis中获取用户的信息LoginUser loginUser = redisCache.getCacheObject(userId);if(ObjectUtil.isEmpty(loginUser)) {throw new RuntimeException("Redis中没有用户信息");}//将数据存储到SecurityContextHolderUsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, null);SecurityContextHolder.getContext().setAuthentication(authenticationToken);//放行filterChain.doFilter(request, response);}
}

使用三个参数的UsernamePasswordAuthenticationToken的构造器,该构造器会设置授权成功。

2.将过滤器设置到用户验证过滤器之前

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@AutowiredJwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;//设置加密方式@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}//将AuthenticationManager配置到ioc中@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}//配置权限规则,主要就睡要放行登录接口,不然登录接口都会被了解,以及其他不要的前后端分离的配置@Overrideprotected void configure(HttpSecurity http) throws Exception {http//由于是前后端分离项目,所以要关闭csrf.csrf().disable()//由于是前后端分离项目,所以session是失效的,我们就不通过Session获取SecurityContext.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()//指定让spring security放行登录接口的规则.authorizeRequests()// 对于登录接口 anonymous表示允许匿名访问.antMatchers("/user/login").anonymous()// 除上面外的所有请求全部需要鉴权认证.anyRequest().authenticated();//将过滤器添加到用户登录处理器之前http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);}
}

进行测试,将成功的token放入header中,进行校验。最终校验成功。

退出登录流程

1.编写退出登录接口

@RestController
@RequestMapping("/user")
public class LoginController {@AutowiredLoginService loginService;@RequestMapping("/logout")public ResponseResult logout() {return loginService.logout();}
}

2.编写service实现类,删除redis中用户信息的数据,即可完成退出登录操作。在解析的时候redis中的数据不存在就会直接被拦截。

@Service
public class LoginServiceImpl implements LoginService {@Autowiredprivate AuthenticationManager authenticationManager;@AutowiredRedisCache redisCache;@Overridepublic ResponseResult logout() {//在进入此接口时会先进行解析,成功之后才会执行logout,此时SecurityContextHolder中是有用户信息的UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();LoginUser loginUser = (LoginUser) authentication.getPrincipal();if(ObjectUtil.isEmpty(loginUser)) {throw new RuntimeException("LoginUser不存在");}//把redis中的数据删除之后,下次解析的时候就会直接报错,在解析中我们对redis的数据做了判空的操作redisCache.deleteObject(loginUser.getUser().getId().toString());return new ResponseResult(200, "退出登录成功", null);}
}

进行测试,最终成功。

授权

1.开启授权功能,在对应的security的配置类中添加对应的注解。

@EnableGlobalMethodSecurity(prePostEnabled = true) //开启授权

2.为接口设置对应的权限需求

@RestController
public class baseController {@RequestMapping("/hello")//拥有text倾向才能访问@PreAuthorize("hasAuthority('text')")public String hello() {return "hello!";}
}

3.在用户进行认证的时候查询用户拥有的权限集合,并设置到 authenticationToken中。

  • 在返回类型中设置权限集合属性和重写获取权限集合方法。
@Data
@NoArgsConstructor
public class LoginUser implements UserDetails {private User user;private List<String> authorities2String;public LoginUser(User user, List<String> authorities2String) {this.user = user;this.authorities2String = authorities2String;}@JSONField(serialize = false)private List<GrantedAuthority> authorities;@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {if(CollUtil.isEmpty(authorities)) {return authorities2String.stream().map(item -> new SimpleGrantedAuthority(item)).collect(Collectors.toList());}return authorities;}@Overridepublic String getPassword() {return user.getPassword();}@Overridepublic String getUsername() {return user.getUserName();}@Overridepublic boolean isAccountNonExpired() {return true;}@Overridepublic boolean isAccountNonLocked() {return true;}@Overridepublic boolean isCredentialsNonExpired() {return true;}@Overridepublic boolean isEnabled() {return true;}
}
  • 在校验Service中查询对应的权限列表。
@Service
public class UserService implements UserDetailsService {@AutowiredUserMapper userMapper;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {QueryWrapper<com.huang.springsecuritydemo.entity.User> userQueryWrapper = new QueryWrapper<>();userQueryWrapper.eq("user_name", username);com.huang.springsecuritydemo.entity.User user = userMapper.selectOne(userQueryWrapper);if(ObjectUtil.isEmpty(user)) {throw new RuntimeException("用户不存在");}//todo 查询并设置对应的权限信息//模拟查到的权限信息List<String> data = Arrays.asList("test", "text");return new LoginUser(user, data);}
}
  • 在JWT认证中向authenticationToken中设置权限集合,最终设置到SecurityContextHolder中。
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {@AutowiredRedisCache redisCache;@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {//获取token,token会存在header中String token = request.getHeader("token");if(StrUtil.isEmpty(token)) {//由后续的拦截器进行拦截filterChain.doFilter(request, response);//后续会返回回来,需要return,不然会执行下面的语句return ;}//解析tokenString userId;try {Claims claims = JwtUtil.parseJWT(token);userId = claims.getSubject();if(StringUtil.isNullOrEmpty(userId)) {throw new RuntimeException("token解析失败");}} catch (Exception e) {throw new RuntimeException(e);}//从redis中获取用户的信息LoginUser loginUser = redisCache.getCacheObject(userId);if(ObjectUtil.isEmpty(loginUser)) {throw new RuntimeException("Redis中没有用户信息");}//将数据存储到SecurityContextHolder//todo 设置对应的权限信息UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());SecurityContextHolder.getContext().setAuthentication(authenticationToken);//放行filterChain.doFilter(request, response);}
}

进行测试,授权成功。

RDAB模型例子(基本通用,看进行二次开发)

1.创建五个数据库 用户表,角色表,权限表,用户角色关联表,角色权限关联表。

2.编写SQL语句查询用户的所有权限,并使用 mybatis-plus进行封装为一个函数进行调用。

SELECTDISTINCT m.`perms`FROMsys_user_role urLEFT JOIN `sys_role` r ON ur.`role_id` = r.`id`LEFT JOIN `sys_role_menu` rm ON ur.`role_id` = rm.`role_id`LEFT JOIN `sys_menu` m ON m.`id` = rm.`menu_id`WHEREuser_id = #{id}AND r.`status` = 0AND m.`status` = 0

3.在校验是进行调用,并返回对应的权限集合。

@Service
public class UserService implements UserDetailsService {@AutowiredUserMapper userMapper;@AutowiredMenuMapper menuMapper;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {QueryWrapper<com.huang.springsecuritydemo.entity.User> userQueryWrapper = new QueryWrapper<>();userQueryWrapper.eq("user_name", username);com.huang.springsecuritydemo.entity.User user = userMapper.selectOne(userQueryWrapper);if(ObjectUtil.isEmpty(user)) {throw new RuntimeException("用户不存在");}//todo 查询并设置对应的权限信息List<String> data = menuMapper.selectPermsByUserId(user.getId());return new LoginUser(user, data);}
}

修改接口所需要的权限。

@RestController
public class baseController {@RequestMapping("/hello")//拥有text倾向才能访问@PreAuthorize("hasAuthority('system:test:list')")public String hello() {return "hello!";}
}

进行测试,最终成功。

自定义失败处理

1.自定义授权异常处理器和校验异常处理器。

  • 校验异常处理器
//校验失败异常处理器
@Component
public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint {@Overridepublic void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {//创建统一的返回对象,设置到response中ResponseResult responseResult = new ResponseResult(HttpStatus.HTTP_UNAUTHORIZED, "校验失败!");String json = JSON.toJSONString(responseResult);//将统一的结果设置到Response中,本质就是将对应的数据设置到response中WebUtil.renderString(response, json);}
}
  • 授权异常处理器

//授权失败异常处理器
@Component
public class AccessDeniedHandlerImpl implements AccessDeniedHandler {@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {ResponseResult responseResult = new ResponseResult(HttpStatus.HTTP_UNAUTHORIZED, "授权失败!");String json = JSON.toJSONString(responseResult);WebUtil.renderString(response, json);}
}

对应的webUtil工具类

public class WebUtil {/*** 将字符串渲染到客户端** @param response 渲染对象* @param string 待渲染的字符串* @return null*/public static String renderString(HttpServletResponse response, String string) {try{response.setStatus(200);response.setContentType("application/json");response.setCharacterEncoding("utf-8");//将结果json以流的形式写入response中response.getWriter().print(string);}catch (IOException e){e.printStackTrace();}return null;}
}

2.将自定义的异常处理器进行配置

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {@AutowiredJwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;@AutowiredAuthenticationEntryPoint authenticationEntryPoint;@AutowiredAccessDeniedHandler accessDeniedHandler;@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}//将AuthenticationManager配置到ioc中@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}//配置权限规则,主要就睡要放行登录接口,不然登录接口都会被了解,以及其他不要的前后端分离的配置@Overrideprotected void configure(HttpSecurity http) throws Exception {http//由于是前后端分离项目,所以要关闭csrf.csrf().disable()//由于是前后端分离项目,没有session.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()//指定让spring security放行登录接口的规则.authorizeRequests()// 对于登录接口 anonymous表示允许匿名访问, permitAll就是 登录和没登录都可以访问.antMatchers("/user/login").anonymous() //匿名访问,未登录就可以访问// 除上面外的所有请求全部需要鉴权认证后访问.anyRequest().authenticated();//将过滤器添加到用户登录处理器之前http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);//设置自定义的异常处理器http.exceptionHandling()//校验异常处理器.authenticationEntryPoint(authenticationEntryPoint)//授权异常处理器.accessDeniedHandler(accessDeniedHandler);}
}

进行测试,异常显示成功。

允许跨域

1.开启springboot的允许跨域。

@Configuration
public class CorsConfig implements WebMvcConfigurer {@Override//重写spring提供的WebMvcConfigurer接口的addCorsMappings方法public void addCorsMappings(CorsRegistry registry) {//设置可以跨域的映射地址registry.addMapping("/**")// 设置可以跨域的源.allowedOriginPatterns("*")// 是否允许使用cookie.allowCredentials(true)// 设置允许的请求方式.allowedMethods("GET", "POST", "DELETE", "PUT")// 设置允许的header属性.allowedHeaders("*")// 跨域允许时间.maxAge(3600);}
}

2.开启springsecurity的允许跨域。

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {@AutowiredJwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;@AutowiredAuthenticationEntryPoint authenticationEntryPoint;@AutowiredAccessDeniedHandler accessDeniedHandler;@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}//将AuthenticationManager配置到ioc中@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}//配置权限规则,主要就睡要放行登录接口,不然登录接口都会被了解,以及其他不要的前后端分离的配置@Overrideprotected void configure(HttpSecurity http) throws Exception {http//由于是前后端分离项目,所以要关闭csrf.csrf().disable()//由于是前后端分离项目,没有session.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()//指定让spring security放行登录接口的规则.authorizeRequests()// 对于登录接口 anonymous表示允许匿名访问, permitAll就是 登录和没登录都可以访问.antMatchers("/user/login").anonymous() //匿名访问,未登录就可以访问// 除上面外的所有请求全部需要鉴权认证后访问.anyRequest().authenticated();//将过滤器添加到用户登录处理器之前http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);//设置自定义的异常处理器http.exceptionHandling()//校验异常处理器.authenticationEntryPoint(authenticationEntryPoint)//授权异常处理器.accessDeniedHandler(accessDeniedHandler);//允许跨域http.cors();}
}

最终设置完成。

自定义权限校验方法(比较灵活,可以自定义策略)

1.自定义校验类

@Component("itolen") //设置该类在ioc中的名称
public class ExpressionRoot {//判断权限是否存在public boolean hasAuthority(String authority) {LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();List<String> authorities2String = loginUser.getAuthorities2String();return authorities2String.contains(authority);}
}

2.在对应的接口上调用自定义方法。

@RestController
public class baseController {@RequestMapping("/hello")//拥有text倾向才能访问@PreAuthorize("@itolen.hasAuthority('system:test:list')")public String hello() {return "hello!";}
}

进行测试。

 其他处理器 

  • 认证成功处理器和认证失败处理器
//认证成功处理器实现类
@Component
public class AuthenticationSuccessHandlerImpl implements AuthenticationSuccessHandler {@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {//认证成功后就会进行该方法System.out.println("认证成功!");}
}
//认证失败处理器实现类
@Component
public class AuthenticationFailureHandlerImpl implements AuthenticationFailureHandler {@Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {//认证失败后执行该方法System.out.println("认证失败!");}
}

 将两个类进行配置。

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate AuthenticationSuccessHandler authenticationSuccessHandler;@Autowiredprivate AuthenticationFailureHandler authenticationFailureHandler;//配置权限规则,主要就睡要放行登录接口,不然登录接口都会被了解,以及其他不要的前后端分离的配置@Overrideprotected void configure(HttpSecurity http) throws Exception {//设置校验成功处理器和校验失败处理器http.formLogin().successHandler(authenticationSuccessHandler).failureHandler(authenticationFailureHandler);}
}
  • 注销成功处理器
@Component
public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler {@Overridepublic void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {//注销成功后执行的方法System.out.println("注销成功!");}
}

将该类进行配置。

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate LogoutSuccessHandler logoutSuccessHandler;//配置权限规则,主要就睡要放行登录接口,不然登录接口都会被了解,以及其他不要的前后端分离的配置@Overrideprotected void configure(HttpSecurity http) throws Exception {//设置注销成功处理器http.logout().logoutSuccessHandler(logoutSuccessHandler);}
}

http://www.khdw.cn/news/63064.html

相关文章:

  • 免费做网站真的免费吗合肥seo排名优化公司
  • 电子商务网站开发需求文档百度号码查询平台
  • 阿里云虚拟主机可以做几个网站吗郑州营销型网站建设
  • 5g创业网站建设网络推广怎么找客户资源
  • 合肥做双语外贸网站搜索引擎关键词seo优化公司
  • 做网站建设需要做哪些工作搜索引擎营销方法有哪些
  • 个人电脑做服务器网站网络营销与策划试题及答案
  • 做信息网站要办icp证吗竞价托管公司排名
  • 有网站前台百度引擎入口官网
  • 毕业设计做网站还是系统好郑州网站建设用户
  • 保定免费建站疫情最新消息今天
  • 哈尔滨网站建设费用宁波seo公司排名
  • 做app 的模板下载网站有哪些代运营
  • 流行用什么做网站seo是什么平台
  • 有哪些公司的网站做的很好看有人看片吗免费的
  • 网站前端开发商业策划公司十大公司
  • 温州高端网站建设公司培训机构排名前十
  • 六安网站自然排名优化价格域名备案查询
  • 深圳模板网站制作关键词批量调词软件
  • 服装加工网seo销售是做什么的
  • 内页网站地图 权重新媒体营销案例
  • 网站排版设计欣赏seo联盟
  • litespeed wordpress百度seo新站优化
  • dw网页制作试题上海网站优化公司
  • 专业ppt代做seo搜索优化推广
  • 微网站制作提供商推荐优化公司
  • 真人做爰网站视频网络推广公司官网
  • 中国万网联系方式百度seo快速见效方法
  • 建歌网站多少钱seo点击软件
  • 下载官方网站app下载百度竞价推广开户