Java中的授权与认证:完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Java中的授权与认证:核心概念与工具



认证和授权是任何Web应用程序安全的两大基石。在Java生态系统中,有许多成熟的库和框架可用于处理这些任务。本文将详细解析关键工具、它们的特点,并提供实用的代码示例。



1. 基本概念

在介绍工具之前,明确区分这两个术语非常重要:

  • 认证 — 验证用户身份(您是谁?)。通常通过登录名/密码、令牌或生物识别来完成。
  • 授权 — 验证访问权限(您被允许做什么?)。决定用户是否可以执行特定操作。


2. Spring Security — 事实标准

Spring Security 是Java应用程序中最流行的安全框架。它为认证和授权提供了全面的解决方案。



2.1. 基本认证配置

要引入Spring Security,请在 pom.xml 中添加依赖:

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-security</artifactId></dependency>


使用内存认证的最小配置:

import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.core.userdetails.User;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.provisioning.InMemoryUserDetailsManager;import org.springframework.security.web.SecurityFilterChain;

@Configurationpublic class SecurityConfig {

@Bean public InMemoryUserDetailsManager userDetailsManager() { UserDetails user = User.withDefaultPasswordEncoder() .username("user") .password("password") .roles("USER") .build(); return new InMemoryUserDetailsManager(user); }

@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(authz -> authz .requestMatchers("/admin/**").hasRole("ADMIN") .requestMatchers("/user/**").hasRole("USER") .anyRequest().authenticated() ) .formLogin(login -> login.defaultSuccessUrl("/home")) .httpBasic(); return http.build(); }}


3. JWT(JSON Web令牌)用于无状态认证

JWT允许实现无服务器端状态的认证。令牌包含所有必要的用户信息,并使用密钥进行签名。



3.1. 使用 jjwt 库生成JWT

添加依赖:

<dependency>    <groupId>io.jsonwebtoken</groupId>    <artifactId>jjwt-api</artifactId>    <version>0.12.5</version></dependency>


创建和验证令牌的示例:

import io.jsonwebtoken.Jwts;import io.jsonwebtoken.SignatureAlgorithm;import io.jsonwebtoken.security.Keys;import javax.crypto.SecretKey;import java.util.Date;

public class JwtUtil {

private static final SecretKey SECRET_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256); private static final long EXPIRATION_TIME = 3600000; // 1小时

public static String generateToken(String username) { return Jwts.builder() .setSubject(username) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTi

推荐