mall整合SpringSecurity及JWT实现认证授权实战

来分享一下“mall整合SpringSecurity及JWT实现认证授权实战”的完整攻略。

1. 环境准备

要完成该攻略,首先需要准备好以下环境:

  • JDK 1.8+
  • Maven 3.x
  • IntelliJ IDEA 2019.2+(或其他任意IDE)

2. 创建maven项目

使用maven创建一个空白的Spring Boot项目,并引入必要的依赖,包括Spring Boot、Spring Security和JWT等。

3. 配置Spring Security

创建一个继承WebSecurityConfigurerAdapter的配置类,重写configure()方法以进行身份验证和授权设置。其中包括:

  • 配置用户身份验证方式:可以通过数据库、自定义验证等方式进行用户验证。
  • 配置权限验证:可以通过@PreAuthorize@PostAuthorize注解进行方法级别的授权。

示例:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/public/**").permitAll() // 允许公开访问的url
                .anyRequest().authenticated() // 其余的URL需要身份验证
                .and()
            .formLogin()
                .loginPage("/login") // 登录页面URL
                .loginProcessingUrl("/doLogin") // 登录接口URL
                .usernameParameter("username") // 登录用户名参数
                .passwordParameter("password") // 登录密码参数
                .successHandler(new MyAuthenticationSuccessHandler()) // 登录成功的处理器
                .failureHandler(new MyAuthenticationFailureHandler()) // 登录失败的处理器
                .permitAll()
                .and()
            .logout()
                .logoutUrl("/logout") // 退出登录的接口URL
                .logoutSuccessUrl("/login") // 退出成功后跳转的URL
                .permitAll();

        http.csrf().disable(); // 禁用CSRF保护
    }

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

注:上述示例中,我们使用了BCryptPasswordEncoder加密方式对用户密码进行加密。

4. 配置JWT

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

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

接着,我们需要创建一个JWT工具类,实现JWT的生成和解析等功能。

示例:

@Component
public class JwtUtils {

    /**
     * 过期时间,单位:分钟
     */
    private static final long EXPIRATION = 30;

    /**
     * 秘钥
     */
    private static final String SECRET_KEY = "mall";

    /**
     * 创建JWT Token
     *
     * @param subject 用户信息
     * @return JWT Token
     */
    public String createToken(String subject) {
        Date now = new Date();
        Date expirationDate = new Date(now.getTime() + EXPIRATION * 60 * 1000);
        return Jwts.builder()
                .setSubject(subject)
                .setIssuedAt(now)
                .setExpiration(expirationDate)
                .signWith(SignatureAlgorithm.HS512, SECRET_KEY)
                .compact();
    }

    /**
     * 解析JWT Token,并返回其中的subject(用户信息)
     *
     * @param token JWT Token
     * @return 用户信息
     */
    public String parseToken(String token) {
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(SECRET_KEY)
                    .parseClaimsJws(token)
                    .getBody();
            return claims.getSubject();
        } catch (Exception e) {
            return null;
        }
    }
}

5. 添加JWT认证

为了使用JWT进行身份验证,我们需要修改WebSecurityConfig类以支持JWT。

示例:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private JwtUtils jwtUtils;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/public/**").permitAll() // 允许公开访问的url
                .anyRequest().authenticated() // 其余的URL需要身份验证
                .and()
            .formLogin()
                .loginPage("/login") // 登录页面URL
                .loginProcessingUrl("/doLogin") // 登录接口URL
                .usernameParameter("username") // 登录用户名参数
                .passwordParameter("password") // 登录密码参数
                .successHandler(new MyAuthenticationSuccessHandler()) // 登录成功的处理器
                .failureHandler(new MyAuthenticationFailureHandler()) // 登录失败的处理器
                .permitAll()
                .and()
            .logout()
                .logoutUrl("/logout") // 退出登录的接口URL
                .logoutSuccessUrl("/login") // 退出成功后跳转的URL
                .permitAll();

        http.csrf().disable(); // 禁用CSRF保护

        // 添加JWT认证
        http.addFilterBefore(new JwtAuthenticationFilter(jwtUtils), UsernamePasswordAuthenticationFilter.class);
    }

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

然后,我们需要创建一个JwtAuthenticationFilter,用于验证JWT,并将用户信息添加到spring security的上下文中。

示例:

public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private JwtUtils jwtUtils;

    public JwtAuthenticationFilter(JwtUtils jwtUtils) {
        this.jwtUtils = jwtUtils;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String authorization = request.getHeader("Authorization");
        if (authorization != null && authorization.startsWith("Bearer ")) {
            String jwt = authorization.substring(7);
            String subject = jwtUtils.parseToken(jwt);
            if (subject != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                UserDetails userDetails = userDetailsService.loadUserByUsername(subject);
                if (jwtUtils.validateToken(jwt, userDetails)) {
                    UsernamePasswordAuthenticationToken authenticationToken =
                            new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                    authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
                }
            }
        }
        filterChain.doFilter(request, response);
    }
}

6. 测试

现在我们可以进行测试了。我们可以编写一个测试接口,例如/api/test,来测试JWT认证是否生效。

示例:

@RestController
@RequestMapping("/api")
public class TestController {

    @GetMapping("/test")
    @PreAuthorize("hasRole('ADMIN')")
    public String test() {
        return "Hello, World!";
    }
}

其中,@PreAuthorize("hasRole('ADMIN')")表示只有具有ADMIN角色的用户才能访问该接口。

接下来,我们可以在Postman或其他工具中发送请求进行测试。请求头中需要携带如下信息:

Authorization:Bearer {JWT Token}

其中,JWT Token可以通过JwtUtils工具类生成。

如果授权成功,接口将返回“Hello, World!”消息。

这就是使用Spring Security和JWT实现认证授权的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:mall整合SpringSecurity及JWT实现认证授权实战 - Python技术站

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

相关文章

  • windows下的WAMP环境搭建图文教程(推荐)

    下面就是“windows下的WAMP环境搭建图文教程(推荐)”的完整攻略: 安装WAMP 首先,我们需要下载WAMP软件。可以在官网 https://www.wampserver.com/en/ 下载。 然后,运行下载的exe文件,按照提示一步步进行安装即可。安装过程中会出现一些选项,如安装路径和默认浏览器等,请根据自己的需求选择。 安装完成后,在系统托盘中…

    Java 2023年6月16日
    00
  • eclipse中jsp码提示不显示该怎么解决?

    解决eclipse中JSP代码提示不显示的问题,可以按照以下步骤进行: 步骤一:安装“JSP Editor”插件 首先需要确保已经安装了“JST Server Adapter”或类似的服务器适配器,接着在Eclipse Marketplace中搜索并安装“JSP Editor”插件。 步骤如下: 打开Eclipse,单击“Help”菜单; 在下拉菜单中选择“…

    Java 2023年6月15日
    00
  • 一篇文章带你了解如何正确使用java线程池

    一篇文章带你了解如何正确使用Java线程池 了解Java线程池的基本概念 什么是线程池? Java线程池是一种用来管理线程的机制,它可以在程序启动时预先创建一定数量的线程,然后缓存起来以供以后使用。当需要执行任务时,从线程池中获取一个线程来执行任务。执行完毕后,线程会自动归还给线程池,线程池可以复用这些线程,这样可以减少因线程创建与销毁所带来的开销。 为什么…

    Java 2023年5月18日
    00
  • java实现简单超市管理系统

    Java实现简单超市管理系统攻略 本文将介绍如何使用Java语言实现一个简单的超市管理系统,包括设计思路、功能需求、创建Java项目、数据库设计、代码实现等方面。本超市管理系统将实现包括用户登录、商品管理、仓库管理、销售管理等基本功能,从而满足超市日常管理需求。 设计思路 总体思路是基于Java Web实现一个简单的超市管理系统。首先,需要确定所需的基本功能…

    Java 2023年5月18日
    00
  • tk.mybatis扩展通用接口使用详解

    tk.mybatis扩展通用接口使用详解 什么是tk.mybatis? tk.mybatis是MyBatis的一个扩展插件,它进一步简化了MyBatis的使用。tk.mybatis对MyBatis进行了增强,提供了一套通用的Mapper接口,可以让我们写更少的代码来完成CRUD操作。同时tk.mybatis提供了一些实用的功能,例如自动填充创建时间和更新时间…

    Java 2023年5月20日
    00
  • Linux下PHP+MYSQL+APACHE配置过程 (摘)第1/2页

    针对“Linux下PHP+MYSQL+APACHE配置过程”这一话题,我会提供一个完整的攻略,并在过程中举两个实例说明,内容如下: Linux下PHP+MYSQL+APACHE配置过程 安装apache 在Linux系统下,Apache是一款非常流行的Web服务器软件,可以通过以下步骤进行安装: 更新包管理器 sudo apt update 安装apache…

    Java 2023年6月2日
    00
  • Spring常用配置及解析类说明

    下面是“Spring常用配置及解析类说明”的详细攻略。 1. Spring常用配置 1.1 XML配置 Spring框架最初是以XML配置为主的,XML配置的方式包括声明bean和对bean进行依赖注入两个方面。 1.1.1 声明bean 在XML配置文件中,声明bean的方式如下: <bean id="beanId" class=…

    Java 2023年5月19日
    00
  • Java编译器用maven打war包出错解决办法

    下面是详细讲解“Java编译器用maven打war包出错解决办法”的完整攻略。 问题描述 当使用Java编译器用maven打war包时,有时会遇到错误,例如“Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile)…

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