代码音符

spring reactive + spring security

创建时间: 9-28 17:34

浏览: 5

1. Security配置类(SecurityConfig.java

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http, JwtFilter jwtFilter) {
        http
            .csrf().disable()
            .authorizeExchange()
                .anyExchange().authenticated()
                .and()
            .addFilterAt(jwtFilter, SecurityWebFiltersOrder.AUTHENTICATION);
        return http.build();
    }

    @Bean
    public ReactiveAuthenticationManager authenticationManager(UserDetailsService userDetailsService) {
        return new ReactiveAuthenticationManagerAdapter(userDetailsService);
    }
}

2. JWT过滤器(JwtFilter.java

@Component
public class JwtFilter implements WebFilter {
    private final JwtUtil jwtUtil;

    public JwtFilter(JwtUtil jwtUtil) {
        this.jwtUtil = jwtUtil;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        String authHeader = exchange.getRequest().getHeaders().getFirst("Authorization");
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            String token = authHeader.substring(7);
            if (jwtUtil.validateToken(token)) {
                // 检查Redis黑名单:若token存在则返回403
                return chain.filter(exchange);
            }
        }
        return Mono.error(new UnauthorizedException("Invalid token"));
    }
}

3. JWT工具类(JwtUtil.java

@Component
public class JwtUtil {
    private final String secretKey = "your-secret-key";
    private final long expirationTime = 86400000; // 24小时

    public String generateToken(String username) {
        // 生成JWT token(实际实现需使用JJWT等库)
        return "JWT_TOKEN_STRING";
    }

    public boolean validateToken(String token) {
        // 验证token签名和过期时间(实际实现需解析JWT)
        return true;
    }
}

4. 服务层代码(AuthService.java

@Service
public class AuthService {
    private final JwtUtil jwtUtil;

    public AuthService(JwtUtil jwtUtil) {
        this.jwtUtil = jwtUtil;
    }

    public String login(String username, String password) {
        // 验证用户名密码(由UserDetailsService处理)
        // 生成JWT token
        return jwtUtil.generateToken(username);
    }

    public void logout(String token) {
        // 将token存入Redis黑名单,设置过期时间为token剩余有效期
        // 示例:redisTemplate.opsForValue().set(token, "blacklisted", remainingTime, TimeUnit.MILLISECONDS);
    }
}

5. 控制器接口(AuthController.java

@RestController
@RequestMapping("/auth")
public class AuthController {
    private final AuthService authService;

    public AuthController(AuthService authService) {
        this.authService = authService;
    }

    @PostMapping("/login")
    public String login(@RequestBody Map<String, String> request) {
        String username = request.get("username");
        String password = request.get("password");
        return authService.login(username, password);
    }

    @PostMapping("/logout")
    public void logout(@RequestHeader("Authorization") String authHeader) {
        String token = authHeader.substring(7); // 移除"Bearer "前缀
        authService.logout(token);
    }

    @GetMapping("/isLogin")
    public ResponseEntity<?> isLogin() {
        return ResponseEntity.ok().build(); // 有有效token时返回200,否则由Security自动返回403
    }
}

创建时间: 9-28 17:34

浏览: 5

*本文遵循 CC BY-NC-SA 许可协议。转载请注明出处!