SpringSecurity + JWT 2024最新版 SpringSecurity角色权限控制 SpringSecurity6

前言

本文默认读者已了解相关知识,所以只介绍代码。
本文尽量使用官方提供的方法尽量简略的实现SpringSecurity+JWT,更多自定义功能需读者扩展。
项目环境:SpringBoot3、JDK21、Mysql8、SpringSecurity6、auth0 JWT


完整代码

pom.xml(引入项目所需依赖)

		<!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>

        <!--Json-->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.9</version>
        </dependency>

        <!--Spring Starter-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--JPA-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!-- MySQL -->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
        </dependency>

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

        <!-- auth0 JWT -->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.18.2</version>
        </dependency>

        <!--开发时用(自动应用程序重启,自动加载静态资源,禁用模板缓存,全局错误页面)-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

application.properties(配置数据库连接)

# Mysql数据库连接配置
spring.datasource.url=jdbc:mysql://localhost:3306/windows?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# Hibernate配置
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

JwtUtil.java(生成、校验、解析JWT)

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;

import jakarta.servlet.http.HttpServletRequest;

import java.util.*;

import org.springframework.util.StringUtils;

public class JwtUtil {
    private static final String jwtKey = "123456";
    private static final Integer expiredTimeInSeconds = 60;

    public static String generateToken(String username) {
        Algorithm algorithm = Algorithm.HMAC256(jwtKey);
        Date now = new Date();
        Date expiration = new Date(now.getTime() + expiredTimeInSeconds * 1000L);

        return JWT.create()
                .withClaim("username", username)
                .withExpiresAt(expiration)
                .withIssuedAt(now)
                .sign(algorithm);
    }

    public static Optional<Map<String, Claim>> getClaims(String token) {
        Algorithm algorithm = Algorithm.HMAC256(jwtKey);
        JWTVerifier verifier = JWT.require(algorithm).build();

        try {
            DecodedJWT decodedJWT = verifier.verify(token);
            return Optional.of(decodedJWT.getClaims());
        } catch (JWTVerificationException e) {
            return Optional.empty();
        }
    }

    public static boolean validateToken(String token) {
        Algorithm algorithm = Algorithm.HMAC256(jwtKey);
        JWTVerifier verifier = JWT.require(algorithm).build();

        try {
            verifier.verify(token);
            return true;
        } catch (JWTVerificationException e) {
            return false;
        }
    }

    public static String getTokenFromRequest(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7, bearerToken.length());
        }
        return null;
    }
}

JsonUtil.java(对象转JSON)

import com.google.gson.Gson;

public class JsonUtil {
    public static String ObjectToJson(Object object) {
        Gson gson = new Gson();
        return gson.toJson(object);
    }
}

User.java(用户实体)

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Data;

@Data
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;
    private String password;
    private String role;
}

UserRepository.java(用户数据接口)

import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.example.windows.windows.enity.User;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByUsername(String username);
}

UserService(实现UserDetailsService)

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import com.example.windows.windows.enity.User;
import com.example.windows.windows.repository.UserRepository;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import com.example.windows.windows.enity.User;
import com.example.windows.windows.repository.UserRepository;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

@Service
public class UserService implements UserDetailsService {
    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("User not found with username: " + username));

        List<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority(user.getRole()));

        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
                authorities);
    }

    public User register(String username,String password) {
        User user = new User();
        if (userRepository.findByUsername(username).isPresent()) {
            return null;
        }
        user.setUsername(username);
        user.setPassword(new BCryptPasswordEncoder().encode(password));
        user.setRole("user");
        return userRepository.save(user);
    }
}

UserController.java(测试权限)

import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;

@RestController
@RequestMapping("/api/user")
public class UserController {
    @GetMapping("/test")
    public String test() {
        return "test";
    }

    @GetMapping("/adminTest")
    public String adminTest() {
        return "adminTest";
    }

    @GetMapping("/userTest")
    public String userTest() {
        return "userTest";
    }
}

JwtAuthenticationFilter(验证JWT是否合法)

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.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import com.auth0.jwt.interfaces.Claim;
import com.example.windows.windows.service.UserService;
import com.example.windows.windows.utils.JwtUtil;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;

import java.io.IOException;
import java.util.Map;
import java.util.Optional;

@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    private UserService userService;

    public JwtAuthenticationFilter(UserService userService) {
        this.userService = userService;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        String jwt = JwtUtil.getTokenFromRequest(request);
        if (StringUtils.hasText(jwt) && JwtUtil.validateToken(jwt)) {
            Optional<Map<String, Claim>> claims = JwtUtil.getClaims(jwt);
            Claim usernameClaim = claims.get().get("username");
            String username = usernameClaim.asString();
            UserDetails userDetails = userService.loadUserByUsername(username);
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
                    userDetails,
                    null,
                    userDetails.getAuthorities());

            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        }
        filterChain.doFilter(request, response);
    }
}

SecurityConfig.java(SpringSecurity配置类)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.example.windows.windows.filter.JwtAuthenticationFilter;
import com.example.windows.windows.handle.JwtAccessDeniedHandler;
import com.example.windows.windows.handle.JwtAuthenticationEntryPoint;
import com.example.windows.windows.handle.LoginFailureHandler;
import com.example.windows.windows.handle.LoginSuccessHandler;
import com.example.windows.windows.service.UserService;

import lombok.RequiredArgsConstructor;

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
    private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
    private final JwtAccessDeniedHandler jwtAccessDeniedHandler;
    private final UserService userService;
    private final LoginFailureHandler loginFailureHandler;
    private final LoginSuccessHandler loginSuccessHandler;

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration)
            throws Exception {
        return configuration.getAuthenticationManager();
    }

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

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.csrf(csrf -> csrf.disable())
                .addFilterBefore(new JwtAuthenticationFilter(userService), UsernamePasswordAuthenticationFilter.class)
               	.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.NEVER))
                .formLogin(login -> login
                        .loginProcessingUrl("/api/user/login")
                        .usernameParameter("username")
                        .passwordParameter("password")
                        .successHandler(loginSuccessHandler)
                        .failureHandler(loginFailureHandler))
                .authorizeHttpRequests(authorize -> authorize
                        .requestMatchers("/api/user/userTest").hasAnyAuthority("user")
                        .requestMatchers("/api/user/adminTest").hasAnyAuthority("admin")
                        .anyRequest().authenticated())
                .exceptionHandling(exception -> exception
                        .accessDeniedHandler(jwtAccessDeniedHandler)
                        .authenticationEntryPoint(jwtAuthenticationEntryPoint));
        return http.build();
    }
}

Result.java(封装返回信息)

package com.example.windows.windows.enity;

import java.io.Serializable;
import lombok.Data;

@Data
public class Result implements Serializable {
    private int code;
    private String message;
    private Object data;

    public Result() {}

    public Result(int code, String message, Object data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }
}

JwtAccessDeniedHandler.java(处理请求路径无权限)

import java.io.IOException;
import java.nio.charset.StandardCharsets;

import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;

import com.example.windows.windows.enity.Result;
import com.example.windows.windows.utils.JsonUtil;

import jakarta.servlet.ServletException;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@Component
public class JwtAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
            AccessDeniedException e) throws IOException, ServletException {
        httpServletResponse.setContentType("application/json;charset=UTF-8");
        httpServletResponse.setStatus(HttpServletResponse.SC_OK);
        ServletOutputStream outputStream = httpServletResponse.getOutputStream();

        Result result = new Result(401, "权限不足", null);
        outputStream.write(JsonUtil.ObjectToJson(result).getBytes(StandardCharsets.UTF_8));
        outputStream.flush();
        outputStream.close();
    }
}

JwtAuthenticationEntryPoint.java(处理无效JWT/未认证用户)

import java.io.IOException;
import java.nio.charset.StandardCharsets;

import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import jakarta.servlet.ServletException;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import com.example.windows.windows.enity.Result;
import com.example.windows.windows.utils.JsonUtil;
import com.example.windows.windows.utils.JwtUtil;

@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
            AuthenticationException authenticationException) throws IOException, ServletException {
        httpServletResponse.setContentType("application/json;charset=UTF-8");
        httpServletResponse.setStatus(HttpServletResponse.SC_OK);
        ServletOutputStream outputStream = httpServletResponse.getOutputStream();
        String jwt = JwtUtil.getTokenFromRequest(httpServletRequest);
        Result result = new Result();
        if (StringUtils.hasText(jwt) && JwtUtil.validateToken(jwt)){
            result.setCode(401);
            result.setMessage("JWT无效");
        }
        else{
            result.setCode(401);
            result.setMessage("请先登录");
        }

        outputStream.write(JsonUtil.ObjectToJson(result).getBytes(StandardCharsets.UTF_8));
        outputStream.flush();
        outputStream.close();
    }
}

LoginFailureHandler.java(处理登录失败逻辑)

import java.io.IOException;
import java.nio.charset.StandardCharsets;

import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;

import com.example.windows.windows.enity.Result;
import com.example.windows.windows.service.UserService;
import com.example.windows.windows.utils.JsonUtil;
import com.example.windows.windows.utils.JwtUtil;

import jakarta.servlet.ServletException;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class LoginFailureHandler implements AuthenticationFailureHandler {
    private final UserService userService;
    Logger logger = LoggerFactory.getLogger(LoginFailureHandler.class);
    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
            AuthenticationException authenticationException) throws IOException, ServletException {
        httpServletResponse.setContentType("application/json;charset=UTF-8");
        httpServletResponse.setStatus(HttpServletResponse.SC_OK);
        ServletOutputStream outputStream = httpServletResponse.getOutputStream();
        String username = httpServletRequest.getParameter("username");
        String password = httpServletRequest.getParameter("password");
        Result result = new Result();
        if (userService.register(username,password) == null) {
            result.setCode(401);
            result.setMessage("用户名或密码错误");
        }
        else{
            String jwt = JwtUtil.generateToken(username);
            result.setCode(200);
            result.setMessage("注册成功");
            result.setData(jwt);
        }
        
        outputStream.write(JsonUtil.ObjectToJson(result).getBytes(StandardCharsets.UTF_8));
        outputStream.flush();
        outputStream.close();
    }
}

LoginSuccessHandler.java(处理登录成功逻辑)

import java.io.IOException;
import java.nio.charset.StandardCharsets;

import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import jakarta.servlet.ServletException;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import com.example.windows.windows.enity.Result;
import com.example.windows.windows.utils.JsonUtil;
import com.example.windows.windows.utils.JwtUtil;

@Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
            Authentication authentication) throws IOException, ServletException {
        httpServletResponse.setContentType("application/json;charset=UTF-8");
        httpServletResponse.setStatus(HttpServletResponse.SC_OK);
        ServletOutputStream outputStream = httpServletResponse.getOutputStream();

        String username = httpServletRequest.getParameter("username");
        String jwt = JwtUtil.generateToken(username);
        Result result = new Result(200, "登录成功", jwt);

        outputStream.write(JsonUtil.ObjectToJson(result).getBytes(StandardCharsets.UTF_8));
        outputStream.flush();
        outputStream.close();
    }
}

效果检验

以下均使用postman测试

1.测试用户注册功能

代码中设置了用户不存在自动注册的逻辑
user注册成功
在这里插入图片描述
admin注册成功
在这里插入图片描述
去数据库修改admin用户的权限用于测试
在这里插入图片描述

2.测试角色user功能

登录user用户
在这里插入图片描述
将返回的jwt(data中的字符串)放到Headers中的Authorization中,并添加前缀((Bearer )有个空格)。
有user权限
在这里插入图片描述
没有admin权限
在这里插入图片描述

3.测试角色admin功能

admin登录
在这里插入图片描述
有admin权限
在这里插入图片描述
没有user权限
在这里插入图片描述

4.测试超时处理

在这里插入图片描述

5.测试未登录用户

在这里插入图片描述

  • 9
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring Security是一个基于Spring的安全框架,它提供了一组可以在Spring应用程序中配置的安全服务。JWT(JSON Web Token)是一种用于在网络应用间传递信息的简洁的、URL安全的表述性声明规范。JWT通过在用户和服务器之间传递安全令牌来实现身份验证和授权。结合使用Spring SecurityJWT可以实现角色权限控制。 具体实现步骤如下: 1.添加Spring SecurityJWT的依赖。 2.创建一个实现UserDetailsService接口的类,用于从数据库中获取用户信息。 3.创建一个实现JwtTokenUtil接口的类,用于生成和解析JWT。 4.创建一个实现AuthenticationEntryPoint接口的类,用于处理未授权的请求。 5.创建一个实现AccessDeniedHandler接口的类,用于处理授权失败的请求。 6.创建一个继承WebSecurityConfigurerAdapter的类,用于配置Spring Security。 7.在配置类中添加一个JwtAuthenticationTokenFilter过滤器,用于验证JWT。 8.在需要进行权限控制的方法上添加@PreAuthorize注解,指定需要的角色权限。 示例代码如下: ```java // UserDetailsService实现类 @Service public class UserDetailsServiceImpl implements UserDetailsService { @Autowired private UserService userService; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = userService.getUserByUsername(username); if (user == null) { throw new UsernameNotFoundException("用户名不存在"); } return new JwtUserDetails(user); } } // JwtTokenUtil实现类 @Component public class JwtTokenUtilImpl implements JwtTokenUtil { private static final String CLAIM_KEY_USERNAME = "sub"; private static final String CLAIM_KEY_CREATED = "created"; @Value("${jwt.secret}") private String secret; @Value("${jwt.expiration}") private Long expiration; @Override 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); } @Override public String getUsernameFromToken(String token) { String username; try { Claims claims = getClaimsFromToken(token); username = claims.getSubject(); } catch (Exception e) { username = null; } return username; } @Override public boolean validateToken(String token, UserDetails userDetails) { JwtUserDetails user = (JwtUserDetails) userDetails; String username = getUsernameFromToken(token); return username.equals(user.getUsername()) && !isTokenExpired(token); } private Claims getClaimsFromToken(String token) { Claims claims; try { claims = Jwts.parser() .setSigningKey(secret) .parseClaimsJws(token) .getBody(); } catch (Exception e) { claims = null; } return claims; } private boolean isTokenExpired(String token) { Date expirationDate = getExpirationDateFromToken(token); return expirationDate.before(new Date()); } private Date getExpirationDateFromToken(String token) { Claims claims = getClaimsFromToken(token); return claims.getExpiration(); } private String generateToken(Map<String, Object> claims) { Date expirationDate = new Date(System.currentTimeMillis() + expiration * 1000); return Jwts.builder() .setClaims(claims) .setExpiration(expirationDate) .signWith(SignatureAlgorithm.HS512, secret) .compact(); } } // AuthenticationEntryPoint实现类 @Component public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException { response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "未授权的请求"); } } // AccessDeniedHandler实现类 @Component public class JwtAccessDeniedHandler implements AccessDeniedHandler { @Override public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException { response.sendError(HttpServletResponse.SC_FORBIDDEN, "权限不足"); } } // 配置类 @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Autowired private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; @Autowired private JwtAccessDeniedHandler jwtAccessDeniedHandler; @Autowired private JwtTokenFilter jwtTokenFilter; @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService) .passwordEncoder(passwordEncoder()); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/login").permitAll() .anyRequest().authenticated() .and() .exceptionHandling() .authenticationEntryPoint(jwtAuthenticationEntryPoint) .accessDeniedHandler(jwtAccessDeniedHandler) .and() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS); http.addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class); } } // JwtAuthenticationTokenFilter过滤器 @Component public class JwtTokenFilter extends OncePerRequestFilter { @Autowired private UserDetailsService userDetailsService; @Autowired private JwtTokenUtil jwtTokenUtil; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { String authHeader = request.getHeader("Authorization"); if (authHeader != null && authHeader.startsWith("Bearer ")) { String authToken = authHeader.substring(7); String username = jwtTokenUtil.getUsernameFromToken(authToken); if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { UserDetails userDetails = userDetailsService.loadUserByUsername(username); if (jwtTokenUtil.validateToken(authToken, userDetails)) { UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(authentication); } } } chain.doFilter(request, response); } } // 在需要进行权限控制的方法上添加@PreAuthorize注解 @PreAuthorize("hasAnyRole('ADMIN','USER')") public void someMethod() { // do something } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值