当前位置:   article > 正文

Spring Security 超详细整合 JWT_spring security jwt详细教程

spring security jwt详细教程

Spring Security是一个功能强大并且高度可定制的Java安全框架,用于保护基于Spring的应用程序。JWT(JSON Web Tokens)是一种用于在网络应用环境间传递声明的一种紧凑的、URL安全的方式。JWT可以被用来认证和信息交换。将Spring Security与JWT整合可以为应用程序提供一个安全且高效的认证机制。

以下是Spring Security与JWT整合的超详细步骤:

### 1. 环境准备
确保你的开发环境中已经包含了Spring Boot和Spring Security的依赖。

```xml
<!-- pom.xml中添加Spring Security和JWT的依赖 -->
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>你的JWT库版本</version>
    </dependency>
</dependencies>
```

### 2. 配置Spring Security
创建一个配置类来定义Spring Security的安全性策略。

```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;

    @Autowired
    private JwtAccessDeniedHandler jwtAccessDeniedHandler;

    @Autowired
    private CustomTokenProvider tokenProvider;

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
            .csrf().disable()
            .authorizeRequests()
            .antMatchers("/api/public/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .exceptionHandling()
            .authenticationEntryPoint(jwtAuthenticationEntryPoint)
            .accessDeniedHandler(jwtAccessDeniedHandler);
        httpSecurity
            .addFilterBefore(jwtRequestFilter(), FilterOrder.AUTHENTICATION);
    }

    @Bean
    public Filter jwtRequestFilter() {
        return new JwtRequestFilter(tokenProvider, authenticationManager());
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    // 其他Bean定义...
}
```

### 3. JWT认证过滤器
创建JWT请求过滤器,用于拦截请求并验证JWT。

```java
public class JwtRequestFilter extends OncePerRequestFilter {

    private final CustomTokenProvider tokenProvider;
    private final AuthenticationManager authenticationManager;

    public JwtRequestFilter(CustomTokenProvider tokenProvider, AuthenticationManager authenticationManager) {
        this.tokenProvider = tokenProvider;
        this.authenticationManager = authenticationManager;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String jwt = getJwtFromRequest(request);
        if (jwt != null && tokenProvider.validateToken(jwt)) {
            Authentication authentication = authenticationManager.authenticate(
                new JwtAuthenticationToken(jwt)
            );
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        filterChain.doFilter(request, response);
    }

    private String getJwtFromRequest(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }
}
```

### 4. JWT令牌提供者
创建一个服务来提供JWT令牌。

```java
@Service
public class CustomTokenProvider {

    public String generateToken(Authentication authentication) {
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        // 构建JWT的payload
        String token = Jwts.builder()
                .setSubject(userDetails.getUsername())
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60)) // 1小时后过期
                .signWith(SignatureAlgorithm.HS512, "your-secret-key").compact();
        return token;
    }

    public boolean validateToken(String token) {
        try {
            Jwts.parser().setSigningKey("your-secret-key").parseClaimsJws(token);
            return true;
        } catch (JwtException | IllegalArgumentException e) {
            return false;
        }
    }

    // 其他方法...
}
```

### 5. 用户详情服务
实现`UserDetailsService`接口,用于从数据库获取用户信息。

```java
@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("User not found with username: " + username);
        }
        return new org.springframework.security.core.userdetails.User(
                user.getUsername(),
                user.getPassword(),
                getAuthorities(user)
        );
    }

    private Collection<? extends GrantedAuthority> getAuthorities(User user) {
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        // 根据用户角色添加权限...
        return authorities;
    }
}
```

### 6. 异常处理
创建自定义异常处理类,用于处理安全相关的异常。

```java
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
    }
}
```

### 7. 测试
编写单元测试和集成测试来验证安全性策略。

### 8. 部署
将应用程序部署到服务器或云环境。

整合Spring Security和JWT涉及到许多细节,上述步骤提供了一个大致的框架。在实际开发中,你可能需要根据具体需求调整配置和实现。
 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/983748
推荐阅读
相关标签
  

闽ICP备14008679号