SpringBoot结合JWT登录权限控制的实现

下面就来详细讲解“SpringBoot结合JWT登录权限控制的实现”的攻略。

第一步:添加Maven依赖

pom.xml文件中添加以下Maven依赖:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

第二步:配置JWT工具类

创建一个JWT工具类,用于生成和解析JWT Token,例如:

@Component
public class JwtUtils {

    /**
     * JWT加密密钥
     */
    private static final String SECRET_KEY = "123456";

    /**
     * 过期时间,单位毫秒
     */
    private static final long EXPIRATION_TIME = 86400000;

    /**
     * 生成JWT Token
     *
     * @param id        用户ID
     * @param username  用户名
     * @param authorities 用户角色
     * @return JWT Token
     */
    public String generateToken(Long id, String username, List<String> authorities) {
        return Jwts.builder()
                .setSubject(username)
                .claim("id", id)
                .claim("authorities", authorities)
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }

    /**
     * 解析JWT Token
     *
     * @param token JWT Token
     * @return
     * @throws JwtException
     */
    public Claims parseToken(String token) throws JwtException {
        return Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody();
    }
}

第三步:实现登录功能

UserController中实现登录API接口,校验登录信息,若登录成功生成JWT Token并返回给客户端,例如:

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private JwtUtils jwtUtils;

    /**
     * 用户登录API接口
     */
    @PostMapping("/login")
    public Result login(String username, String password) {
        // 校验用户名和密码是否正确
        if ("admin".equals(username) && "123456".equals(password)) {
            // 登录成功,生成JWT Token
            List<String> authorities = new ArrayList<>();
            authorities.add("ADMIN");
            String token = jwtUtils.generateToken(1L, username, authorities);
            // 返回JWT Token
            return Result.success(token, "登录成功");
        } else {
            // 登录失败
            return Result.failure("用户名或密码错误");
        }
    }
}

第四步:实现权限控制

WebSecurityConfig中实现权限控制逻辑,先排除登录接口路径,将其他路径都设置为需要进行认证,例如:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthenticationFilter jwtAuthenticationFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 排除登录接口路径
        http.authorizeRequests().antMatchers("/user/login").permitAll()
            // 其他路径都需要进行认证
            .anyRequest().authenticated()
            .and().csrf().disable()
            .addFilterAt(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
    }

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

然后实现一个JwtAuthenticationFilter类,用于从JWT Token中获取用户信息并进行权限校验,例如:

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private JwtUtils jwtUtils;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        String header = request.getHeader("Authorization");
        if (StringUtils.isNotEmpty(header) && header.startsWith("Bearer ")) {
            String token = header.substring(7);
            try {
                Claims claims = jwtUtils.parseToken(token);
                String username = claims.getSubject();
                Long id = Long.valueOf(claims.get("id").toString());
                List<String> authorities = (List<String>) claims.get("authorities");
                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(id, username, authorities.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList()));
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            } catch (JwtException e) {
                throw new JwtAuthenticationException(e.getMessage());
            }
        }
        chain.doFilter(request, response);
    }
}

JwtAuthenticationFilter中,首先从Authorization请求头中获取JWT Token,然后解析出用户信息和角色信息,最后将用户信息封装成UsernamePasswordAuthenticationToken对象并设置到SecurityContextHolder中。

示例一:调用登录接口获取Token

通过调用登录接口,获取JWT Token,例如:

curl --location --request POST 'http://localhost:8080/user/login' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'username=admin' \
--data-urlencode 'password=123456'

返回示例:

{
    "code": 200,
    "message": "登录成功",
    "data": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImlkIjoxLCJhdXRob3JpdGllcyI6WyJBRE1JTiJdLCJleHAiOjE2MzE2MjU1MzF9.eD6m3uowKnl04go5xK2tYZTjZrmGHj-qK8vFv7BjOoY"
}

示例二:调用需要身份认证的接口

通过携带上文获得的JWT Token,访问需要身份认证的API接口,例如:

curl --location --request GET 'http://localhost:8080/user/info' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImlkIjoxLCJhdXRob3JpdGllcyI6WyJBRE1JTiJdLCJleHAiOjE2MzE2MjU1MzF9.eD6m3uowKnl04go5xK2tYZTjZrmGHj-qK8vFv7BjOoY'

这时候,如果JWT Token有效,接口将会返回用户信息。

以上就是“SpringBoot结合JWT登录权限控制的实现”的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot结合JWT登录权限控制的实现 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • Java Web请求与响应实例详解

    Java Web请求与响应实例详解 概览 Java Web中的Http请求和响应机制是非常重要的一个部分,它允许Web应用程序从客户端浏览器接收请求,并向客户端浏览器发送响应。 在本文中,我们将会对Java Web请求与响应进行详细讲解,首先介绍HttpServletRequest对象和HttpServletResponse对象,然后我们将通过两条完整的示例…

    Java 2023年5月20日
    00
  • SpringBoot2.7 WebSecurityConfigurerAdapter类过期配置

    下面就为您详细讲解SpringBoot 2.7版本中WebSecurityConfigurerAdapter类过期配置的完整攻略。 1. WebSecurityConfigurerAdapter类过期原因 在SpringBoot2.7版本中,WebSecurityConfigurerAdapter类的configure(HttpSecurity http)方…

    Java 2023年6月3日
    00
  • Ajax+Servlet+jsp显示搜索效果

    如果想要实现“Ajax+Servlet+jsp显示搜索效果”,我们需要完成以下步骤: 前端页面设计 首先,我们需要在前端设计一个搜索框和搜索结果展示区域。搜索框用于输入查询关键词,搜索结果展示区域用于显示查询到的结果。如下示例代码: <form> <input type="text" id="searchInp…

    Java 2023年6月15日
    00
  • eclipse中自动生成构造函数的两种方法

    当我们在使用Eclipse编写Java代码时,为了方便对象的初始化,我们经常需要对类生成构造函数。下面我将为您介绍两种在Eclipse中自动生成构造函数的方法。 方法一:使用快捷键自动生成构造函数 打开Eclipse并进入Java文件的编辑窗口。 将光标定位在类的声明语句中(class后)。 按下Ctrl + Shift + O键,自动导入所有需要的impo…

    Java 2023年5月26日
    00
  • 一文详解Java线程的6种状态与生命周期

    一文详解Java线程的6种状态与生命周期 线程生命周期 Java线程的生命周期可以分为6种不同的状态:1. New(新建): 当线程对象被创建时,它处于新建状态,但还没有开始运行。2. Runnable(可运行): 当调用start()方法时,线程进入可运行状态,等待被线程调度器分派时间片得以运行。3. Blocked(阻塞): 线程被阻塞于某一个等待状态,…

    Java 2023年5月19日
    00
  • SpringMVC五种类型参数传递及json传递参数

    Spring MVC是一种常用的Web框架,它提供了多种参数传递方式,包括基本类型、对象、集合、数组和JSON等。本文将详细讲解Spring MVC五种类型参数传递及JSON传递参数,并提供两个示例说明。 五种类型参数传递 1. 基本类型参数传递 基本类型参数传递是指将基本类型的值作为请求参数传递给Controller方法。在Spring MVC中,我们可以…

    Java 2023年5月18日
    00
  • jsp session.setAttribute()和session.getAttribute()用法案例详解

    下面是“jsp session.setAttribute()和session.getAttribute()用法案例详解”的完整攻略。 什么是Session? Session是指浏览器和服务器之间维护的一个会话状态,用于保存用户信息、用户访问状态等。在JSP中我们可以使用session对象来操作session。 session.setAttribute() s…

    Java 2023年6月15日
    00
  • 使用Spring源码报错java:找不到类 InstrumentationSavingAgent的问题

    针对“使用Spring源码报错java:找不到类 InstrumentationSavingAgent的问题”,我们可以采取以下步骤进行排查和解决。 1. 确定报错原因 在编译或运行代码过程中,如果出现了类找不到的问题,有可能是因为该类被成功编译但在运行时无法被找到。针对这种情况,我们需要先明确报错原因。 通过查看报错提示信息,判断问题是否出在Spring源…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部