微信小程序使用springsecurity和jwt实现权限验证java代码
时间: 2023-11-27 13:55:20 浏览: 105
以下是微信小程序使用Spring Security和JWT实现权限验证的Java代码示例:
1. 配置Spring Security
创建一个SecurityConfig类,配置Spring Security的基本设置和JWT过滤器:
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
@Autowired
private JwtAuthorizationTokenFilter jwtAuthorizationTokenFilter;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
httpSecurity.addFilterBefore(jwtAuthorizationTokenFilter, UsernamePasswordAuthenticationFilter.class);
httpSecurity.headers().cacheControl();
}
@Override
public void configure(WebSecurity webSecurity) throws Exception {
webSecurity.ignoring().antMatchers(HttpMethod.POST, "/api/auth/login");
}
}
```
2. 创建JWT工具类
创建一个JwtTokenUtil类,用于处理JWT的生成、解析和验证:
```java
@Component
public class JwtTokenUtil {
private static final Logger logger = LoggerFactory.getLogger(JwtTokenUtil.class);
private static final String CLAIM_KEY_USERNAME = "sub";
private static final String CLAIM_KEY_CREATED = "iat";
private static final String CLAIM_KEY_EXPIRED = "exp";
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expiration}")
private Long expiration;
public String getUsernameFromToken(String token) {
String username;
try {
final Claims claims = getClaimsFromToken(token);
username = claims.getSubject();
} catch (Exception e) {
username = null;
}
return username;
}
public Date getCreatedDateFromToken(String token) {
Date created;
try {
final Claims claims = getClaimsFromToken(token);
created = new Date((Long) claims.get(CLAIM_KEY_CREATED));
} catch (Exception e) {
created = null;
}
return created;
}
public Date getExpirationDateFromToken(String token) {
Date expiration;
try {
final Claims claims = getClaimsFromToken(token);
expiration = claims.getExpiration();
} catch (Exception e) {
expiration = null;
}
return expiration;
}
private Claims getClaimsFromToken(String token) {
Claims claims;
try {
claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
} catch (Exception e) {
claims = null;
}
return claims;
}
private Date generateExpirationDate() {
return new Date(System.currentTimeMillis() + expiration * 1000);
}
private Boolean isTokenExpired(String token) {
final Date expiration = getExpirationDateFromToken(token);
return expiration.before(new Date());
}
public String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
claims.put(CLAIM_KEY_USERNAME, userDetails.getUsername());
claims.put(CLAIM_KEY_CREATED, new Date());
return generateToken(claims);
}
private String generateToken(Map<String, Object> claims) {
return Jwts.builder()
.setClaims(claims)
.setExpiration(generateExpirationDate())
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
public Boolean canTokenBeRefreshed(String token) {
return !isTokenExpired(token);
}
public String refreshToken(String token) {
String refreshedToken;
try {
final Claims claims = getClaimsFromToken(token);
claims.put(CLAIM_KEY_CREATED, new Date());
refreshedToken = generateToken(claims);
} catch (Exception e) {
refreshedToken = null;
}
return refreshedToken;
}
public Boolean validateToken(String token, UserDetails userDetails) {
JwtUser user = (JwtUser) userDetails;
final String username = getUsernameFromToken(token);
return (
username.equals(user.getUsername())
&& !isTokenExpired(token));
}
}
```
3. 创建JWT过滤器
创建一个JwtAuthorizationTokenFilter类,用于处理JWT的解析和验证:
```java
@Component
public class JwtAuthorizationTokenFilter extends OncePerRequestFilter {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
logger.debug("processing authentication for '{}'", request.getRequestURL());
final String requestHeader = request.getHeader("Authorization");
String username = null;
String authToken = null;
if (requestHeader != null && requestHeader.startsWith("Bearer ")) {
authToken = requestHeader.substring(7);
try {
username = jwtTokenUtil.getUsernameFromToken(authToken);
} catch (IllegalArgumentException e) {
logger.error("an error occured during getting username from token", e);
} catch (ExpiredJwtException e) {
logger.warn("the token is expired and not valid anymore", e);
}
} else {
logger.warn("couldn't find bearer string, will ignore the header");
}
logger.debug("checking authentication for user '{}'", username);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (jwtTokenUtil.validateToken(authToken, userDetails)) {
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
logger.info("authenticated user '{}', setting security context", username);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
chain.doFilter(request, response);
}
}
```
4. 创建JWT用户类
创建一个JwtUser类,实现Spring Security的UserDetails接口:
```java
public class JwtUser implements UserDetails {
private final Long id;
private final String username;
private final String password;
private final Collection<? extends GrantedAuthority> authorities;
private final boolean enabled;
private final Date lastPasswordResetDate;
public JwtUser(
Long id,
String username,
String password,
Collection<? extends GrantedAuthority> authorities,
boolean enabled,
Date lastPasswordResetDate
) {
this.id = id;
this.username = username;
this.password = password;
this.authorities = authorities;
this.enabled = enabled;
this.lastPasswordResetDate = lastPasswordResetDate;
}
@JsonIgnore
public Long getId() {
return id;
}
@Override
public String getUsername() {
return username;
}
@JsonIgnore
@Override
public boolean isAccountNonExpired() {
return true;
}
@JsonIgnore
@Override
public boolean isAccountNonLocked() {
return true;
}
@JsonIgnore
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@JsonIgnore
@Override
public String getPassword() {
return password;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public boolean isEnabled() {
return enabled;
}
@JsonIgnore
public Date getLastPasswordResetDate() {
return lastPasswordResetDate;
}
}
```
5. 创建登录控制器
创建一个AuthController类,用于处理用户登录和令牌的生成:
```java
@RestController
@RequestMapping("/api/auth")
public class AuthController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Autowired
private UserDetailsService userDetailsService;
@PostMapping("/login")
public ResponseEntity<?> createAuthenticationToken(@RequestBody JwtAuthenticationRequest authenticationRequest) throws AuthenticationException {
logger.info("authenticating user '{}'", authenticationRequest.getUsername());
final Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
authenticationRequest.getUsername(),
authenticationRequest.getPassword()
)
);
SecurityContextHolder.getContext().setAuthentication(authentication);
final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());
final String token = jwtTokenUtil.generateToken(userDetails);
return ResponseEntity.ok(new JwtAuthenticationResponse(token));
}
}
```
6. 创建异常处理器
创建一个JwtAuthenticationEntryPoint类,用于处理不允许访问的请求:
```java
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
logger.error("unauthorized error: {}", authException.getMessage());
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
```
7. 创建请求对象
创建一个JwtAuthenticationRequest类,用于保存用户登录请求:
```java
public class JwtAuthenticationRequest implements Serializable {
private static final long serialVersionUID = -8445943548965154778L;
@NotBlank
private String username;
@NotBlank
private String password;
public JwtAuthenticationRequest() {
super();
}
public JwtAuthenticationRequest(String username, String password) {
this.setUsername(username);
this.setPassword(password);
}
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
}
```
8. 创建响应对象
创建一个JwtAuthenticationResponse类,用于保存令牌响应:
```java
public class JwtAuthenticationResponse implements Serializable {
private static final long serialVersionUID = 1250166508152483573L;
private final String token;
public JwtAuthenticationResponse(String token) {
this.token = token;
}
public String getToken() {
return this.token;
}
}
```
以上是微信小程序使用Spring Security和JWT实现权限验证的Java代码示例,希望能对你有所帮助。
阅读全文