您的位置:首页 > 游戏 > 游戏 > crm软件定制_山东起诉网站服务平台_百度明星人气榜排名_如何在网上推广自己的公司

crm软件定制_山东起诉网站服务平台_百度明星人气榜排名_如何在网上推广自己的公司

2024/11/15 19:40:24 来源:https://blog.csdn.net/qq_35201802/article/details/143694195  浏览:    关键词:crm软件定制_山东起诉网站服务平台_百度明星人气榜排名_如何在网上推广自己的公司
crm软件定制_山东起诉网站服务平台_百度明星人气榜排名_如何在网上推广自己的公司

依赖

<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.12.3</version>
</dependency>
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.12.3</version>
</dependency>
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId><version>0.12.3</version>
</dependency>

JwtUtil 工具类

用于生成 token,校验 token,从 token 中解析数据

package com.shore.my_spring_demo.common.utils;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;import java.security.KeyPair;
import java.security.PrivateKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;public class JwtUtil {private static String SECRET_KEY = "mySecretKey";private static long EXPIRATION_TIME = 10 * 24 * 60 * 60 * 1000;private static final KeyPair keyPair; // 如果使用RSA等非对称加密,需要生成密钥对static {// 初始化密钥对(仅当使用非对称加密时需要)// 这里使用RSA作为示例,你可以根据需要选择其他算法keyPair = Keys.keyPairFor(SignatureAlgorithm.RS256);}/*** 非对称加密生成 token** @param username* @return*/public static String generateTokenAsymmetric (String username) {return Jwts.builder().claim("sub", username).expiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)).signWith(SignatureAlgorithm.RS256, keyPair.getPrivate()).compact();}/*** 对称加密生成 token** @param username* @return*/public static String generateTokenSymmetric(String username) {return Jwts.builder().claim("sub", username).expiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)).signWith(SignatureAlgorithm.ES512, SECRET_KEY).compact();}/*** 对称加密校验token** @param token* @return*/public static boolean validateTokenSymmetric (String token) {try {Claims claims = Jwts.parser().setSigningKey(SECRET_KEY).build().parseClaimsJws(token).getBody();return claims.getExpiration().after(new Date());} catch (Exception e) {// 处理解析或验证错误,可以根据需要抛出异常或返回 nullthrow new RuntimeException("JWT validation failed: " + e.getMessage(), e);}}/*** 非对称加密校验token** @param token* @return*/public static boolean validateTokenAsymmetric(String token) {try {Claims claims = Jwts.parser().setSigningKey(keyPair.getPublic()).build().parseClaimsJws(token).getBody();return claims.getExpiration().after(new Date());} catch (Exception e) {// 处理解析或验证错误,可以根据需要抛出异常或返回 nullthrow new RuntimeException("JWT validation failed: " + e.getMessage(), e);}}/*** 对称加密根据token获取用户名** @param token* @return*/public static String getUsernameFromTokenSymmetric (String token) {Claims claims = Jwts.parser().setSigningKey(keyPair.getPublic()).build().parseClaimsJws(token).getBody();return (String) claims.get("sub");}/*** 非对称加密根据token获取用户名** @param token* @return*/public static String getUsernameFromTokenAsymmetric (String token) {Claims claims = Jwts.parser().setSigningKey(keyPair.getPublic()).build().parseClaimsJws(token).getBody();return (String) claims.get("sub");}
}

SpringSecurity 配置类

配置 凭证校验规则,接口拦截,可参考:https://editor.csdn.net/md/?articleId=143686996

package com.shore.my_spring_demo.web.config;import com.shore.my_spring_demo.dal.entity.UserEntity;
import com.shore.my_spring_demo.dal.repo.UserServiceRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;import javax.annotation.Resource;
import java.util.ArrayList;@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {@Resourceprivate UserServiceRepo userServiceRepo;@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(username -> {UserEntity userEntity = userServiceRepo.getUserByUsername(username);if (userEntity == null) {throw new UsernameNotFoundException(String.format("User %s not found", username));}return new User(userEntity.getUsername(), userEntity.getPassword(), new ArrayList<>());}).passwordEncoder(passwordEncoder());}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.csrf().disable().authorizeRequests().antMatchers("/", "/shore/demo/user/login", "/shore/demo/user/register", "/shore/demo/user/query").permitAll().anyRequest().authenticated().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);}@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}
}

实现 UserDetail 接口

重写 UserDetail 的构建方法,用于创建认证对象

package com.shore.my_spring_demo.web.filters;import com.shore.my_spring_demo.dal.entity.UserEntity;
import com.shore.my_spring_demo.dal.repo.UserServiceRepo;
import com.shore.my_spring_demo.service.user.UserService;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;@Service
public class UserDetailService implements UserDetailsService {@Resourceprivate UserServiceRepo userServiceRepo;@Overridepublic UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {UserEntity userEntity = userServiceRepo.getUserByUsername(s);return new UserDetails() {// 用户被授予的所有权限集合@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {Set<GrantedAuthority> authorities = new HashSet<>();authorities.add(new SimpleGrantedAuthority("ROLE_USER"));authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));return authorities;}@Overridepublic String getPassword() {return userEntity.getPassword();}@Overridepublic String getUsername() {return userEntity.getUsername();}// 检查用户账号是否过期@Overridepublic boolean isAccountNonExpired() {return true;}// 检查用户账户是否锁住@Overridepublic boolean isAccountNonLocked() {return true;}// 检查用户凭据是否过期@Overridepublic boolean isCredentialsNonExpired() {return true;}// 检查用户是否被启用@Overridepublic boolean isEnabled() {return true;}};}
}

Jwt 过滤器

校验受保护接口的 token

package com.shore.my_spring_demo.web.filters;import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;import com.shore.my_spring_demo.common.utils.JwtUtil;@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {private final UserDetailService userDetailsService;// 通过构造函数注入UserDetailsServicepublic JwtAuthenticationFilter(UserDetailService userDetailsService) {this.userDetailsService = userDetailsService;}@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException {List<String> allowedURI = Arrays.asList("/shore/demo/user/login", "/shore/demo/user/register");if (allowedURI.contains(request.getRequestURI())) {filterChain.doFilter(request, response);}String header = request.getHeader("Authorization");if (header != null && header.startsWith("Bearer")) {String token = header.substring(6); // 去除"Bearer "前缀// 验证JWT的有效性if (JwtUtil.validateTokenAsymmetric(token)) {// 从JWT中获取用户名String username = JwtUtil.getUsernameFromTokenAsymmetric(token);// 从UserDetailsService加载用户信息UserDetails userDetails = userDetailsService.loadUserByUsername(username);// 如果用户信息存在,创建一个认证对象,并将其存储在安全上下文中if (userDetails != null) {UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));SecurityContextHolder.getContext().setAuthentication(authentication);}}// 继续过滤器链filterChain.doFilter(request, response);} else {throw new RuntimeException("用户未登录");}}
}

控制器

登录接口,使用 Spring Security 的规则校验凭证,校验成功生成 token 返回

package com.shore.my_spring_demo.web.controller;import com.shore.my_spring_demo.common.utils.JwtUtil;
import com.shore.my_spring_demo.service.user.UserService;
import com.shore.my_spring_demo.web.domain.user.req.UserReq;
import com.shore.my_spring_demo.web.domain.user.vo.UserVO;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestController
@RequestMapping("/shore/demo/user")
public class UserController {@Resourceprivate UserService userService;@Resourceprivate AuthenticationManager authenticationManager;@PostMapping("/register")public void register(@RequestBody UserReq req) {System.out.println(req.toString());userService.register(req);}@PostMapping("/query")public UserVO queryUser(@RequestBody UserReq req) {System.out.println(req);return userService.getUserById(req.getId());}@PostMapping("/login")public String login(@RequestBody UserReq req) {try {Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(req.getUsername(), req.getPassword()));return JwtUtil.generateTokenAsymmetric(req.getUsername());} catch (Exception e) {System.out.println("登录校验失败");throw new RuntimeException("Invalid credentials");}}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com