相册特效手机网站,重庆最好的网站建设,教育投资网站建设方案,格力空调显示h5是什么意思Springboot结合SpringSecurity实现身份认证以及接口鉴权 身份认证1. 添加依赖2. 配置JWT工具类3. 配置Spring Security4. 创建JWT请求过滤器5. 创建认证控制器6. 创建请求和响应对象7. 配置UserDetailsService8. 运行应用程序9. 测试总结 接口鉴权1. 启用方法级安全注解2. 定义… Springboot结合SpringSecurity实现身份认证以及接口鉴权 身份认证1. 添加依赖2. 配置JWT工具类3. 配置Spring Security4. 创建JWT请求过滤器5. 创建认证控制器6. 创建请求和响应对象7. 配置UserDetailsService8. 运行应用程序9. 测试总结 接口鉴权1. 启用方法级安全注解2. 定义角色和权限示例定义用户角色 3. 使用注解进行接口鉴权1. PreAuthorize2. PostAuthorize3. Secured4. RolesAllowed 4. 配置全局异常处理5. 测试接口鉴权1. 登录获取Token2. 访问受保护的接口 6. 总结 相关文献  身份认证 
在Spring Boot中使用Spring Security和JWTJSON Web Token实现身份认证和接口鉴权是一个常见的需求。下面是一个完整的示例展示了如何实现这些功能并支持Token刷新。 
1. 添加依赖 
首先在pom.xml中添加必要的依赖 
dependencies!-- Spring Boot Starter Web --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!-- Spring Boot Starter Security --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactId/dependency!-- JWT Library --dependencygroupIdio.jsonwebtoken/groupIdartifactIdjjwt/artifactIdversion0.9.1/version/dependency!-- Spring Boot Starter Data JPA (Optional, for UserDetailsService) --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-jpa/artifactId/dependency!-- H2 Database (Optional, for testing) --dependencygroupIdcom.h2database/groupIdartifactIdh2/artifactIdscoperuntime/scope/dependency
/dependencies2. 配置JWT工具类 
创建一个JWT工具类用于生成和解析JWT Token。 
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;Component
public class JwtUtil {private String SECRET_KEY  secret;// 生成Tokenpublic String generateToken(UserDetails userDetails) {MapString, Object claims  new HashMap();return createToken(claims, userDetails.getUsername());}// 创建Tokenprivate String createToken(MapString, Object claims, String subject) {return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis())).setExpiration(new Date(System.currentTimeMillis()  1000 * 60 * 60 * 10)) // 10小时有效期.signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact();}// 验证Tokenpublic Boolean validateToken(String token, UserDetails userDetails) {final String username  extractUsername(token);return (username.equals(userDetails.getUsername())  !isTokenExpired(token));}// 提取用户名public String extractUsername(String token) {return extractClaim(token, Claims::getSubject);}// 提取过期时间public Date extractExpiration(String token) {return extractClaim(token, Claims::getExpiration);}// 提取Claimpublic T T extractClaim(String token, FunctionClaims, T claimsResolver) {final Claims claims  extractAllClaims(token);return claimsResolver.apply(claims);}// 提取所有Claimprivate Claims extractAllClaims(String token) {return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();}// 判断Token是否过期private Boolean isTokenExpired(String token) {return extractExpiration(token).before(new Date());}
}3. 配置Spring Security 
创建一个Spring Security配置类配置身份认证和接口鉴权。 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {Autowiredprivate UserDetailsService userDetailsService;Autowiredprivate JwtRequestFilter jwtRequestFilter;Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService);}Overrideprotected void configure(HttpSecurity http) throws Exception {http.csrf().disable().authorizeRequests().antMatchers(/authenticate, /refreshToken).permitAll() // 允许匿名访问的接口.anyRequest().authenticated() // 其他接口需要认证.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); // 无状态会话http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);}Beanpublic PasswordEncoder passwordEncoder() {return NoOpPasswordEncoder.getInstance(); // 仅用于示例生产环境应使用BCryptPasswordEncoder}OverrideBeanpublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}
}4. 创建JWT请求过滤器 
创建一个过滤器用于在每次请求中验证JWT Token。 
import org.springframework.beans.factory.annotation.Autowired;
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;Component
public class JwtRequestFilter extends OncePerRequestFilter {Autowiredprivate UserDetailsService userDetailsService;Autowiredprivate JwtUtil jwtUtil;Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)throws ServletException, IOException {final String authorizationHeader  request.getHeader(Authorization);String username  null;String jwt  null;if (authorizationHeader ! null  authorizationHeader.startsWith(Bearer )) {jwt  authorizationHeader.substring(7);username  jwtUtil.extractUsername(jwt);}if (username ! null  SecurityContextHolder.getContext().getAuthentication()  null) {UserDetails userDetails  this.userDetailsService.loadUserByUsername(username);if (jwtUtil.validateToken(jwt, userDetails)) {UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken  new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);}}chain.doFilter(request, response);}
}5. 创建认证控制器 
创建一个控制器用于处理用户登录和Token刷新。 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.*;RestController
public class AuthenticationController {Autowiredprivate AuthenticationManager authenticationManager;Autowiredprivate UserDetailsService userDetailsService;Autowiredprivate JwtUtil jwtUtil;PostMapping(/authenticate)public ResponseEntity? createAuthenticationToken(RequestBody AuthenticationRequest authenticationRequest) throws Exception {try {authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(authenticationRequest.getUsername(), authenticationRequest.getPassword()));} catch (Exception e) {throw new Exception(Incorrect username or password, e);}final UserDetails userDetails  userDetailsService.loadUserByUsername(authenticationRequest.getUsername());final String jwt  jwtUtil.generateToken(userDetails);return ResponseEntity.ok(new AuthenticationResponse(jwt));}PostMapping(/refreshToken)public ResponseEntity? refreshAuthenticationToken(RequestHeader(Authorization) String oldToken) {String username  jwtUtil.extractUsername(oldToken.substring(7));UserDetails userDetails  userDetailsService.loadUserByUsername(username);if (jwtUtil.validateToken(oldToken.substring(7), userDetails)) {String newToken  jwtUtil.generateToken(userDetails);return ResponseEntity.ok(new AuthenticationResponse(newToken));}return ResponseEntity.badRequest().body(Invalid token);}
}6. 创建请求和响应对象 
创建用于封装请求和响应的对象。 
public class AuthenticationRequest {private String username;private String password;// Getters and Setters
}public class AuthenticationResponse {private final String jwt;public AuthenticationResponse(String jwt) {this.jwt  jwt;}public String getJwt() {return jwt;}
}7. 配置UserDetailsService 
实现UserDetailsService接口用于加载用户信息。 
import org.springframework.security.core.userdetails.User;
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 java.util.ArrayList;Service
public class MyUserDetailsService implements UserDetailsService {Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {// 这里可以从数据库中加载用户信息return new User(user, password, new ArrayList());}
}8. 运行应用程序 
现在你可以运行Spring Boot应用程序并通过以下接口进行测试 
登录接口: POST /authenticate刷新Token接口: POST /refreshToken受保护的接口: 任何其他接口都需要在请求头中添加Authorization: Bearer token。 
9. 测试 
你可以使用Postman或curl等工具进行测试 登录请求: POST /authenticate
{username: user,password: password
}刷新Token请求: POST /refreshToken
Authorization: Bearer old_token总结 
通过以上步骤我们实现了一个基于Spring Security和JWT的身份认证和接口鉴权系统并支持Token刷新。你可以根据实际需求进一步扩展和优化这个系统。 
接口鉴权 
在Spring Security中接口鉴权通常通过配置HttpSecurity来实现。我们可以使用注解如PreAuthorize、PostAuthorize、Secured等来细粒度地控制接口的访问权限。以下是接口鉴权的详细实现和示例。 1. 启用方法级安全注解 
在Spring Boot中默认情况下方法级安全注解是关闭的。我们需要在配置类中启用它。 
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;Configuration
EnableGlobalMethodSecurity(prePostEnabled  true,  // 启用PreAuthorize和PostAuthorize注解securedEnabled  true,  // 启用Secured注解jsr250Enabled  true    // 启用RolesAllowed注解
)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
}2. 定义角色和权限 
在Spring Security中角色和权限通常通过UserDetails实现类来定义。我们可以为用户分配角色或权限然后在接口上使用注解进行鉴权。 
示例定义用户角色 
在UserDetailsService中为用户分配角色 
import org.springframework.security.core.userdetails.User;
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 java.util.Arrays;Service
public class MyUserDetailsService implements UserDetailsService {Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {if (admin.equals(username)) {return new User(admin, password, Arrays.asList(new SimpleGrantedAuthority(ROLE_ADMIN)));} else if (user.equals(username)) {return new User(user, password, Arrays.asList(new SimpleGrantedAuthority(ROLE_USER)));} else {throw new UsernameNotFoundException(User not found with username:   username);}}
}3. 使用注解进行接口鉴权 
Spring Security提供了多种注解来实现接口鉴权。以下是常用的注解及其用法 
1. PreAuthorize 
在方法执行前进行权限检查。 
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;RestController
RequestMapping(/api)
public class ApiController {// 只有ADMIN角色可以访问GetMapping(/admin)PreAuthorize(hasRole(ADMIN))public String adminEndpoint() {return Hello Admin!;}// 只有USER角色可以访问GetMapping(/user)PreAuthorize(hasRole(USER))public String userEndpoint() {return Hello User!;}// 同时支持ADMIN和USER角色GetMapping(/all)PreAuthorize(hasAnyRole(ADMIN, USER))public String allEndpoint() {return Hello All!;}// 自定义权限表达式GetMapping(/custom)PreAuthorize(hasAuthority(READ_PRIVILEGE))public String customEndpoint() {return Custom Access!;}
}2. PostAuthorize 
在方法执行后进行权限检查。 
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;RestController
RequestMapping(/api)
public class ApiController {// 方法执行后检查返回值GetMapping(/postAuth)PostAuthorize(returnObject  Hello Admin!)public String postAuthEndpoint() {return Hello Admin!;}
}3. Secured 
基于角色的简单鉴权。 
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;RestController
RequestMapping(/api)
public class ApiController {// 只有ADMIN角色可以访问GetMapping(/secured)Secured(ROLE_ADMIN)public String securedEndpoint() {return Secured Access!;}
}4. RolesAllowed 
基于JSR-250标准的角色鉴权。 
import javax.annotation.security.RolesAllowed;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;RestController
RequestMapping(/api)
public class ApiController {// 只有ADMIN角色可以访问GetMapping(/rolesAllowed)RolesAllowed(ADMIN)public String rolesAllowedEndpoint() {return Roles Allowed Access!;}
}4. 配置全局异常处理 
当用户访问未授权的接口时Spring Security会抛出AccessDeniedException。我们可以通过全局异常处理来返回友好的错误信息。 
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;RestControllerAdvice
public class GlobalExceptionHandler {// 处理权限不足异常ExceptionHandler(AccessDeniedException.class)public ResponseEntityString handleAccessDeniedException(AccessDeniedException e) {return ResponseEntity.status(HttpStatus.FORBIDDEN).body(Access Denied:   e.getMessage());}// 处理其他异常ExceptionHandler(Exception.class)public ResponseEntityString handleException(Exception e) {return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Error:   e.getMessage());}
}5. 测试接口鉴权 
使用Postman或curl测试接口 
1. 登录获取Token 
POST /authenticate
{username: admin,password: password
}2. 访问受保护的接口 ADMIN接口: GET /api/admin
Authorization: Bearer tokenUSER接口: GET /api/user
Authorization: Bearer token未授权访问: 如果用户没有权限会返回403 Forbidden。  6. 总结 
通过以上步骤我们实现了基于Spring Security的接口鉴权功能。主要步骤包括 
启用方法级安全注解。定义用户角色和权限。使用注解如PreAuthorize、Secured等控制接口访问权限。配置全局异常处理返回友好的错误信息。 
你可以根据实际需求扩展和调整这些配置例如从数据库中动态加载权限、支持更复杂的权限表达式等。 
相关文献 
JWTJSON Web Tokens) 详细介绍 【spring知识】Spring Security从入门到放弃 文章转载自: http://www.morning.fwgnq.cn.gov.cn.fwgnq.cn http://www.morning.zphlb.cn.gov.cn.zphlb.cn http://www.morning.qctsd.cn.gov.cn.qctsd.cn http://www.morning.wjpsn.cn.gov.cn.wjpsn.cn http://www.morning.frsbf.cn.gov.cn.frsbf.cn http://www.morning.jtwck.cn.gov.cn.jtwck.cn http://www.morning.ywzqk.cn.gov.cn.ywzqk.cn http://www.morning.pgmyn.cn.gov.cn.pgmyn.cn http://www.morning.lfgql.cn.gov.cn.lfgql.cn http://www.morning.rfmzc.cn.gov.cn.rfmzc.cn http://www.morning.svrud.cn.gov.cn.svrud.cn http://www.morning.mrccd.cn.gov.cn.mrccd.cn http://www.morning.jfbpf.cn.gov.cn.jfbpf.cn http://www.morning.bbrf.cn.gov.cn.bbrf.cn http://www.morning.pyswr.cn.gov.cn.pyswr.cn http://www.morning.kstlm.cn.gov.cn.kstlm.cn http://www.morning.kwdfn.cn.gov.cn.kwdfn.cn http://www.morning.pudejun.com.gov.cn.pudejun.com http://www.morning.glbnc.cn.gov.cn.glbnc.cn http://www.morning.tgmfg.cn.gov.cn.tgmfg.cn http://www.morning.qhydkj.com.gov.cn.qhydkj.com http://www.morning.xxknq.cn.gov.cn.xxknq.cn http://www.morning.ybmp.cn.gov.cn.ybmp.cn http://www.morning.hqwcd.cn.gov.cn.hqwcd.cn http://www.morning.brps.cn.gov.cn.brps.cn http://www.morning.txfxy.cn.gov.cn.txfxy.cn http://www.morning.ccffs.cn.gov.cn.ccffs.cn http://www.morning.znsyn.cn.gov.cn.znsyn.cn http://www.morning.fznj.cn.gov.cn.fznj.cn http://www.morning.jkfyt.cn.gov.cn.jkfyt.cn http://www.morning.ldspj.cn.gov.cn.ldspj.cn http://www.morning.mzpd.cn.gov.cn.mzpd.cn http://www.morning.ccjhr.cn.gov.cn.ccjhr.cn http://www.morning.hdlhh.cn.gov.cn.hdlhh.cn http://www.morning.jtkfm.cn.gov.cn.jtkfm.cn http://www.morning.rrqbm.cn.gov.cn.rrqbm.cn http://www.morning.hwnnh.cn.gov.cn.hwnnh.cn http://www.morning.fbrshjf.com.gov.cn.fbrshjf.com http://www.morning.sqtsl.cn.gov.cn.sqtsl.cn http://www.morning.gcqdp.cn.gov.cn.gcqdp.cn http://www.morning.plqkz.cn.gov.cn.plqkz.cn http://www.morning.tfei69.cn.gov.cn.tfei69.cn http://www.morning.qpqb.cn.gov.cn.qpqb.cn http://www.morning.ryfpx.cn.gov.cn.ryfpx.cn http://www.morning.tsgxz.cn.gov.cn.tsgxz.cn http://www.morning.gqnll.cn.gov.cn.gqnll.cn http://www.morning.lydtr.cn.gov.cn.lydtr.cn http://www.morning.bqdpy.cn.gov.cn.bqdpy.cn http://www.morning.yfnjk.cn.gov.cn.yfnjk.cn http://www.morning.mdmqg.cn.gov.cn.mdmqg.cn http://www.morning.tqrxm.cn.gov.cn.tqrxm.cn http://www.morning.khcpx.cn.gov.cn.khcpx.cn http://www.morning.mzzqs.cn.gov.cn.mzzqs.cn http://www.morning.gnwse.com.gov.cn.gnwse.com http://www.morning.hqxyt.cn.gov.cn.hqxyt.cn http://www.morning.snrbl.cn.gov.cn.snrbl.cn http://www.morning.hncrc.cn.gov.cn.hncrc.cn http://www.morning.bscsp.cn.gov.cn.bscsp.cn http://www.morning.yggwn.cn.gov.cn.yggwn.cn http://www.morning.kjmws.cn.gov.cn.kjmws.cn http://www.morning.fmrwl.cn.gov.cn.fmrwl.cn http://www.morning.pzwfw.cn.gov.cn.pzwfw.cn http://www.morning.tsyny.cn.gov.cn.tsyny.cn http://www.morning.yesidu.com.gov.cn.yesidu.com http://www.morning.fkmrj.cn.gov.cn.fkmrj.cn http://www.morning.zlgbx.cn.gov.cn.zlgbx.cn http://www.morning.mtgkq.cn.gov.cn.mtgkq.cn http://www.morning.sbqrm.cn.gov.cn.sbqrm.cn http://www.morning.chbcj.cn.gov.cn.chbcj.cn http://www.morning.wqpsf.cn.gov.cn.wqpsf.cn http://www.morning.syssdz.cn.gov.cn.syssdz.cn http://www.morning.bmlcy.cn.gov.cn.bmlcy.cn http://www.morning.gxeqedd.cn.gov.cn.gxeqedd.cn http://www.morning.bwjws.cn.gov.cn.bwjws.cn http://www.morning.zrqs.cn.gov.cn.zrqs.cn http://www.morning.bwgrd.cn.gov.cn.bwgrd.cn http://www.morning.dskmq.cn.gov.cn.dskmq.cn http://www.morning.xrnh.cn.gov.cn.xrnh.cn http://www.morning.lqzhj.cn.gov.cn.lqzhj.cn http://www.morning.thjqk.cn.gov.cn.thjqk.cn