<dependencies><!-- SpringBoot的依赖配置--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--jwt依赖--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.0</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version></dependency><!--验证码 --><dependency><groupId>com.github.penggle</groupId><artifactId>kaptcha</artifactId><version>2.3.2</version></dependency><dependency><groupId>org.apachemons</groupId><artifactId>commons-lang3</artifactId><version>3.8.1</version></dependency><!--fastjson--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.75</version></dependency><!-- Spring Security--><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-web</artifactId><version>5.0.1.RELEASE</version></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-config</artifactId><version>5.0.1.RELEASE</version></dependency><!-- Spring Security方法级权限控制注解--><dependency><groupId>javax.annotation</groupId><artifactId>jsr250-api</artifactId><version>1.0</version></dependency><!--redis--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><!--<version>2.1.4.RELEASE</version>--></dependency><dependency><groupId>org.apachemons</groupId><artifactId>commons-pool2</artifactId></dependency><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--mybatis--><dependency><groupId&batis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.3</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.1</version><configuration><source>${java.version}</source><target>${java.version}</target><encoding>${project.build.sourceEncoding}</encoding></configuration></plugin></plugins></build>
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;@AutowiredAuthenticationEntryPoint authenticationEntryPoint;@AutowiredAccessDeniedHandler accessDeniedHandler;@Overrideprotected void configure(HttpSecurity http) throws Exception {http//关闭csrf.csrf().disable()//不通过Session获取SecurityContext.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests()// 对于登录接口 允许匿名访问.antMatchers("/login").anonymous()//注销接口需要认证才能访问.antMatchers("/logout").authenticated()//.antMatchers("/upload").authenticated()//个人信息接口必须登录后才能访问.antMatchers("/user/userInfo").authenticated()//jwt过滤器测试用,如果测试没有问题吧这里删除了//.antMatchers("/link/getAllLink").authenticated()// 除上面外的所有请求全部不需要认证即可访问.anyRequest().permitAll();//配置异常处理器ptionHandling().authenticationEntryPoint(authenticationEntryPoint).accessDeniedHandler(accessDeniedHandler);http.logout().disable();//关闭默认的注销功能http.logout().disable();//把jwtAuthenticationTokenFilter添加到SpringSecurity的过滤器链中http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);//允许跨域s();}@Override@Beanpublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}@Beanpublic PasswordEncoder PasswordEncoder(){return new BCryptPasswordEncoder();}}
@RestController
public class LoginController {@Autowiredprivate LoginService loginService;@PostMapping("/login")@ApiOperation(value = "登陆",notes = "登陆")public R<?> login(@RequestBody User user){if (!StringUtils.UserName())||!StringUtils.Password())){throw new CodeException(ResultCode.INVALID_PARAMETER,"请输入用户名或密码");}return loginService.login(user);}@PostMapping("/logout")@ApiOperation(value = "退出登陆",notes = "退出登陆")public R<?> logout(){return null;}}
@Resourceprivate RedisCache redisCache;@Resourceprivate AuthenticationManager authenticationManager;@Overridepublic R login(User user) {UsernamePasswordAuthenticationToken authenticationToken = new UserName(), Password());//发起认证Authentication authenticate = authenticationManager.authenticate(authenticationToken);//判断是否通过if (Objects.isNull(authenticationToken)){throw new RuntimeException("用户名或密码错误");}LoginUser loginUser = (LoginUser) Principal();String userId = User().getUserId().toString();String jwt = ateJWT(userId);redisCache.setCacheObject("login"+userId,loginUser);LoginVo loginVo = new LoginVo(jwt, User());return R.success(loginVo);}
public class UserDetailServiceImpl implements UserDetailsService {@Resourceprivate UserDao userDao;@Resourceprivate RoleDao roleDao;@Overridepublic UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {//根据用户名查询用户信息User user = userDao.selectOne(userName);if (Null(user)){throw new RuntimeException("用户不存在");}//查询用户权限List<String> permssions = roleDao.UserId());//返回UserDetails 对象return new LoginUser(user,permssions);}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class LoginUser implements UserDetails {private User user;private List<String> permissions;@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {return null;}@Overridepublic String getPassword() {Password();}@Overridepublic String getUsername() {UserName();}@Overridepublic boolean isAccountNonExpired() {return true;}@Overridepublic boolean isAccountNonLocked() {return true;}@Overridepublic boolean isCredentialsNonExpired() {return true;}@Overridepublic boolean isEnabled() {return true;}}
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {@Autowiredprivate RedisCache redisCache;@Overrideprotected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {String token = Header("token");if (!StringUtils.hasText(token)){filterChain.doFilter(httpServletRequest,httpServletResponse);return;}Claims claims = null;try {claims = JwtUtil.parseJWT(token);}catch (Exception e){e.printStackTrace();//提示报错}String userId = Subject();LoginUser loginUser = CacheObject("login:" + userId);if (Objects.isNull(loginUser)){//提示登陆}//存入SecurityContextHolderUsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, null);Context().setAuthentication(usernamePasswordAuthenticationToken);//放行filterChain.doFilter(httpServletRequest, httpServletResponse);}
}
@Component
public class AccessDeniedHandlerImpl implements AccessDeniedHandler {@Overridepublic void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {R result = R.failure(ResultCode.AUTH_FUILURE);//响应给前端derString(httpServletResponse, JSONString(result));}
}
@Component
public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint{@Overridepublic void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {R result = R.failure(ResultCode.AUTH_FAILURE);//响应给前端derString(httpServletResponse, JSONString(result));}
}
public class JwtUtil {//有效期为public static final Long JWT_TTL = 24*60 * 60 *1000L;// 60 * 60 *1000 一个小时//设置秘钥明文public static final String JWT_KEY = "wangfei";public static String getUUID(){String token = UUID.randomUUID().toString().replaceAll("-", "");return token;}/*** 生成jtw* @param subject token中要存放的数据(json格式)* @return*/public static String createJWT(String subject) {JwtBuilder builder = getJwtBuilder(subject, null, getUUID());// 设置过期时间return builderpact();}/*** 生成jtw* @param subject token中要存放的数据(json格式)* @param ttlMillis token超时时间* @return*/public static String createJWT(String subject, Long ttlMillis) {JwtBuilder builder = getJwtBuilder(subject, ttlMillis, getUUID());// 设置过期时间return builderpact();}private static JwtBuilder getJwtBuilder(String subject, Long ttlMillis, String uuid) {SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;SecretKey secretKey = generalKey();long nowMillis = System.currentTimeMillis();Date now = new Date(nowMillis);if(ttlMillis==null){ttlMillis=JwtUtil.JWT_TTL;}long expMillis = nowMillis + ttlMillis;Date expDate = new Date(expMillis);return Jwts.builder().setId(uuid) //唯一的ID.setSubject(subject) // 主题 可以是JSON数据.setIssuer("sg") // 签发者.setIssuedAt(now) // 签发时间.signWith(signatureAlgorithm, secretKey) //使用HS256对称加密算法签名, 第二个参数为秘钥.setExpiration(expDate);}/*** 创建token* @param id* @param subject* @param ttlMillis* @return*/public static String createJWT(String id, String subject, Long ttlMillis) {JwtBuilder builder = getJwtBuilder(subject, ttlMillis, id);// 设置过期时间return builderpact();}public static void main(String[] args) throws Exception {String token = "";Claims claims = parseJWT(token);System.out.println(claims);}/*** 生成加密后的秘钥 secretKey* @return*/public static SecretKey generalKey() {byte[] encodedKey = Decoder().decode(JwtUtil.JWT_KEY);SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");return key;}/*** 解析** @param jwt* @return* @throws Exception*/public static Claims parseJWT(String jwt) throws Exception {SecretKey secretKey = generalKey();return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwt).getBody();}}
@Component
public class RedisCache {@Autowiredpublic RedisTemplate redisTemplate;/*** 缓存基本的对象,Integer、String、实体类等** @param key 缓存的键值* @param value 缓存的值*/public <T> void setCacheObject(final String key, final T value){redisTemplate.opsForValue().set(key, value);}/*** 缓存基本的对象,Integer、String、实体类等** @param key 缓存的键值* @param value 缓存的值* @param timeout 时间* @param timeUnit 时间颗粒度*/public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit){redisTemplate.opsForValue().set(key, value, timeout, timeUnit);}/*** 设置有效时间** @param key Redis键* @param timeout 超时时间* @return true=设置成功;false=设置失败*/public boolean expire(final String key, final long timeout){return expire(key, timeout, TimeUnit.SECONDS);}/*** 设置有效时间** @param key Redis键* @param timeout 超时时间* @param unit 时间单位* @return true=设置成功;false=设置失败*/public boolean expire(final String key, final long timeout, final TimeUnit unit){pire(key, timeout, unit);}/*** 获得缓存的基本对象。** @param key 缓存键值* @return 缓存键值对应的数据*/public <T> T getCacheObject(final String key){ValueOperations<String, T> operation = redisTemplate.opsForValue();(key);}/*** 删除单个对象** @param key*/public boolean deleteObject(final String key){return redisTemplate.delete(key);}/*** 删除集合对象** @param collection 多个对象* @return*/public long deleteObject(final Collection collection){return redisTemplate.delete(collection);}/*** 缓存List数据** @param key 缓存的键值* @param dataList 待缓存的List数据* @return 缓存的对象*/public <T> long setCacheList(final String key, final List<T> dataList){Long count = redisTemplate.opsForList().rightPushAll(key, dataList);return count == null ? 0 : count;}/*** 获得缓存的list对象** @param key 缓存的键值* @return 缓存键值对应的数据*/public <T> List<T> getCacheList(final String key){return redisTemplate.opsForList().range(key, 0, -1);}/*** 缓存Set** @param key 缓存键值* @param dataSet 缓存的数据* @return 缓存数据的对象*/public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet){BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);Iterator<T> it = dataSet.iterator();while (it.hasNext()){setOperation.());}return setOperation;}/*** 获得缓存的set** @param key* @return*/public <T> Set<T> getCacheSet(final String key){return redisTemplate.opsForSet().members(key);}/*** 缓存Map** @param key* @param dataMap*/public <T> void setCacheMap(final String key, final Map<String, T> dataMap){if (dataMap != null) {redisTemplate.opsForHash().putAll(key, dataMap);}}/*** 获得缓存的Map** @param key* @return*/public <T> Map<String, T> getCacheMap(final String key){return redisTemplate.opsForHash().entries(key);}/*** 往Hash中存入数据** @param key Redis键* @param hKey Hash键* @param value 值*/public <T> void setCacheMapValue(final String key, final String hKey, final T value){redisTemplate.opsForHash().put(key, hKey, value);}/*** 获取Hash中的数据** @param key Redis键* @param hKey Hash键* @return Hash中的对象*/public <T> T getCacheMapValue(final String key, final String hKey){HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();(key, hKey);}/*** 删除Hash中的数据** @param key* @param hkey*/public void delCacheMapValue(final String key, final String hkey){HashOperations hashOperations = redisTemplate.opsForHash();hashOperations.delete(key, hkey);}/*** 获取多个Hash中的数据** @param key Redis键* @param hKeys Hash键集合* @return Hash对象集合*/public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys){return redisTemplate.opsForHash().multiGet(key, hKeys);}/*** 获得缓存的基本对象列表** @param pattern 字符串前缀* @return 对象列表*/public Collection<String> keys(final String pattern){return redisTemplate.keys(pattern);}public void incrementCacheMapValue(String key,String hKey,long v) {redisTemplate.boundHashOps(key).increment(hKey, v);}}
public class WebUtils {/*** 将字符串渲染到客户端** @param response 渲染对象* @param string 待渲染的字符串* @return null*/public static void renderString(HttpServletResponse response, String string) {try{response.setStatus(200);response.setContentType("application/json");response.setCharacterEncoding("utf-8");Writer().print(string);}catch (IOException e){e.printStackTrace();}}public static void setDownLoadHeader(String filename, HttpServletResponse response) throws UnsupportedEncodingException {response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");String fname= de(filename,"UTF-8").replaceAll("\+", "%20");response.setHeader("Content-disposition","attachment; filename="+fname);}}
本文发布于:2024-01-30 17:10:51,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170660585721564.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |