信息发布→ 登录 注册 退出

Spring Security前后分离校验token的实现方法

发布时间:2026-01-11

点击量:
目录
  • 前言
  • token配置
    • 引入JWT依赖文件
    • 配置token管理器类
  • security 配置
    • 配置未登录处理类
    • 配置无权限处理类
    • 配置登出操作处理类
    • 配置token认证过滤器
    • 配置token权限校验过滤器
    • 自定义加密类
    • 配置UserDetailService
    • 配置数据库User对象映射类
    • 配置UserDetailService使用的SecurityUser类
    • 配置mybatis-plus
    • 配置security配置类
    • 配置几个测试接口
    • Md5加密工具类
  • 测试
    • 首先测试登录
    • 测试存在权限的接口
    • 测试不存在权限的接口
    • 测试登出
    • 测试不需要权限的接口
  • 数据库sql脚本
    • 代码下载

      前言

      之前采取项目中嵌套html页面,实现基本的登录校验权限校验登出操作记住我等功能试下。

      但是,现在的开发基本都是前后分离样式,后端并不需要配置登录页的操作。

      如何才能做到前后分离,同时也能支持登录token校验呢,本篇博客详细说明。

      token配置

      本次token生成采取jwt的方式。

      引入JWT依赖文件

      <dependency>
        <groupId>com.auth0</groupId>
          <artifactId>java-jwt</artifactId>
          <version>3.10.3</version>
      </dependency>
      

      配置token管理器类

      自定一个Token生成和从token中解析用户名的一个类,并交给Spring管理。

      package security.config;
      
      import com.auth0.jwt.JWT;
      import com.auth0.jwt.JWTVerifier;
      import com.auth0.jwt.algorithms.Algorithm;
      import com.auth0.jwt.interfaces.Claim;
      import com.auth0.jwt.interfaces.DecodedJWT;
      import org.springframework.stereotype.Component;
      import java.util.Calendar;
      import java.util.HashMap;
      @Component
      public class TokenJwtManager {
          // 设置token时间
          private int tokenEcpiration = 24*60*60*1000; // 毫秒   24h
          // 编码密钥
          private String tokenSignKey = "123456";
          // 1、根据用户名生成token
          public String createToken(String userName){
              Calendar calendar = Calendar.getInstance();
              calendar.add(Calendar.SECOND, tokenEcpiration);
              String userName1 = JWT.create()
                      .withHeader(new HashMap<>())
                      .withClaim("userName", userName)
                      .withExpiresAt(calendar.getTime()) // 过期时间
                      .sign(Algorithm.HMAC256(tokenSignKey));// 签名
              return userName1;
          }
          // 2、根据token得到用户名信息
          public String getUserName(String token){
              JWTVerifier build = JWT.require(Algorithm.HMAC256(tokenSignKey)).build();
              DecodedJWT verify = build.verify(token);
              Claim userName = verify.getClaim("userName");
              return userName.asString();
          public static void main(String[] args) {
              String ss = new TokenJwtManager().createToken("1111111");
              System.out.println(ss);
              System.out.println(new TokenJwtManager().getUserName(ss));
      }

      security 配置

      配置未登录处理类

      package security.config.handler;
      
      import lombok.extern.slf4j.Slf4j;
      import org.springframework.security.core.AuthenticationException;
      import org.springframework.security.web.AuthenticationEntryPoint;
      import org.springframework.stereotype.Component;
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      import java.io.PrintWriter;
      import java.util.HashMap;
      import java.util.Map;
      /**
       * 未登录
       */
      @Component
      @Slf4j
      public class MyUnAuthEntryPoint implements AuthenticationEntryPoint {
          @Override
          public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
              log.info("======= commence ===");
              // 返回请求端
              Map<String,Object> resultMap = new HashMap<>();
              // 保存数据
              resultMap.put("code","10000");
              resultMap.put("msg","当前账户未登录");
              resultMap.put("data",new HashMap<>());
              // 设置返回消息类型
              httpServletResponse.setHeader("Content-type", "text/html;charset=UTF-8");
              httpServletResponse.setCharacterEncoding("utf-8");
              httpServletResponse.setContentType("application/json;charset=UTF-8");
              // 返回给请求端
              PrintWriter writer  = httpServletResponse.getWriter();
              writer.write(resultMap.toString());
              writer.close();
          }
      }

      配置无权限处理类

      package security.config.handler;
      
      import org.springframework.security.access.AccessDeniedException;
      import org.springframework.security.web.access.AccessDeniedHandler;
      import org.springframework.stereotype.Component;
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      import java.io.PrintWriter;
      import java.util.HashMap;
      import java.util.Map;
      /**
       * 无权访问配置(前后分离)
       */
      @Component  // 交给spring管理
      public class MyAccessDeniedHandler implements AccessDeniedHandler {
          @Override
          public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
              Map<String,Object> resultMap = new HashMap<>();
              // 保存数据
              resultMap.put("code","403");
              resultMap.put("msg","无权访问");
              resultMap.put("data",null);
              // 设置返回消息类型
              httpServletResponse.setHeader("Content-type", "text/html;charset=UTF-8");
              httpServletResponse.setCharacterEncoding("utf-8");
              httpServletResponse.setContentType("application/json;charset=UTF-8");
              // 返回给请求端
              PrintWriter writer = httpServletResponse.getWriter();
              writer.write(resultMap.toString());
              writer.flush();
              writer.close();
          }
      }

      配置登出操作处理类

      package security.config.handler;
      
      import lombok.extern.slf4j.Slf4j;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.security.core.Authentication;
      import org.springframework.security.web.authentication.logout.LogoutHandler;
      import org.springframework.stereotype.Component;
      import security.config.TokenJwtManager;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      import java.io.PrintWriter;
      import java.util.HashMap;
      import java.util.Map;
      /**
       * 登出
       */
      @Component
      @Slf4j
      public class MyLogoutHandler implements LogoutHandler {
          @Autowired
          private TokenJwtManager tokenJwtManager;
      //    public MyLogoutHandler(TokenJwtManager tokenJwtManager) {
      //        this.tokenJwtManager = tokenJwtManager;
      //    }
          @Override
          public void logout(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) {
              // 1、从header中获取token
              String token = httpServletRequest.getHeader("token");
              log.info("token信息为  {}",token);
              String userName = tokenJwtManager.getUserName(token);
              log.info("从token获取userName信息为  {}",token);
              // redis 移除登录信息等逻辑
              // xxxxx
              // 2、返回请求端
              Map<String,Object> resultMap = new HashMap<>();
              // 保存数据
              resultMap.put("code","200");
              resultMap.put("msg",userName+"登录成功");
              resultMap.put("data",new HashMap<>());
              // 设置返回消息类型
              httpServletResponse.setHeader("Content-type", "text/html;charset=UTF-8");
              httpServletResponse.setCharacterEncoding("utf-8");
              httpServletResponse.setContentType("application/json;charset=UTF-8");
              // 返回给请求端
              PrintWriter writer = null;
              try {
                  writer = httpServletResponse.getWriter();
                  writer.write(resultMap.toString());
                  writer.flush();
                  writer.close();
              } catch (IOException e) {
                 e.printStackTrace();
              }
          }
      }

      配置token认证过滤器

      package security.filter;
      
      import com.fasterxml.jackson.databind.ObjectMapper;
      import lombok.extern.slf4j.Slf4j;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.security.authentication.AuthenticationManager;
      import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
      import org.springframework.security.core.Authentication;
      import org.springframework.security.core.AuthenticationException;
      import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
      import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
      import org.springframework.stereotype.Component;
      import security.config.TokenJwtManager;
      import security.vo.SecurityUser;
      import security.vo.User;
      import javax.servlet.FilterChain;
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      import java.io.PrintWriter;
      import java.util.ArrayList;
      import java.util.HashMap;
      import java.util.Map;
      // 这里交给spring管理会报错
      @Slf4j
      public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {
          private TokenJwtManager tokenJwtManager;
          private AuthenticationManager authenticationManager;
          public TokenLoginFilter(TokenJwtManager tokenJwtManager, AuthenticationManager authenticationManager) {
              this.tokenJwtManager = tokenJwtManager;
              this.authenticationManager = authenticationManager;
              this.setPostOnly(false); // 关闭登录只允许 post
              // 设置登陆路径,并且post请求
              this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/user/login","POST"));
          }
          // 1、获取登录页传递来的账户和密码信息
          @Override
          public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response){
              log.info("==== attemptAuthentication  ======");
              String userName = request.getParameter("userName");
              String pwd = request.getParameter("passWord");
              log.info("userName:{},pwd:{}",userName,pwd);
              return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(userName,
                      pwd,new ArrayList<>()));
          // 2、认证成功调用
          @Autowired
          protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult)
                  throws IOException, ServletException {
              log.info("==== successfulAuthentication  ======");
              // 认证成功之后,获取认证后的用户基本信息
              SecurityUser securityUser = (SecurityUser) authResult.getPrincipal();
              // 根据用户名生成对应的token
              String token = tokenJwtManager.createToken(securityUser.getUsername());
              // token信息存于redis、数据库、缓存等
              // 返回成功
              Map<String,Object> resultMap = new HashMap<>();
              // 保存数据
              resultMap.put("code","200");
              resultMap.put("msg","登录成功");
              resultMap.put("data",token);
              // 设置返回消息类型
              response.setHeader("Content-type", "text/html;charset=UTF-8");
              response.setCharacterEncoding("utf-8");
              response.setContentType("application/json;charset=UTF-8");
              // 返回给请求端
              PrintWriter writer = response.getWriter();
              writer.write(resultMap.toString());
              writer.flush();
              writer.close();
          // 3、认证失败调用的方法
          protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed)
              log.info("==== unsuccessfulAuthentication  ======");
              resultMap.put("code","500");
              resultMap.put("msg","登录验证失败");
              resultMap.put("data",new HashMap<>());
      }

      配置token权限校验过滤器

      package security.filter;
      
      import lombok.extern.slf4j.Slf4j;
      import org.springframework.security.authentication.AuthenticationManager;
      import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
      import org.springframework.security.core.GrantedAuthority;
      import org.springframework.security.core.authority.SimpleGrantedAuthority;
      import org.springframework.security.core.context.SecurityContextHolder;
      import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
      import org.springframework.stereotype.Component;
      import security.config.TokenJwtManager;
      import javax.servlet.FilterChain;
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      import java.util.ArrayList;
      import java.util.Arrays;
      import java.util.Collection;
      import java.util.List;
      /**
       * token 校验
       */
      @Slf4j
      //@Component // 交给 spring 会报错
      public class TokenAuthFilter extends BasicAuthenticationFilter {
          private TokenJwtManager tokenJwtManager;
          public TokenAuthFilter(AuthenticationManager authenticationManager, TokenJwtManager tokenJwtManager) {
              super(authenticationManager);
              this.tokenJwtManager = tokenJwtManager;
          }
          @Override
          protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
              log.info("====  doFilterInternal   ==========   token校验");
              //获取当前认证成功用户权限信息
              UsernamePasswordAuthenticationToken authRequest = getAuthentication(request);
              if(authRequest != null){
                  // 有权限,则放入权限上下文中
                  SecurityContextHolder.getContext().setAuthentication(authRequest);
              }
              // 执行下一个 filter 过滤器链
              chain.doFilter(request,response);
          private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
              log.info("==== getAuthentication =====");
              //从header获取token
              String token = request.getHeader("token");
              log.info("token:{}",token);
              if(token != null) {
                  //从token获取用户名
                  String username = tokenJwtManager.getUserName(token);
                  log.info("解析token获取userName为:{}",username);
                  // 数据库获取权限信息
                  // 本次模拟
                  List<String> permissionValueList = Arrays.asList("admin","select");
                  Collection<GrantedAuthority> authority = new ArrayList<>();
                  for(String permissionValue : permissionValueList) {
                      SimpleGrantedAuthority auth = new SimpleGrantedAuthority(permissionValue);
                      authority.add(auth);
                  }
                  return new UsernamePasswordAuthenticationToken(username,token,authority);
              return null;
      }

      自定义加密类

      package security.config;
      
      import lombok.extern.slf4j.Slf4j;
      import org.springframework.security.crypto.password.PasswordEncoder;
      import org.springframework.stereotype.Component;
      import security.utils.Md5Utils;
      /**
       * 密码加密、比对
       */
      @Component // bean
      @Slf4j
      public class DefaultPwdEndoder implements PasswordEncoder {
          /**
           * 加密
           * @param charSequence
           * @return
           */
          @Override
          public String encode(CharSequence charSequence) {
              log.info("==== encode ====");
              log.info("charSequence 为 {}",charSequence);
              log.info("charSequence md5为 {}",Md5Utils.md5(charSequence.toString()));
              return Md5Utils.md5(charSequence.toString());
          }
           * 进行密码比对
           * @param charSequence 不加密
           * @param encodePwd  加密
          public boolean matches(CharSequence charSequence, String encodePwd) {
              log.info("==== matches ====");
              log.info("charSequence:{}",charSequence);
              log.info("charSequenceMd5:{}",Md5Utils.md5(charSequence.toString()));
              log.info("encodePwd:{}",encodePwd);
              return encodePwd.equalsIgnoreCase(Md5Utils.md5(charSequence.toString()));
      }

      配置UserDetailService

      package security.service;
      
      import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
      import lombok.extern.slf4j.Slf4j;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.security.core.GrantedAuthority;
      import org.springframework.security.core.authority.AuthorityUtils;
      import org.springframework.security.core.userdetails.UserDetails;
      import org.springframework.security.core.userdetails.UserDetailsService;
      import org.springframework.security.core.userdetails.UsernameNotFoundException;
      import org.springframework.stereotype.Component;
      import org.springframework.stereotype.Service;
      import security.mapper.UserMapper;
      import security.vo.SecurityUser;
      import security.vo.User;
      import java.util.Arrays;
      import java.util.List;
      /**
       * security 登录信息和权限获取类
       */
      @Service("userDetailsService")
      @Slf4j
      public class UserDetailService implements UserDetailsService {
          // 注入Usermapper
          @Autowired
          private UserMapper userMapper;
          @Override
          public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
              log.info("====== loadUserByUsername ======");
              // 通过username查询数据库获取用户信息
              QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
              userQueryWrapper.eq("username",userName);
              User user = userMapper.selectOne(userQueryWrapper);
              // 判断用户是否存在
              if(user == null){
                  throw new UsernameNotFoundException("账户信息不存在!");
              }
              // 存在对应的用户信息,则将其封装,丢给security自己去解析
              log.info("user:{}",user);
              // 权限暂时不查数据库
              List<String> admin = Arrays.asList("ROLE_user,ROLE_admin,admin");
              // 将数据封装给 SecurityUser ,因为 SecurityUser 是 UserDetails 的子类
              SecurityUser securityUser = new SecurityUser();
              securityUser.setPermissionValueList(admin);
              securityUser.setUser(user);
              log.info("securityUser:{}",securityUser.toString());
              return securityUser;
          }
      }

      配置数据库User对象映射类

      package security.vo;
      
      import lombok.AllArgsConstructor;
      import lombok.Data;
      import lombok.NoArgsConstructor;
      import java.io.Serializable;
      @Data
      @NoArgsConstructor
      @AllArgsConstructor
      public class User implements Serializable {
          private static final long serialVersionUID = -5461108964440966122L;
          private Integer id;
          private String username;
          private String password;
          private Integer enabled;
          private Integer locked;
      }

      配置UserDetailService使用的SecurityUser类

      package security.vo;
      
      import lombok.Data;
      import org.springframework.security.core.GrantedAuthority;
      import org.springframework.security.core.authority.SimpleGrantedAuthority;
      import org.springframework.security.core.userdetails.UserDetails;
      import org.springframework.util.StringUtils;
      import java.util.ArrayList;
      import java.util.Collection;
      import java.util.List;
      /**
       * UserDetailService 使用该类,该类必须是 UserDetails 的子类
       */
      @Data
      public class SecurityUser implements UserDetails {
          // 登录用户的基本信息
          private User user;
          //当前权限
          private List<String> permissionValueList;
          public SecurityUser() {
          }
          public SecurityUser(User user) {
              if (user != null) {
                  this.user = user;
              }
          @Override
          public Collection<? extends GrantedAuthority> getAuthorities() {
              Collection<GrantedAuthority> authorities = new ArrayList<>();
              permissionValueList.forEach(permission ->{
                  if(!StringUtils.isEmpty(permission)){
                      SimpleGrantedAuthority authority = new SimpleGrantedAuthority(permission);
                      authorities.add(authority);
                  }
              });
              return authorities;
          public String getPassword() {
              return user.getPassword();
          public String getUsername() {
              return user.getUsername();
          public boolean isAccountNonExpired() {
              return true;
          public boolean isAccountNonLocked() {
          public boolean isCredentialsNonExpired() {
          public boolean isEnabled() {
      }

      配置mybatis-plus

      首先,需要配置application.properties数据库连接源。

      spring.datasource.username=root
      spring.datasource.password=root
      spring.datasource.url=jdbc:mysql://106.55.137.66:3306/security?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
      spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
      
      server.port=80

      其次,需要配置Mapper类,查询数据库获取基本数据信息。

      package security.mapper;
      
      import com.baomidou.mybatisplus.core.mapper.BaseMapper;
      import org.springframework.stereotype.Repository;
      import security.vo.User;
      @Repository
      public interface UserMapper extends BaseMapper<User> {
      }

      配置security配置类

      package security.config;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.http.HttpMethod;
      import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
      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.WebSecurityConfigurerAdapter;
      import security.config.handler.*;
      import security.filter.TokenAuthFilter;
      import security.filter.TokenLoginFilter;
      import security.service.UserDetailService;
      /**
       * security 配置类
       */
      @Configuration
      @EnableGlobalMethodSecurity(prePostEnabled = true)  // 方法增加权限
      public class MyTokenSecurityConfig extends WebSecurityConfigurerAdapter {
          // 将 UserDetailService 注入,使其去查询数据库
          @Autowired
          private UserDetailService userDetailsService;
          // token 生成器
          @Autowired
          private TokenJwtManager tokenManager;
          // 自定义密码加密解密
          @Autowired
          private DefaultPwdEndoder defaultPwdEndoder;
          // 未登录handler
          @Autowired
          private MyUnAuthEntryPoint myUnAuthEntryPoint;
          // 无权限
          @Autowired
          private MyAccessDeniedHandler myAccessDeniedHandler;
          //  登出handler处理
          @Autowired
          private MyLogoutHandler myLogoutHandler;
          // 登录失败
          @Autowired
          private LoginFailedHandler loginFailedHandler;
          // 登录成功
          @Autowired
          private LoginSuccessHandler loginSuccessHandler;
          /**
           * 登录时,从数据库获取基本信息和权限信息
           * @param auth
           * @throws Exception
           */
          @Override
          protected void configure(AuthenticationManagerBuilder auth) throws Exception {
              // 设置 userDetailsService 和 密码解析
              auth.userDetailsService(userDetailsService).passwordEncoder(defaultPwdEndoder);
          }
          /**
           * 配置访问过滤
           * @param http
           * @throws Exception
           */
          @Override
          protected void configure(HttpSecurity http) throws Exception {
              http.exceptionHandling()
                      .authenticationEntryPoint(myUnAuthEntryPoint) // 未登录 handler
                      .accessDeniedHandler(myAccessDeniedHandler) // 无权限
                      .and().csrf().disable() // 关闭 csrf 跨域请求
                      .formLogin()
                      .loginProcessingUrl("/user/login")  // 设定登录请求接口
                      .usernameParameter("userName")
                      .passwordParameter("passWord")
                      //.successHandler(loginSuccessHandler) // 因为有了 TokenLoginFilter 配置过滤器,此处配置没用
                      //.failureHandler(loginFailedHandler) // 因为有了 TokenLoginFilter 配置过滤器,此处配置没用
                      .permitAll()
                      .and()
                      .authorizeRequests() // 请求设置
                      .antMatchers("/test").permitAll() // 配置不需要认证的接口
                      .anyRequest().authenticated() // 任何请求都需要认证
                      .and()
                      .logout() // logout设定
                      .logoutUrl("/logouts")  //退出请求  /logouts 未定义,交给自定义handler实现功能
                      .addLogoutHandler(myLogoutHandler) // 登出 myLogoutHandler 处理
                      .and()
                      .addFilter(new TokenLoginFilter(tokenManager,authenticationManager())) // 认证交给 自定义 TokenLoginFilter 实现
                      .addFilter(new TokenAuthFilter(authenticationManager(),tokenManager))
                      .httpBasic();
          }
          /**
           * 配置不需要验证的访问路径
           * @param web
           * @throws Exception
           */
          @Override
          public void configure(WebSecurity web) throws Exception {
              //web.ignoring().antMatchers("/test","/user/login");
              web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
          }
      }
      

      配置几个测试接口

      package security.controller;
      
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      @RestController
      public class TestController {
          @RequestMapping("/test")
          public String test(){
              return "不需要认证就能访问";
          }
      }
      package security.controller;
      
      import org.springframework.security.access.prepost.PreAuthorize;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      @RestController
      public class UserController {
          @RequestMapping("/user/test1")
          @PreAuthorize("hasAnyAuthority('admin','user')")
          public String test1(){
              return "需要认证的 /user/test1";
          }
          @RequestMapping("/user/test2")
          @PreAuthorize("hasAnyAuthority('test')")
          public String test2(){
              return "需要认证的 /user/test2";
      }

      Md5加密工具类

      package security.utils;
      
      import java.io.UnsupportedEncodingException;
      import java.security.MessageDigest;
      import java.security.NoSuchAlgorithmException;
      import java.util.Base64;
      /**
       * 加密工具类
       */
      public class Md5Utils {
          public static String md5(String str) {
              try {
                  MessageDigest md = MessageDigest.getInstance("MD5");
                  md.update(str.getBytes());
                  byte b[] = md.digest();
                  str = byteToStr(b);
              } catch (Exception e) {
                  e.printStackTrace();
              }
              return str;
          }
          public static String byteToStr(byte[] b){
              int i;
              StringBuffer buf = new StringBuffer("");
              for (int offset = 0; offset < b.length; offset++) {
                  i = b[offset];
                  //System.out.println(i);
                  if (i < 0)
                      i += 256;
                  if (i < 16)
                      buf.append("0");
                  buf.append(Integer.toHexString(i));
              return buf.toString();
          /**
           * 传入文本内容,返回 SHA-256 串
           *
           * @param strText
           * @return
           */
          public static String SHA256(final String strText)
          {
              return SHA(strText, "SHA-256");
          public static String SHA1(final String strText)
              return SHA(strText, "SHA-1");
           * 传入文本内容,返回 SHA-512 串
          public static String SHA512(final String strText)
              return SHA(strText, "SHA-512");
           * 字符串 SHA 加密
          private static String SHA(final String strText, final String strType)
              // 返回值
              String strResult = null;
              // 是否是有效字符串
              if (strText != null && strText.length() > 0)
              {
                  try
                  {
                      // SHA 加密开始
                      MessageDigest messageDigest = MessageDigest.getInstance(strType);
                      // 传入要加密的字符串
                      messageDigest.update(strText.getBytes("utf-8"));
                      // 得到 byte 类型的结果
                      byte byteBuffer[] = messageDigest.digest();
                      strResult = byteToStr(byteBuffer);
                  }
                  catch (NoSuchAlgorithmException e)
                      e.printStackTrace();
                  }catch (UnsupportedEncodingException e) {
                      // TODO Auto-generated catch block
              return strResult;
          public static String base64(String str){
              String baseStr = null;
              Base64.Encoder encoder = Base64.getEncoder();
              byte[] textByte;
                  textByte = str.getBytes("UTF-8");
                  baseStr = encoder.encodeToString(textByte);
              } catch (UnsupportedEncodingException e) {
              return baseStr;
          public static void main(String[] args) {
              String password = "bunana1";
              System.out.println(md5(password));
              //String base64 = base64(sha512);
              //System.out.println(base64);
              //String pwd1 = md5(base64);
              //System.out.println(pwd1);
      }

      测试

      测试采取ApiPost 工具,让测试更接近前后分离。

      首先测试登录

      Post
      localhost/user/login

      账号密码有一个不对时。

      正确的账号密码

      测试存在权限的接口

      localhost/user/test1

      测试不存在权限的接口

      localhost/user/test2

      测试登出

      localhost/logouts

      测试不需要权限的接口

      localhost/test

      数据库sql脚本

      CREATE TABLE `user` (
        `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, -- 主键
        `username` varchar(255) DEFAULT NULL,    -- 用户名
        `password` varchar(255) DEFAULT NULL,    -- 用户密码
        `enabled` tinyint(1) DEFAULT '1',        -- 是否启用 1-启用 0-未启用
        `locked` tinyint(1) DEFAULT '0',         -- 是否被锁 1-已锁 0-未锁
        PRIMARY KEY (`id`)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
      

      数据为:

      insert INTO user(username,password,enabled,locked) VALUES("xiangjiaoSS","1babad058e03c5296a94a5a8d7d6dd8a",1,0); -- bunana 的md5 值
      insert INTO user(username,password,enabled,locked) VALUES("xiangjiaoSS2","0b13310f8db2dc22e7ddd0cdc5f0a61a",1,0); -- bunana1 的md5 值
      insert INTO user(username,password,enabled,locked) VALUES("xiangjiaoSS3","b3fbcd9c9d97e47f263a19a0e01efc7d",1,0); -- bunana2 的md5 值
      

      代码下载

      springboot-security-10-qianhou

      gitee 代码下载地址

      在线客服
      服务热线

      服务热线

      4008888355

      微信咨询
      二维码
      返回顶部
      ×二维码

      截屏,微信识别二维码

      打开微信

      微信号已复制,请打开微信添加咨询详情!