spring boot集成spring security(jwt+redis有完整源码)

一、Spring Security官方解释

Spring Security是一个强大的和高度可定制的身份验证和访问控制框架。它是保证基于spring的应用程序安全的实际标准。Spring Security是一个框架,着重于为Java应用程序提供身份验证和授权。春天像所有项目,Spring Security的真正力量是很容易找到的它可以扩展以满足定制需求。

本项目使用jwt当作token,使用redis存储token,登录信息不依赖于单个项目,集中存储到redis内存型数据库中。

二、spring boot集成步骤(完整项目地址:https://gitee.com/fds520/spring-security-demo

1. 项目结构

在这里插入图片描述

2.核心代码
主配置类SpringSecurityConfig
package com.fds.system.config;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * spring security 主配置类
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;

    @Autowired
    private SecurityProperties securityProperties;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 禁用 csrf 拦截
        http.csrf().disable()
                .sessionManagement()
                // 关闭session管理,使用token机制处理
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                // 未登录返回 JSON 格式的数据
                .httpBasic().authenticationEntryPoint((httpServletRequest, httpServletResponse, e) -> {
                    httpServletRequest.setCharacterEncoding("utf-8");
                    httpServletResponse.setHeader("Content-type", "application/json;charset=UTF-8");
                    httpServletResponse.getWriter().write(JSON.toJSONString("未登录"));
                })
                .and()
                // 无权访问 JSON 格式的数据
                .exceptionHandling().accessDeniedHandler((httpServletRequest, httpServletResponse, e) -> {
                    httpServletResponse.setCharacterEncoding("utf-8");
                    httpServletResponse.setHeader("Content-type", "application/json;charset=UTF-8");
                    httpServletResponse.getWriter().write(JSON.toJSONString("没有权限"));
                })
                .and()
                .authorizeRequests()
                // 对option不校验
                .antMatchers(HttpMethod.OPTIONS).permitAll()
                // 设置不校验白名单
                .antMatchers(securityProperties.getIgnoreUrl()).permitAll()
                .anyRequest().authenticated()
                .and()
                // 添加自定义请求jwt过滤器
                .addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
    }

    @Override
    public void configure(WebSecurity web) {
        // 设置拦截忽略文件夹,可以对静态资源放行
        web.ignoring().antMatchers("/images/**");
    }
}

登录service
    /**
     * 获取数据库用户
     *
     * @param username 用户名
     * @return
     * @throws UsernameNotFoundException
     */
    public String login(String username, String password) {
        // 模拟从数据库 获取登录用户
        LoginUser loginUser = new LoginUser("fds", "123");
        loginUser.setId(123L);
        loginUser.setType("people");
        Set authoritiesSet = new HashSet();
        // 模拟从数据库中获取用户权限
        authoritiesSet.add("test:add");
        authoritiesSet.add("test:list");
        authoritiesSet.add("ddd:list");
        loginUser.setCustomAuthorities(authoritiesSet);
        String token = JwtTokenUtil.generateToken(loginUser);
        redisUtil.set(token, JSONObject.toJSONString(loginUser), securityProperties.getExpirationMilliSeconds());
        return token;
    }
token过滤器
package com.fds.system.config;

import com.alibaba.fastjson.JSONObject;
import com.fds.system.model.LoginUser;
import com.fds.system.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * @author: fds
 * @description: jwt-token过滤器
 */
@Component
@Slf4j
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private SecurityProperties securityProperties;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String authToken = request.getHeader("Authorization");
        response.setCharacterEncoding("utf-8");
        if (StringUtils.isEmpty(authToken)) {
            // 用户未登录
            filterChain.doFilter(request, response);
            return;
        }
        // 获取redis中的token信息
        if (!redisUtil.hasKey(authToken)) {
            // 用户未登录
            filterChain.doFilter(request, response);
            return;
        }

        Object data = redisUtil.get(authToken);
        if (null == data) {
            // 用户未登录
            filterChain.doFilter(request, response);
            return;
        }

        // 获取缓存中的信息(根据自己的业务进行拓展)
        LoginUser loginUser = JSONObject.parseObject(data.toString(), LoginUser.class);
        // 设置权限
        loginUser.setSystemAuthorities();
        // 从tokenInfo中取出用户信息
        // 更新token过期时间
        redisUtil.setKeyExpire(authToken, securityProperties.getExpirationMilliSeconds());
        // 将信息交给security
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
        authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        filterChain.doFilter(request, response);
    }
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot 是一个用于构建微服务的开框架,它能够快速搭建项目并且提供了许多便捷的功能和特性。Spring Security 是一个用于处理认证和授权的框架,可以保护我们的应用程序免受恶意攻击。JWT(JSON Web Token)是一种用于身份验证的开放标准,可以被用于安全地传输信息。Spring MVC 是一个用于构建 Web 应用程序的框架,它能够处理 HTTP 请求和响应。MyBatis 是一个用于操作数据库的框架,可以简化数据库操作和提高效率。Redis 是一种高性能的键值存储系统,可以用于缓存与数据存储。 基于这些技术,可以搭建一个商城项目。Spring Boot 可以用于构建商城项目的后端服务,Spring Security 可以确保用户信息的安全性,JWT 可以用于用户的身份验证,Spring MVC 可以处理前端请求,MyBatis 可以操作数据库,Redis 可以用于缓存用户信息和商品信息。 商城项目的后端可以使用 Spring BootSpring Security 来搭建,通过 JWT 来处理用户的身份验证和授权。数据库操作可以使用 MyBatis 来简化与提高效率,同时可以利用 Redis 来缓存一些常用的数据和信息,提升系统的性能。前端请求则可以通过 Spring MVC 来处理,实现商城项目的整体功能。 综上所述,借助于 Spring BootSpring SecurityJWTSpring MVC、MyBatis 和 Redis 这些技术,可以构建出一个高性能、安全可靠的商城项目,为用户提供良好的购物体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值