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

网站出现 503怎么了数据分析方法

网站出现 503怎么了,数据分析方法,如何设计网站logo,做网站贴吧1. SpringSecurity介绍 Spring Security 是一个功能强大且高度可定制的身份验证和访问控制框架。它是为Java应用程序设计的,特别是那些基于Spring的应用程序。Spring Security是一个社区驱动的开源项目,它提供了全面的安全性解决方案,包括防…

1. SpringSecurity介绍

Spring Security 是一个功能强大且高度可定制的身份验证和访问控制框架。它是为Java应用程序设计的,特别是那些基于Spring的应用程序。Spring Security是一个社区驱动的开源项目,它提供了全面的安全性解决方案,包括防止常见的安全漏洞如CSRF、点击劫持、会话固定等。

以下是Spring Security的一些关键特性和概念:

  1. 认证(Authentication):Spring Security可以处理用户的身份验证过程,即确认用户是否是他们声称的人。它可以使用多种机制来进行身份验证,例如表单登录、HTTP基本认证、OAuth2、JWT等。

  2. 授权(Authorization):一旦用户通过了身份验证,Spring Security就会根据用户的权限来决定他们可以访问哪些资源。这可以通过定义角色、权限或更细粒度的访问规则来实现。

  3. 安全配置:Spring Security可以通过Java配置或XML配置来设置安全策略。通常推荐使用Java配置,因为它与现代Spring应用更为集成,并提供编译时检查。

  4. 拦截URL模式:可以定义哪些URL需要特定的权限才能访问,以及如何处理未认证或未经授权的请求。

  5. 过滤器链:Spring Security利用了一组过滤器(Filter),这些过滤器在每次HTTP请求时被调用,以执行各种安全相关的任务。开发者可以根据需要添加自定义过滤器。

  6. 密码编码:为了安全存储用户密码,Spring Security支持多种加密方式,如BCrypt、PBKDF2等。

  7. 记住我(Remember-Me):允许系统在用户关闭浏览器后仍然保持登录状态,直到明确登出或cookie过期。

  8. 注销(Logout):提供了安全的退出机制,确保用户的会话被正确地销毁。

  9. CSRF保护:默认启用跨站请求伪造攻击防护,确保只有来自合法来源的请求才能修改服务器端的状态。

  10. Session管理:可以配置会话创建策略,例如只在需要时创建会话,或者限制同一时间内的并发会话数量。

  11. OAuth2和OpenID Connect支持:内置对OAuth2客户端和资源服务器的支持,方便集成第三方认证服务。

使用Spring Security,开发者可以专注于业务逻辑的开发,而将安全问题交给这个成熟可靠的框架来处理。同时,由于其高度可扩展性和灵活性,Spring Security也适合用于构建复杂的安全需求。

2. 登录流程

登录API无需拦截,SpringSecurity直接放行。

/*** @description 认证授权**/
@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Api(tags = "认证")
public class AuthController {private final AuthService authService;@PostMapping("/login")@ApiOperation("登录")public ResponseEntity<Void> login(@RequestBody LoginRequest loginRequest) {String token = authService.createToken(loginRequest);HttpHeaders httpHeaders = new HttpHeaders();httpHeaders.set(SecurityConstants.TOKEN_HEADER, token);return new ResponseEntity<>(httpHeaders, HttpStatus.OK);}
}

AuthService首先会校验用户名与密码,和用户的角色,然后调用JwtTokenUtils创建token,然后以userId为key,token作为value存在Redis中。

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class AuthService {private final UserService userService;private final StringRedisTemplate stringRedisTemplate;private final CurrentUserUtils currentUserUtils;public String createToken(LoginRequest loginRequest) {User user = userService.find(loginRequest.getUsername());if (!userService.check(loginRequest.getPassword(), user.getPassword())) {throw new BadCredentialsException("The user name or password is not correct.");}JwtUser jwtUser = new JwtUser(user);if (!jwtUser.isEnabled()) {throw new BadCredentialsException("User is forbidden to login");}List<String> authorities = jwtUser.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());String token = JwtTokenUtils.createToken(user.getUserName(), user.getId().toString(), authorities, loginRequest.getRememberMe());stringRedisTemplate.opsForValue().set(user.getId().toString(), token);return token;}public void removeToken() {stringRedisTemplate.delete(currentUserUtils.getCurrentUser().getId().toString());}
}

JwtTokenUtils负责创建token、解析token与获取userId。

public class JwtTokenUtils {/*** 生成足够的安全随机密钥,以适合符合规范的签名*/private static final byte[] API_KEY_SECRET_BYTES = DatatypeConverter.parseBase64Binary(SecurityConstants.JWT_SECRET_KEY);private static final SecretKey SECRET_KEY = Keys.hmacShaKeyFor(API_KEY_SECRET_BYTES);public static String createToken(String username, String id, List<String> roles, boolean isRememberMe) {long expiration = isRememberMe ? SecurityConstants.EXPIRATION_REMEMBER : SecurityConstants.EXPIRATION;final Date createdDate = new Date();final Date expirationDate = new Date(createdDate.getTime() + expiration * 1000);String tokenPrefix = Jwts.builder().setHeaderParam("type", SecurityConstants.TOKEN_TYPE).signWith(SECRET_KEY, SignatureAlgorithm.HS256).claim(SecurityConstants.ROLE_CLAIMS, String.join(",", roles)).setId(id).setIssuer("SnailClimb").setIssuedAt(createdDate).setSubject(username).setExpiration(expirationDate).compact();return SecurityConstants.TOKEN_PREFIX + tokenPrefix; // 添加 token 前缀 "Bearer ";}// userIdpublic static String getId(String token) {Claims claims = getClaims(token);return claims.getId();}// 得到 userName、token与 authoritiespublic static UsernamePasswordAuthenticationToken getAuthentication(String token) {Claims claims = getClaims(token);List<SimpleGrantedAuthority> authorities = getAuthorities(claims);String userName = claims.getSubject();return new UsernamePasswordAuthenticationToken(userName, token, authorities);}private static List<SimpleGrantedAuthority> getAuthorities(Claims claims) {String role = (String) claims.get(SecurityConstants.ROLE_CLAIMS);return Arrays.stream(role.split(",")).map(SimpleGrantedAuthority::new).collect(Collectors.toList());}private static Claims getClaims(String token) {return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();}
}

3. JWT认证流程

// 启用 SpringSecurity
@EnableWebSecurity
// 启用 SpringSecurity 注解开发
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {private final StringRedisTemplate stringRedisTemplate;public SecurityConfiguration(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate = stringRedisTemplate;}/*** 密码编码器*/@Beanpublic BCryptPasswordEncoder bCryptPasswordEncoder() {return new BCryptPasswordEncoder();}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.cors(withDefaults())// 禁用 CSRF.csrf().disable().authorizeRequests()// 指定的接口直接放行// swagger.antMatchers(SecurityConstants.SWAGGER_WHITELIST).permitAll().antMatchers(SecurityConstants.H2_CONSOLE).permitAll().antMatchers(HttpMethod.POST, SecurityConstants.SYSTEM_WHITELIST).permitAll()// 其他的接口都需要认证后才能请求.anyRequest().authenticated().and()//添加自定义Filter.addFilter(new JwtAuthorizationFilter(authenticationManager(), stringRedisTemplate))// 不需要session(不创建会话).sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()// 授权异常处理.exceptionHandling().authenticationEntryPoint(new JwtAuthenticationEntryPoint()).accessDeniedHandler(new JwtAccessDeniedHandler());// 防止H2 web 页面的Frame 被拦截http.headers().frameOptions().disable();}/*** Cors配置优化**/@BeanCorsConfigurationSource corsConfigurationSource() {org.springframework.web.cors.CorsConfiguration configuration = new CorsConfiguration();configuration.setAllowedOrigins(singletonList("*"));// configuration.setAllowedOriginPatterns(singletonList("*"));configuration.setAllowedHeaders(singletonList("*"));configuration.setAllowedMethods(Arrays.asList("GET", "POST", "DELETE", "PUT", "OPTIONS"));configuration.setExposedHeaders(singletonList(SecurityConstants.TOKEN_HEADER));configuration.setAllowCredentials(false);configuration.setMaxAge(3600L);UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**", configuration);return source;}
}

自定义Filter

@Slf4j
public class JwtAuthorizationFilter extends BasicAuthenticationFilter {private final StringRedisTemplate stringRedisTemplate;// 不是 Bean, 需要手动注入public JwtAuthorizationFilter(AuthenticationManager authenticationManager, StringRedisTemplate stringRedisTemplate) {super(authenticationManager);this.stringRedisTemplate = stringRedisTemplate;}@Overrideprotected void doFilterInternal(HttpServletRequest request,HttpServletResponse response,FilterChain chain) throws IOException, ServletException {String token = request.getHeader(SecurityConstants.TOKEN_HEADER);if (token == null || !token.startsWith(SecurityConstants.TOKEN_PREFIX)) {SecurityContextHolder.clearContext();chain.doFilter(request, response);return;}String tokenValue = token.replace(SecurityConstants.TOKEN_PREFIX, "");UsernamePasswordAuthenticationToken authentication = null;try {// token是否有效String previousToken = stringRedisTemplate.opsForValue().get(JwtTokenUtils.getId(tokenValue));if (!token.equals(previousToken)) {SecurityContextHolder.clearContext();chain.doFilter(request, response);return;}authentication = JwtTokenUtils.getAuthentication(tokenValue);} catch (JwtException e) {logger.error("Invalid jwt : " + e.getMessage());}// 将userName, token, authorities保存在Context中SecurityContextHolder.getContext().setAuthentication(authentication);chain.doFilter(request, response);}
}

SecurityContextHolder是基于ThreadLocal实现的,可以实现不同线程之间的隔离。

public class SecurityContextHolder {public static final String MODE_THREADLOCAL = "MODE_THREADLOCAL";public static final String MODE_INHERITABLETHREADLOCAL = "MODE_INHERITABLETHREADLOCAL";public static final String MODE_GLOBAL = "MODE_GLOBAL";public static final String SYSTEM_PROPERTY = "spring.security.strategy";private static String strategyName = System.getProperty("spring.security.strategy");private static SecurityContextHolderStrategy strategy;private static int initializeCount = 0;public SecurityContextHolder() {}private static void initialize() {if (!StringUtils.hasText(strategyName)) {strategyName = "MODE_THREADLOCAL";}if (strategyName.equals("MODE_THREADLOCAL")) {strategy = new ThreadLocalSecurityContextHolderStrategy();} else if (strategyName.equals("MODE_INHERITABLETHREADLOCAL")) {strategy = new InheritableThreadLocalSecurityContextHolderStrategy();} else if (strategyName.equals("MODE_GLOBAL")) {strategy = new GlobalSecurityContextHolderStrategy();} else {try {Class<?> clazz = Class.forName(strategyName);Constructor<?> customStrategy = clazz.getConstructor();strategy = (SecurityContextHolderStrategy)customStrategy.newInstance();} catch (Exception var2) {Exception ex = var2;ReflectionUtils.handleReflectionException(ex);}}++initializeCount;}
}

4. 全局异常处理器

public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {/*** 当用户尝试访问需要权限才能的REST资源而不提供Token或者Token错误或者过期时,* 将调用此方法发送401响应以及错误信息*/@Overridepublic void commence(HttpServletRequest request,HttpServletResponse response,AuthenticationException authException) throws IOException {response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());}
}
public class JwtAccessDeniedHandler implements AccessDeniedHandler {/*** 当用户尝试访问需要权限才能的REST资源而权限不足的时候,* 将调用此方法发送403响应以及错误信息*/@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {accessDeniedException = new AccessDeniedException("Sorry you don not enough permissions to access it!");response.sendError(HttpServletResponse.SC_FORBIDDEN, accessDeniedException.getMessage());}
}

5. 注销流程

删除Redis中保存的token。

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class AuthService {private final UserService userService;private final StringRedisTemplate stringRedisTemplate;private final CurrentUserUtils currentUserUtils;public String createToken(LoginRequest loginRequest) {User user = userService.find(loginRequest.getUsername());if (!userService.check(loginRequest.getPassword(), user.getPassword())) {throw new BadCredentialsException("The user name or password is not correct.");}JwtUser jwtUser = new JwtUser(user);if (!jwtUser.isEnabled()) {throw new BadCredentialsException("User is forbidden to login");}List<String> authorities = jwtUser.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());String token = JwtTokenUtils.createToken(user.getUserName(), user.getId().toString(), authorities, loginRequest.getRememberMe());stringRedisTemplate.opsForValue().set(user.getId().toString(), token);return token;}public void removeToken() {stringRedisTemplate.delete(currentUserUtils.getCurrentUser().getId().toString());}
}
@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class CurrentUserUtils {private final UserService userService;public User getCurrentUser() {return userService.find(getCurrentUserName());}private  String getCurrentUserName() {Authentication authentication = SecurityContextHolder.getContext().getAuthentication();if (authentication != null && authentication.getPrincipal() != null) {return (String) authentication.getPrincipal();}return null;}
}

6. 权限管理

基于@PreAuthorize实现权限管理

@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@RequestMapping("/users")
@Api(tags = "用户")
public class UserController {private final UserService userService;@GetMapping// 有任意角色的权限都可以访问@PreAuthorize("hasAnyRole('ROLE_USER','ROLE_MANAGER','ROLE_ADMIN')")@ApiOperation("获取所有用户的信息(分页)")public ResponseEntity<Page<UserRepresentation>> getAllUser(@RequestParam(value = "pageNum", defaultValue = "0") int pageNum, @RequestParam(value = "pageSize", defaultValue = "10") int pageSize) {Authentication authentication = SecurityContextHolder.getContext().getAuthentication();System.out.println("auth信息: " + authentication.getPrincipal().toString() + " 鉴权" + authentication.getAuthorities().toString());System.out.println("***********");Page<UserRepresentation> allUser = userService.getAll(pageNum, pageSize);return ResponseEntity.ok().body(allUser);}@PutMapping@PreAuthorize("hasAnyRole('ROLE_ADMIN')")@ApiOperation("更新用户")public ResponseEntity<Void> update(@RequestBody @Valid UserUpdateRequest userUpdateRequest) {userService.update(userUpdateRequest);return ResponseEntity.ok().build();}@DeleteMapping@PreAuthorize("hasAnyRole('ROLE_ADMIN')")@ApiOperation("根据用户名删除用户")public ResponseEntity<Void> deleteUserByUserName(@RequestParam("username") String username) {userService.delete(username);return ResponseEntity.ok().build();}
}

文章转载自:
http://dinncoinbreaking.bkqw.cn
http://dinncoweldment.bkqw.cn
http://dinncoquantitatively.bkqw.cn
http://dinncobaric.bkqw.cn
http://dinncosubmundane.bkqw.cn
http://dinncoenthusiastically.bkqw.cn
http://dinncoallay.bkqw.cn
http://dinncolythe.bkqw.cn
http://dinncotrigon.bkqw.cn
http://dinncoconsenescence.bkqw.cn
http://dinncocolporrhaphy.bkqw.cn
http://dinncoavuncular.bkqw.cn
http://dinncophantomlike.bkqw.cn
http://dinncocobbly.bkqw.cn
http://dinncoece.bkqw.cn
http://dinncoflyblow.bkqw.cn
http://dinncothirsty.bkqw.cn
http://dinncowingover.bkqw.cn
http://dinncohyperpyrexia.bkqw.cn
http://dinncomourner.bkqw.cn
http://dinncoworrisome.bkqw.cn
http://dinncoperambulatory.bkqw.cn
http://dinncoboina.bkqw.cn
http://dinncoselenology.bkqw.cn
http://dinncohooknose.bkqw.cn
http://dinncodarter.bkqw.cn
http://dinncopaleozoic.bkqw.cn
http://dinncoedge.bkqw.cn
http://dinncoproteolytic.bkqw.cn
http://dinncocapsular.bkqw.cn
http://dinncoasti.bkqw.cn
http://dinncoavitaminosis.bkqw.cn
http://dinncosemiography.bkqw.cn
http://dinncomammoplasty.bkqw.cn
http://dinncosoniferous.bkqw.cn
http://dinncocarborundum.bkqw.cn
http://dinncoabutter.bkqw.cn
http://dinncocrazyweed.bkqw.cn
http://dinncosentient.bkqw.cn
http://dinncooogamete.bkqw.cn
http://dinncovivarium.bkqw.cn
http://dinncopiccanin.bkqw.cn
http://dinncononprescription.bkqw.cn
http://dinncocopperbottom.bkqw.cn
http://dinncoballadeer.bkqw.cn
http://dinncoouroscopy.bkqw.cn
http://dinncothermonuclear.bkqw.cn
http://dinncokennedy.bkqw.cn
http://dinncoorthogon.bkqw.cn
http://dinncopearmain.bkqw.cn
http://dinncoeanling.bkqw.cn
http://dinncoelena.bkqw.cn
http://dinncorickshaw.bkqw.cn
http://dinncomuzzleloading.bkqw.cn
http://dinncocredibility.bkqw.cn
http://dinncocountryside.bkqw.cn
http://dinncopaleoanthropology.bkqw.cn
http://dinncoyourselves.bkqw.cn
http://dinncofixed.bkqw.cn
http://dinncoiadl.bkqw.cn
http://dinncoearthlight.bkqw.cn
http://dinnconomisma.bkqw.cn
http://dinncomoraine.bkqw.cn
http://dinncoabbevillian.bkqw.cn
http://dinncochurel.bkqw.cn
http://dinncosuperconduct.bkqw.cn
http://dinncowilga.bkqw.cn
http://dinnconaderism.bkqw.cn
http://dinncoscrollhead.bkqw.cn
http://dinncooverlord.bkqw.cn
http://dinncocochair.bkqw.cn
http://dinncoemigrant.bkqw.cn
http://dinncosemiconscious.bkqw.cn
http://dinncomanitu.bkqw.cn
http://dinncoorangutang.bkqw.cn
http://dinncophaeton.bkqw.cn
http://dinncocormel.bkqw.cn
http://dinncogls.bkqw.cn
http://dinncolineup.bkqw.cn
http://dinncoparulis.bkqw.cn
http://dinncofind.bkqw.cn
http://dinncosplitter.bkqw.cn
http://dinncoundertax.bkqw.cn
http://dinncobicho.bkqw.cn
http://dinncoprelexical.bkqw.cn
http://dinncocursor.bkqw.cn
http://dinncoarmlock.bkqw.cn
http://dinncotabernacle.bkqw.cn
http://dinncorulership.bkqw.cn
http://dinncoantisepticise.bkqw.cn
http://dinncohyperplastic.bkqw.cn
http://dinncosacque.bkqw.cn
http://dinncomgal.bkqw.cn
http://dinncowhirl.bkqw.cn
http://dinnconpcf.bkqw.cn
http://dinncofoglight.bkqw.cn
http://dinncoshypoo.bkqw.cn
http://dinncounsurpassed.bkqw.cn
http://dinncogenevieve.bkqw.cn
http://dinncofurcula.bkqw.cn
http://www.dinnco.com/news/152699.html

相关文章:

  • 汕头专业网站制作公司雅虎日本新闻
  • 哈尔滨市建设网站百度有几个总部
  • 怎么知道网站的空间服务商seo网站优化培训怎么样
  • 做网站需要注册哪类商标有免费推广平台
  • 小蚂蚁page页面模板佳木斯seo
  • 网站响应式和电脑手机推广普通话手抄报模板
  • 郑州网站建设选智巢地推团队如何收费
  • 免费高清视频素材网站有哪些广告公司品牌营销推广
  • 做网站需要公司备案网络营销有哪些就业岗位
  • 网站备案 英文seo快速优化文章排名
  • 编辑wordpress代码长沙谷歌seo
  • 做地产网站哪家好网络营销大赛策划书
  • 设计出色的网站有哪些平台可以免费发广告
  • 广西网站建设运营费用智能建站平台
  • wordpress算数验证seo经验是什么
  • 电子商务网站开发设计报告书精准客源推广引流
  • 视频网站管理系统企业网站制作费用
  • 怎么切图做网站百度seo排名优化助手
  • 有做微推客的网站吗百度公司有哪些部门
  • 可以直接做海报的网站游戏推广工作好做吗
  • 网站 建设平台推广文案
  • 做网站设分辨率友情链接软件
  • 网站手机模板源码淘宝推广哪种方式最好
  • 已将绑定域名给另一个网站常用的seo查询工具有哪些
  • 在哪个网站里下载的图片可以做展架百度推广的定义
  • 网站编辑做啥都日本网站源码
  • 有什么设计网站seo教育培训机构
  • 天津网站制作首页在线咨询seo项目
  • 德国诺莫斯手表网站搜索引擎营销
  • 网站建设方案书微商城毕业设计网站