17 changed files with 651 additions and 3 deletions
-
5pom.xml
-
11src/main/java/com/iflytop/nuclear/NuclearApplication.java
-
68src/main/java/com/iflytop/nuclear/config/SecurityConfig.java
-
56src/main/java/com/iflytop/nuclear/controller/AccountController.java
-
80src/main/java/com/iflytop/nuclear/entity/JwtUser.java
-
25src/main/java/com/iflytop/nuclear/exception/JWTAccessDeniedHandler.java
-
28src/main/java/com/iflytop/nuclear/exception/JWTAuthenticationEntryPoint.java
-
27src/main/java/com/iflytop/nuclear/exception/TokenIsExpiredException.java
-
77src/main/java/com/iflytop/nuclear/filter/JWTAuthenticationFilter.java
-
73src/main/java/com/iflytop/nuclear/filter/JWTAuthorizationFilter.java
-
13src/main/java/com/iflytop/nuclear/mapper/AccountMapper.java
-
26src/main/java/com/iflytop/nuclear/model/Account.java
-
16src/main/java/com/iflytop/nuclear/service/AccountService.java
-
28src/main/java/com/iflytop/nuclear/service/UserDetailsServiceImpl.java
-
51src/main/java/com/iflytop/nuclear/service/impl/AccountServiceImpl.java
-
68src/main/java/com/iflytop/nuclear/utils/JwtTokenUtils.java
-
2src/main/resources/application-dev.yml
@ -1,15 +1,22 @@ |
|||
package com.iflytop.nuclear; |
|||
|
|||
import org.mybatis.spring.annotation.MapperScan; |
|||
import org.springframework.boot.Banner; |
|||
import org.springframework.boot.ResourceBanner; |
|||
import org.springframework.boot.SpringApplication; |
|||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
|||
import org.springframework.boot.builder.SpringApplicationBuilder; |
|||
import org.springframework.core.io.ClassPathResource; |
|||
|
|||
@SpringBootApplication |
|||
@MapperScan("com.iflytop.boditech.mapper") |
|||
@MapperScan("com.iflytop.nuclear.mapper") |
|||
public class NuclearApplication { |
|||
|
|||
public static void main(String[] args) { |
|||
SpringApplication.run(NuclearApplication.class, args); |
|||
SpringApplicationBuilder builder = new SpringApplicationBuilder(NuclearApplication.class); |
|||
builder.bannerMode(Banner.Mode.CONSOLE); |
|||
builder.banner(new ResourceBanner(new ClassPathResource("banner.txt"))); |
|||
builder.run(args); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,68 @@ |
|||
package com.iflytop.nuclear.config; |
|||
|
|||
import com.iflytop.nuclear.exception.JWTAccessDeniedHandler; |
|||
import com.iflytop.nuclear.exception.JWTAuthenticationEntryPoint; |
|||
import com.iflytop.nuclear.filter.JWTAuthenticationFilter; |
|||
import com.iflytop.nuclear.filter.JWTAuthorizationFilter; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.beans.factory.annotation.Qualifier; |
|||
import org.springframework.context.annotation.Bean; |
|||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; |
|||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; |
|||
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.UserDetailsService; |
|||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; |
|||
import org.springframework.web.cors.CorsConfiguration; |
|||
import org.springframework.web.cors.CorsConfigurationSource; |
|||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource; |
|||
|
|||
/** |
|||
* @author cool |
|||
* @desc spring-security 配置类 |
|||
*/ |
|||
@EnableWebSecurity |
|||
@EnableGlobalMethodSecurity(prePostEnabled = true) |
|||
public class SecurityConfig extends WebSecurityConfigurerAdapter { |
|||
|
|||
@Autowired |
|||
@Qualifier("userDetailsServiceImpl") |
|||
private UserDetailsService userDetailsService; |
|||
|
|||
@Bean |
|||
public BCryptPasswordEncoder bCryptPasswordEncoder() { |
|||
return new BCryptPasswordEncoder(); |
|||
} |
|||
|
|||
@Override |
|||
protected void configure(AuthenticationManagerBuilder auth) throws Exception { |
|||
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder()); |
|||
} |
|||
|
|||
@Override |
|||
protected void configure(HttpSecurity http) throws Exception { |
|||
http.cors().and().csrf().disable() |
|||
.authorizeRequests() |
|||
// 注册接口,需要ADMIN用户才能访问 |
|||
.antMatchers("/account/register").hasRole("ADMIN") |
|||
// 其他都放行了 |
|||
.anyRequest().permitAll() |
|||
.and() |
|||
.addFilter(new JWTAuthenticationFilter(authenticationManager())) |
|||
.addFilter(new JWTAuthorizationFilter(authenticationManager())) |
|||
// 不需要session |
|||
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) |
|||
.and() |
|||
.exceptionHandling().authenticationEntryPoint(new JWTAuthenticationEntryPoint()) |
|||
.accessDeniedHandler(new JWTAccessDeniedHandler()); //添加无权限时的处理 |
|||
} |
|||
|
|||
@Bean |
|||
CorsConfigurationSource corsConfigurationSource() { |
|||
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); |
|||
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues()); |
|||
return source; |
|||
} |
|||
} |
@ -0,0 +1,56 @@ |
|||
package com.iflytop.nuclear.controller; |
|||
|
|||
import com.iflytop.nuclear.model.Account; |
|||
import com.iflytop.nuclear.service.AccountService; |
|||
import com.iflytop.nuclear.utils.ResponseData; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.security.access.prepost.PreAuthorize; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* @author cool |
|||
* @desc 用户接口 |
|||
*/ |
|||
@Slf4j |
|||
@RestController |
|||
@RequestMapping("/account") |
|||
public class AccountController { |
|||
|
|||
@Autowired |
|||
AccountService accountService; |
|||
|
|||
/** |
|||
* 查询用户列表 |
|||
* @return |
|||
*/ |
|||
@GetMapping("/list") |
|||
public ResponseData getAccountList() { |
|||
log.info("-----------------查询账户列表开始-----------------"); |
|||
// 筛除password |
|||
// TODO |
|||
List<Account> accounts = accountService.list(); |
|||
log.info("-----------------查询账户列表结束-----------------"); |
|||
return ResponseData.success(accounts); |
|||
} |
|||
|
|||
/** |
|||
* 注册接口,需要有ADMIN权限 |
|||
* @param registerUser |
|||
* @return |
|||
*/ |
|||
@PostMapping("/register") |
|||
@PreAuthorize("hasRole('ADMIN')") |
|||
public ResponseData registerAccount(@RequestBody Map<String,String> registerUser) { |
|||
log.info("-----------------注册账户开始-----------------"); |
|||
boolean register = accountService.register(registerUser.get("username"), registerUser.get("password")); |
|||
if (register) { |
|||
log.info("-----------------注册账户成功-----------------"); |
|||
return ResponseData.success(); |
|||
} |
|||
return ResponseData.fail("注册失败"); |
|||
} |
|||
} |
@ -0,0 +1,80 @@ |
|||
package com.iflytop.nuclear.entity; |
|||
|
|||
import com.iflytop.nuclear.model.Account; |
|||
import org.springframework.security.core.GrantedAuthority; |
|||
import org.springframework.security.core.authority.SimpleGrantedAuthority; |
|||
import org.springframework.security.core.userdetails.UserDetails; |
|||
|
|||
import java.util.Collection; |
|||
import java.util.Collections; |
|||
|
|||
/** |
|||
* @author cool |
|||
* @desc 自定义实现UserDetails |
|||
*/ |
|||
public class JwtUser implements UserDetails { |
|||
|
|||
private Long id; |
|||
private String username; |
|||
private String password; |
|||
private Collection<? extends GrantedAuthority> authorities; |
|||
|
|||
public JwtUser() { |
|||
} |
|||
|
|||
// 写一个能直接使用user创建jwtUser的构造器 |
|||
public JwtUser(Account user) { |
|||
id = user.getId(); |
|||
username = user.getUsername(); |
|||
password = user.getPassword(); |
|||
authorities = Collections.singleton(new SimpleGrantedAuthority(user.getRole())); |
|||
} |
|||
|
|||
@Override |
|||
public Collection<? extends GrantedAuthority> getAuthorities() { |
|||
return authorities; |
|||
} |
|||
|
|||
@Override |
|||
public String getPassword() { |
|||
return password; |
|||
} |
|||
|
|||
@Override |
|||
public String getUsername() { |
|||
return username; |
|||
} |
|||
|
|||
// 账号是否未过期 |
|||
@Override |
|||
public boolean isAccountNonExpired() { |
|||
return true; |
|||
} |
|||
|
|||
// 账号是否未锁定 |
|||
@Override |
|||
public boolean isAccountNonLocked() { |
|||
return true; |
|||
} |
|||
|
|||
// 账号凭证是否未过期 |
|||
@Override |
|||
public boolean isCredentialsNonExpired() { |
|||
return true; |
|||
} |
|||
|
|||
@Override |
|||
public boolean isEnabled() { |
|||
return true; |
|||
} |
|||
|
|||
@Override |
|||
public String toString() { |
|||
return "JwtUser{" + |
|||
"id=" + id + |
|||
", username='" + username + '\'' + |
|||
", password='" + password + '\'' + |
|||
", authorities=" + authorities + |
|||
'}'; |
|||
} |
|||
} |
@ -0,0 +1,25 @@ |
|||
package com.iflytop.nuclear.exception; |
|||
|
|||
import com.fasterxml.jackson.databind.ObjectMapper; |
|||
import org.springframework.security.access.AccessDeniedException; |
|||
import org.springframework.security.web.access.AccessDeniedHandler; |
|||
|
|||
import javax.servlet.ServletException; |
|||
import javax.servlet.http.HttpServletRequest; |
|||
import javax.servlet.http.HttpServletResponse; |
|||
import java.io.IOException; |
|||
|
|||
/** |
|||
* @author cool |
|||
* @description: 没有访问权限 |
|||
*/ |
|||
public class JWTAccessDeniedHandler implements AccessDeniedHandler { |
|||
@Override |
|||
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException { |
|||
httpServletResponse.setCharacterEncoding("UTF-8"); |
|||
httpServletResponse.setContentType("application/json; charset=utf-8"); |
|||
httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN); |
|||
String reason = "统一处理,原因:" + e.getMessage(); |
|||
httpServletResponse.getWriter().write(new ObjectMapper().writeValueAsString(reason)); |
|||
} |
|||
} |
@ -0,0 +1,28 @@ |
|||
package com.iflytop.nuclear.exception; |
|||
|
|||
import com.fasterxml.jackson.databind.ObjectMapper; |
|||
import org.springframework.security.core.AuthenticationException; |
|||
import org.springframework.security.web.AuthenticationEntryPoint; |
|||
|
|||
import javax.servlet.ServletException; |
|||
import javax.servlet.http.HttpServletRequest; |
|||
import javax.servlet.http.HttpServletResponse; |
|||
import java.io.IOException; |
|||
|
|||
/** |
|||
* @author cool |
|||
* @description: 没有携带token或者token无效 |
|||
*/ |
|||
public class JWTAuthenticationEntryPoint implements AuthenticationEntryPoint { |
|||
@Override |
|||
public void commence(HttpServletRequest request, |
|||
HttpServletResponse response, |
|||
AuthenticationException authException) throws IOException, ServletException { |
|||
|
|||
response.setCharacterEncoding("UTF-8"); |
|||
response.setContentType("application/json; charset=utf-8"); |
|||
response.setStatus(HttpServletResponse.SC_FORBIDDEN); |
|||
String reason = "统一处理,原因:" + authException.getMessage(); |
|||
response.getWriter().write(new ObjectMapper().writeValueAsString(reason)); |
|||
} |
|||
} |
@ -0,0 +1,27 @@ |
|||
package com.iflytop.nuclear.exception; |
|||
|
|||
/** |
|||
* @author cool |
|||
* @description: 自定义异常 |
|||
*/ |
|||
public class TokenIsExpiredException extends Exception { |
|||
|
|||
public TokenIsExpiredException() { |
|||
} |
|||
|
|||
public TokenIsExpiredException(String message) { |
|||
super(message); |
|||
} |
|||
|
|||
public TokenIsExpiredException(String message, Throwable cause) { |
|||
super(message, cause); |
|||
} |
|||
|
|||
public TokenIsExpiredException(Throwable cause) { |
|||
super(cause); |
|||
} |
|||
|
|||
public TokenIsExpiredException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { |
|||
super(message, cause, enableSuppression, writableStackTrace); |
|||
} |
|||
} |
@ -0,0 +1,77 @@ |
|||
package com.iflytop.nuclear.filter; |
|||
|
|||
import com.fasterxml.jackson.databind.ObjectMapper; |
|||
import com.iflytop.nuclear.entity.JwtUser; |
|||
import com.iflytop.nuclear.model.Account; |
|||
import com.iflytop.nuclear.utils.JwtTokenUtils; |
|||
import org.springframework.security.authentication.AuthenticationManager; |
|||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
|||
import org.springframework.security.core.Authentication; |
|||
import org.springframework.security.core.AuthenticationException; |
|||
import org.springframework.security.core.GrantedAuthority; |
|||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; |
|||
|
|||
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.ArrayList; |
|||
import java.util.Collection; |
|||
|
|||
/** |
|||
* @author cool |
|||
* @desc 该过滤器用于获取用户登录的信息 |
|||
*/ |
|||
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter { |
|||
|
|||
private AuthenticationManager authenticationManager; |
|||
|
|||
public JWTAuthenticationFilter(AuthenticationManager authenticationManager) { |
|||
this.authenticationManager = authenticationManager; |
|||
super.setFilterProcessesUrl("/account/login"); |
|||
} |
|||
|
|||
@Override |
|||
public Authentication attemptAuthentication(HttpServletRequest request, |
|||
HttpServletResponse response) throws AuthenticationException { |
|||
|
|||
// 从输入流中获取到登录的信息 |
|||
try { |
|||
Account loginUser = new ObjectMapper().readValue(request.getInputStream(), Account.class); |
|||
return authenticationManager.authenticate( |
|||
new UsernamePasswordAuthenticationToken(loginUser.getUsername(), loginUser.getPassword(), new ArrayList<>()) |
|||
); |
|||
} catch (IOException e) { |
|||
e.printStackTrace(); |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
// 成功验证后调用的方法 |
|||
// 如果验证成功,就生成token并返回 |
|||
@Override |
|||
protected void successfulAuthentication(HttpServletRequest request, |
|||
HttpServletResponse response, |
|||
FilterChain chain, |
|||
Authentication authResult) throws IOException, ServletException { |
|||
|
|||
JwtUser jwtUser = (JwtUser) authResult.getPrincipal(); |
|||
System.out.println("jwtUser:" + jwtUser.toString()); |
|||
String role = ""; |
|||
Collection<? extends GrantedAuthority> authorities = jwtUser.getAuthorities(); |
|||
for (GrantedAuthority authority : authorities){ |
|||
role = authority.getAuthority(); |
|||
} |
|||
String token = JwtTokenUtils.createToken(jwtUser.getUsername(), role); |
|||
// 返回创建成功的token |
|||
// 但是这里创建的token只是单纯的token |
|||
// 按照jwt的规定,最后请求的时候应该是 `Bearer token` |
|||
response.setHeader("token", JwtTokenUtils.TOKEN_PREFIX + token); |
|||
} |
|||
|
|||
@Override |
|||
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException { |
|||
response.getWriter().write("authentication failed, reason: " + failed.getMessage()); |
|||
} |
|||
} |
@ -0,0 +1,73 @@ |
|||
package com.iflytop.nuclear.filter; |
|||
|
|||
import com.fasterxml.jackson.databind.ObjectMapper; |
|||
import com.iflytop.nuclear.exception.TokenIsExpiredException; |
|||
import com.iflytop.nuclear.utils.JwtTokenUtils; |
|||
import org.springframework.security.authentication.AuthenticationManager; |
|||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
|||
import org.springframework.security.core.authority.SimpleGrantedAuthority; |
|||
import org.springframework.security.core.context.SecurityContextHolder; |
|||
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; |
|||
|
|||
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.Collections; |
|||
|
|||
/** |
|||
* @author cool |
|||
* @desc 鉴权 |
|||
*/ |
|||
public class JWTAuthorizationFilter extends BasicAuthenticationFilter { |
|||
|
|||
public JWTAuthorizationFilter(AuthenticationManager authenticationManager) { |
|||
super(authenticationManager); |
|||
} |
|||
|
|||
@Override |
|||
protected void doFilterInternal(HttpServletRequest request, |
|||
HttpServletResponse response, |
|||
FilterChain chain) throws IOException, ServletException { |
|||
|
|||
String tokenHeader = request.getHeader(JwtTokenUtils.TOKEN_HEADER); |
|||
// 如果请求头中没有Authorization信息则直接放行了 |
|||
if (tokenHeader == null || !tokenHeader.startsWith(JwtTokenUtils.TOKEN_PREFIX)) { |
|||
chain.doFilter(request, response); |
|||
return; |
|||
} |
|||
// 如果请求头中有token,则进行解析,并且设置认证信息 |
|||
try { |
|||
SecurityContextHolder.getContext().setAuthentication(getAuthentication(tokenHeader)); |
|||
} catch (TokenIsExpiredException e) { |
|||
//返回json形式的错误信息 |
|||
response.setCharacterEncoding("UTF-8"); |
|||
response.setContentType("application/json; charset=utf-8"); |
|||
response.setStatus(HttpServletResponse.SC_FORBIDDEN); |
|||
String reason = "统一处理,原因:" + e.getMessage(); |
|||
response.getWriter().write(new ObjectMapper().writeValueAsString(reason)); |
|||
response.getWriter().flush(); |
|||
return; |
|||
} |
|||
super.doFilterInternal(request, response, chain); |
|||
} |
|||
|
|||
// 这里从token中获取用户信息并新建一个token |
|||
private UsernamePasswordAuthenticationToken getAuthentication(String tokenHeader) throws TokenIsExpiredException { |
|||
String token = tokenHeader.replace(JwtTokenUtils.TOKEN_PREFIX, ""); |
|||
boolean expiration = JwtTokenUtils.isExpiration(token); |
|||
if (expiration) { |
|||
throw new TokenIsExpiredException("token超时了"); |
|||
} else { |
|||
String username = JwtTokenUtils.getUsername(token); |
|||
String role = JwtTokenUtils.getUserRole(token); |
|||
if (username != null) { |
|||
return new UsernamePasswordAuthenticationToken(username, null, |
|||
Collections.singleton(new SimpleGrantedAuthority(role)) |
|||
); |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
} |
@ -0,0 +1,13 @@ |
|||
package com.iflytop.nuclear.mapper; |
|||
|
|||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
|||
import com.iflytop.nuclear.model.Account; |
|||
import org.apache.ibatis.annotations.Mapper; |
|||
|
|||
/** |
|||
* @author cool |
|||
*/ |
|||
@Mapper |
|||
public interface AccountMapper extends BaseMapper<Account> { |
|||
|
|||
} |
@ -0,0 +1,26 @@ |
|||
package com.iflytop.nuclear.model; |
|||
|
|||
import com.baomidou.mybatisplus.annotation.TableId; |
|||
import com.baomidou.mybatisplus.annotation.TableName; |
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Builder; |
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
/** |
|||
* @author cool |
|||
* @desc 账户model |
|||
*/ |
|||
@Data |
|||
@TableName("account") |
|||
@Builder |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
public class Account { |
|||
@TableId |
|||
private Long id; |
|||
private String username; |
|||
private String password; |
|||
private String role; |
|||
private String nickname; |
|||
} |
@ -0,0 +1,16 @@ |
|||
package com.iflytop.nuclear.service; |
|||
|
|||
import com.baomidou.mybatisplus.extension.service.IService; |
|||
import com.iflytop.nuclear.model.Account; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
|
|||
/** |
|||
* @author cool |
|||
*/ |
|||
@Transactional |
|||
public interface AccountService extends IService<Account> { |
|||
|
|||
boolean register(String username, String password); |
|||
|
|||
Account findByUsername(String username); |
|||
} |
@ -0,0 +1,28 @@ |
|||
package com.iflytop.nuclear.service; |
|||
|
|||
import com.iflytop.nuclear.entity.JwtUser; |
|||
import com.iflytop.nuclear.model.Account; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.context.annotation.Lazy; |
|||
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; |
|||
|
|||
/** |
|||
* @author cool |
|||
* @desc 使用springSecurity需要实现UserDetailsService接口供权限框架调用 |
|||
*/ |
|||
@Service |
|||
public class UserDetailsServiceImpl implements UserDetailsService { |
|||
|
|||
@Autowired |
|||
@Lazy |
|||
AccountService accountService; |
|||
|
|||
@Override |
|||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { |
|||
Account user = accountService.findByUsername(username); |
|||
return new JwtUser(user); |
|||
} |
|||
} |
@ -0,0 +1,51 @@ |
|||
package com.iflytop.nuclear.service.impl; |
|||
|
|||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
|||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
|||
import com.iflytop.nuclear.mapper.AccountMapper; |
|||
import com.iflytop.nuclear.model.Account; |
|||
import com.iflytop.nuclear.service.AccountService; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.context.annotation.Lazy; |
|||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
/** |
|||
* @author cool |
|||
*/ |
|||
@Service |
|||
public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> implements AccountService { |
|||
|
|||
@Autowired |
|||
@Lazy |
|||
private BCryptPasswordEncoder bCryptPasswordEncoder; |
|||
|
|||
/** |
|||
* 注册用户 |
|||
* @param username |
|||
* @param password |
|||
* @return |
|||
*/ |
|||
@Override |
|||
public boolean register(String username, String password) { |
|||
Account account = Account.builder() |
|||
.username(username) |
|||
.password(bCryptPasswordEncoder.encode(password)) |
|||
.role("ROLE_USER") |
|||
.build(); |
|||
return this.save(account); |
|||
} |
|||
|
|||
/** |
|||
* 根据用户名查找用户 |
|||
* @param username |
|||
* @return |
|||
*/ |
|||
@Override |
|||
public Account findByUsername(String username) { |
|||
QueryWrapper<Account> accountQueryWrapper = new QueryWrapper<>(); |
|||
accountQueryWrapper.eq("username", username); |
|||
Account account = this.getOne(accountQueryWrapper); |
|||
return account; |
|||
} |
|||
} |
@ -0,0 +1,68 @@ |
|||
package com.iflytop.nuclear.utils; |
|||
|
|||
import io.jsonwebtoken.Claims; |
|||
import io.jsonwebtoken.ExpiredJwtException; |
|||
import io.jsonwebtoken.Jwts; |
|||
import io.jsonwebtoken.SignatureAlgorithm; |
|||
|
|||
import java.util.Date; |
|||
import java.util.HashMap; |
|||
|
|||
/** |
|||
* @author cool |
|||
* @desc 操作jwt token 的工具类 |
|||
*/ |
|||
public class JwtTokenUtils { |
|||
|
|||
public static final String TOKEN_HEADER = "Authorization"; |
|||
public static final String TOKEN_PREFIX = "Bearer "; |
|||
|
|||
private static final String SECRET = "eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2NDg5ODg1MjAsInN1YiI6ImFkbWluIiwiY3JlYXR"; |
|||
private static final String ISS = "iflytop"; |
|||
|
|||
// 角色的key |
|||
private static final String ROLE_CLAIMS = "rol"; |
|||
|
|||
// 过期时间是3600秒,既是1个小时 |
|||
private static final long EXPIRATION = 3600L; |
|||
|
|||
// 创建token |
|||
public static String createToken(String username, String role) { |
|||
HashMap<String, Object> map = new HashMap<>(); |
|||
map.put(ROLE_CLAIMS, role); |
|||
return Jwts.builder() |
|||
.signWith(SignatureAlgorithm.HS512, SECRET) |
|||
.setClaims(map) |
|||
.setIssuer(ISS) |
|||
.setSubject(username) |
|||
.setIssuedAt(new Date()) |
|||
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION * 1000)) |
|||
.compact(); |
|||
} |
|||
|
|||
// 从token中获取用户名 |
|||
public static String getUsername(String token){ |
|||
return getTokenBody(token).getSubject(); |
|||
} |
|||
|
|||
// 获取用户角色 |
|||
public static String getUserRole(String token){ |
|||
return (String) getTokenBody(token).get(ROLE_CLAIMS); |
|||
} |
|||
|
|||
// 是否已过期 |
|||
public static boolean isExpiration(String token) { |
|||
try { |
|||
return getTokenBody(token).getExpiration().before(new Date()); |
|||
} catch (ExpiredJwtException e) { |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
private static Claims getTokenBody(String token){ |
|||
return Jwts.parser() |
|||
.setSigningKey(SECRET) |
|||
.parseClaimsJws(token) |
|||
.getBody(); |
|||
} |
|||
} |
@ -1,7 +1,7 @@ |
|||
|
|||
spring: |
|||
datasource: |
|||
url: jdbc:mysql://127.0.0.1:3306/boditech?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai |
|||
url: jdbc:mysql://127.0.0.1:3306/nuclear?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai |
|||
username: root |
|||
password: root |
|||
driverClassName: com.mysql.cj.jdbc.Driver |
Write
Preview
Loading…
Cancel
Save
Reference in new issue