Security和JWT

  • Post author:
  • Post category:其他


配置Security

package cn.tedu.csmall.passport.config;

import cn.tedu.csmall.passport.filter.JwtAuthorizationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
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.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * Spring Security的配置类
 *
 * @author java@tedu.cn
 * @version 0.0.1
 */
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthorizationFilter jwtAuthorizationFilter;

    @Bean
    public PasswordEncoder passwordEncoder() {
        // return NoOpPasswordEncoder.getInstance(); // NoOpPasswordEncoder是“不加密”的密码编码器
        return new BCryptPasswordEncoder();
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // super.configure(http); // 父类方法配置要求所有请求都是认证过的

        // 白名单URL
        // 注意:所有路径使用 / 作为第1个字符
        // 可以使用 * 通配符,例如 /admins/* 可以匹配 /admins/add-new,但是,不能匹配多级,例如不能匹配到 /admins/9527/delete
        // 可以使用 ** 通配符,例如 /admins/** 可以匹配若干级,例如可以匹配 /admins/add-new,也可以匹配到 /admins/9527/delete
        String[] urls = {
                "/admins/login",
                "/doc.html",
                "/**/*.css",
                "/**/*.js",
                "/a.jpg",
                "/favicon.ico",
                "/swagger-resources",
                "/v2/api-docs"
        };

        // 配置请求是否需要认证
        http.authorizeRequests() // 配置请求的认证授权
                .mvcMatchers(HttpMethod.OPTIONS, "/**")
                .permitAll()
                .mvcMatchers(urls) // 匹配某些请求路径
                .permitAll() // 允许直接访问,即不需要通过认证
                .anyRequest() // 其它任何请求
                .authenticated(); // 需要是通过认证的

        // 禁用“防止伪造的跨域攻击”这种防御机制
        http.csrf().disable();

        // 将JWT过滤器添加在Spring Security的“用户名密码认证信息过滤器”之前
        http.addFilterBefore(jwtAuthorizationFilter, UsernamePasswordAuthenticationFilter.class);

        // http.formLogin(); // 开启登录表单

        // 设置Session创建策略:从不创建
        // http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
    }

}

JWT过滤器

package cn.tedu.csmall.passport.filter;

import cn.tedu.csmall.passport.security.LoginPrincipal;
import cn.tedu.csmall.passport.web.JsonResult;
import cn.tedu.csmall.passport.web.ServiceCode;
import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
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;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>JWT过滤器</p>
 *
 * <p>此JWT的作用:</p>
 * <ul>
 *     <li>获取客户端携带的JWT,要求客户端将JWT存放在请求头的Authorization属性中</li>
 *     <li>解析客户端携带的JWT,并创建Authentication对象,存入到SecurityContext中</li>
 * </ul>
 *
 * @author java@tedu.cn
 * @version 0.0.1
 */
@Slf4j
@Component
public class JwtAuthorizationFilter extends OncePerRequestFilter {

    public static final int JWT_MIN_LENGTH = 113;

    @Value("${csmall.jwt.secret-key}")
    private String secretKey;

    public JwtAuthorizationFilter() {
        log.debug("创建过滤器对象:JwtAuthorizationFilter");
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        // 清空SecurityContext
        // 则SecurityContext中不再包含Authentication对象,也就没了认证信息
        // 避免前序请求携带JWT且解析成功后向SecurityContext中存入认证信息,后续未超时的请求都可以不携带JWT的“问题”
        SecurityContextHolder.clearContext();

        // 尝试从请求头中获取JWT
        String jwt = request.getHeader("Authorization");
        log.debug("尝试从请求头中获取JWT,结果:{}", jwt);

        // 检查是否获取到了有效的JWT
        if (!StringUtils.hasText(jwt) || jwt.length() < JWT_MIN_LENGTH) {
            // 对于无效的JWT,放行请求,由后续的组件继续处理
            log.debug("获取到的JWT被视为无效,当前过滤器将放行……");
            filterChain.doFilter(request, response);
            return;
        }

        // 设置响应的文档类型,用于处理异常时
        response.setContentType("application/json;charset=utf-8");

        // 尝试解析JWT
        log.debug("获取到的JWT被视为有效,准备解析JWT……");
        Claims claims = null;
        try {
            claims = Jwts.parser()
                    .setSigningKey(secretKey)
                    .parseClaimsJws(jwt)
                    .getBody();
        } catch (ExpiredJwtException e) {
            String message = "您的登录信息已过期,请重新登录!";
            log.warn("解析JWT时出现ExpiredJwtException,响应的消息:{}", message);
            JsonResult jsonResult = JsonResult.fail(ServiceCode.ERR_JWT_EXPIRED, message);
            PrintWriter writer = response.getWriter();
            writer.println(JSON.toJSONString(jsonResult));
            writer.close();
            return;
        } catch (SignatureException e) {
            String message = "非法访问!";
            log.warn("解析JWT时出现SignatureException,响应的消息:{}", message);
            JsonResult jsonResult = JsonResult.fail(ServiceCode.ERR_JWT_SIGNATURE, message);
            PrintWriter writer = response.getWriter();
            writer.println(JSON.toJSONString(jsonResult));
            writer.close();
            return;
        } catch (MalformedJwtException e) {
            String message = "非法访问!";
            log.warn("解析JWT时出现MalformedJwtException,响应的消息:{}", message);
            JsonResult jsonResult = JsonResult.fail(ServiceCode.ERR_JWT_MALFORMED, message);
            PrintWriter writer = response.getWriter();
            writer.println(JSON.toJSONString(jsonResult));
            writer.close();
            return;
        } catch (Throwable e) {
            String message = "服务器忙,请稍后再尝试(开发阶段,请检查服务器端控制台)!";
            log.warn("解析JWT时出现{},响应的消息:{}", e.getClass().getName(), message);
            e.printStackTrace();
            JsonResult jsonResult = JsonResult.fail(ServiceCode.ERR_UNKNOWN, message);
            PrintWriter writer = response.getWriter();
            writer.println(JSON.toJSONString(jsonResult));
            writer.close();
            return;
        }

        // 从Claims中获取生成时存入的数据
        Long id = claims.get("id", Long.class);
        String username = claims.get("username", String.class);
        String authoritiesJsonString = claims.get("authorities", String.class);
        log.debug("从JWT中解析得到id:{}", id);
        log.debug("从JWT中解析得到username:{}", username);
        log.debug("从JWT中解析得到authoritiesJsonString:{}", authoritiesJsonString);

        // 将解析JWT得到的管理员信息创建成为AdminPrincipal(当事人)对象
        LoginPrincipal loginPrincipal = new LoginPrincipal();
        loginPrincipal.setId(id);
        loginPrincipal.setUsername(username);

        // 准备管理员权限
        List<SimpleGrantedAuthority> authorities
                = JSON.parseArray(authoritiesJsonString, SimpleGrantedAuthority.class);

        // 创建Authentication对象,将存入到SecurityContext中
        // 此Authentication对象必须包含:当事人(Principal)、权限(Authorities),不必包含凭证(Credentials)
        Authentication authentication
                = new UsernamePasswordAuthenticationToken(
                loginPrincipal, null, authorities);

        // 将Authentication对象存入到SecurityContext中
        log.debug("即将向SecurityContext中存入认证信息:{}", authentication);
        SecurityContext securityContext = SecurityContextHolder.getContext();
        securityContext.setAuthentication(authentication);

        // 放行请求,由后续的组件继续处理
        log.debug("JWT过滤器执行完毕,放行!");
        filterChain.doFilter(request, response);
    }

}
package cn.tedu.csmall.passport.security;

import cn.tedu.csmall.passport.mapper.AdminMapper;
import cn.tedu.csmall.passport.pojo.vo.AdminLoginInfoVO;
import lombok.extern.slf4j.Slf4j;
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.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Slf4j
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private AdminMapper adminMapper;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        log.debug("Spring Security调用了loadUserByUsername()方法,参数:{}", s);

        AdminLoginInfoVO loginInfo = adminMapper.getLoginInfoByUsername(s);
        log.debug("从数据库查询用户名【{}】匹配的信息,结果:{}", s, loginInfo);

        if (loginInfo == null) {
            return null; // 暂时
        }

        // 创建权限列表
        // AdminDetails的构造方法要求是Collection<? extends GrantedAuthority>类型的
        // 在Mapper查询结果中的权限是List<String>类型的,所以需要遍历再创建得到所需的权限列表
        List<String> permissions = loginInfo.getPermissions();
        Collection<GrantedAuthority> authorities = new ArrayList<>();
        for (String permission : permissions) {
            GrantedAuthority authority = new SimpleGrantedAuthority(permission);
            authorities.add(authority);
        }

        // 创建AdminDetails类型的对象
        // 此类型是基于User类型扩展的,可以有自定义属性,例如id
        AdminDetails adminDetails = new AdminDetails(
                loginInfo.getId(), loginInfo.getUsername(), loginInfo.getPassword(),
                loginInfo.getEnable() == 1, authorities);

        log.debug("即将向Spring Security返回UserDetails对象:{}", adminDetails);
        return adminDetails;
    }

}

AdminServiceImpl

package cn.tedu.csmall.passport.service.impl;

import cn.tedu.csmall.passport.ex.ServiceException;
import cn.tedu.csmall.passport.mapper.AdminMapper;
import cn.tedu.csmall.passport.mapper.AdminRoleMapper;
import cn.tedu.csmall.passport.pojo.dto.AdminAddNewDTO;
import cn.tedu.csmall.passport.pojo.dto.AdminLoginDTO;
import cn.tedu.csmall.passport.pojo.entity.Admin;
import cn.tedu.csmall.passport.pojo.entity.AdminRole;
import cn.tedu.csmall.passport.pojo.vo.AdminListItemVO;
import cn.tedu.csmall.passport.pojo.vo.AdminStandardVO;
import cn.tedu.csmall.passport.security.AdminDetails;
import cn.tedu.csmall.passport.service.IAdminService;
import cn.tedu.csmall.passport.web.ServiceCode;
import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 处理管理员数据的业务实现类
 *
 * @author java@tedu.cn
 * @version 0.0.1
 */
@Slf4j
@Service
public class AdminServiceImpl implements IAdminService {

    @Value("${csmall.jwt.secret-key}")
    private String secretKey;
    @Value("${csmall.jwt.duration-in-minute}")
    private long durationInMinute;
    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private AdminRoleMapper adminRoleMapper;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private AuthenticationManager authenticationManager;

    public AdminServiceImpl() {
        log.debug("创建业务对象:AdminServiceImpl");
    }

    @Override
    public String login(AdminLoginDTO adminLoginDTO) {
        log.debug("开始处理【管理员登录】的业务,参数:{}", adminLoginDTO);
        // 执行认证
        Authentication authentication = new UsernamePasswordAuthenticationToken(
                adminLoginDTO.getUsername(), adminLoginDTO.getPassword());
        Authentication authenticateResult
                = authenticationManager.authenticate(authentication);
        log.debug("认证通过!");
        log.debug("认证结果:{}", authenticateResult); // 注意:此认证结果中的Principal就是UserDetailsServiceImpl中返回的UserDetails对象

        // 从认证结果中取出将要存入到JWT中的数据
        Object principal = authenticateResult.getPrincipal();
        AdminDetails adminDetails = (AdminDetails) principal;
        Long id = adminDetails.getId();
        String username = adminDetails.getUsername();
        Collection<GrantedAuthority> authorities = adminDetails.getAuthorities();
        String authoritiesJsonString = JSON.toJSONString(authorities);
        log.debug("认证结果中的当事人ID:{}", id);
        log.debug("认证结果中的当事人username:{}", username);
        log.debug("认证结果中的当事人authorities:{}", authorities);
        log.debug("认证结果中的当事人authoritiesJsonString:{}", authoritiesJsonString);

        // 将认证通过后得到的认证信息存入到SecurityContext中
        // 【注意】注释以下2行代码后,在未完成JWT验证流程之前,用户的登录将不可用
        // SecurityContext securityContext = SecurityContextHolder.getContext();
        // securityContext.setAuthentication(authenticateResult);

        // ===== 生成并返回JWT =====
        // JWT的过期时间
        Date date = new Date(System.currentTimeMillis() + durationInMinute * 60 * 1000);
        // 你要存入到JWT中的数据
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", id);
        claims.put("username", username);
        claims.put("authorities", authoritiesJsonString);
        String jwt = Jwts.builder() // 获取JwtBuilder,准备构建JWT数据
                // 【1】Header:主要配置alg(algorithm:算法)和typ(type:类型)属性
                .setHeaderParam("alg", "HS256")
                .setHeaderParam("typ", "JWT")
                // 【2】Payload:主要配置Claims,把你要存入的数据放进去
                .setClaims(claims)
                // 【3】Signature:主要配置JWT的过期时间、签名的算法和secretKey
                .setExpiration(date)
                .signWith(SignatureAlgorithm.HS256, secretKey)
                // 完成
                .compact(); // 得到JWT数据
        log.debug("即将返回JWT数据:{}", jwt);
        return jwt;
    }

    @Override
    public void addNew(AdminAddNewDTO adminAddNewDTO) {
        log.debug("开始处理【添加管理员】的业务,参数:{}", adminAddNewDTO);
        {
            // 从参数对象中取出用户名
            String username = adminAddNewDTO.getUsername();
            // 调用adminMapper.countByUsername()执行统计
            int count = adminMapper.countByUsername(username);
            // 判断统计结果是否大于0
            if (count > 0) {
                // 是:抛出异常(ERR_CONFLICT)
                String message = "添加管理员失败,尝试使用的用户名已经被占用!";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
            }
        }

        {
            // 从参数对象中取出手机号码
            String phone = adminAddNewDTO.getPhone();
            // 调用adminMapper.countByPhone()执行统计
            int count = adminMapper.countByPhone(phone);
            // 判断统计结果是否大于0
            if (count > 0) {
                // 是:抛出异常(ERR_CONFLICT)
                String message = "添加管理员失败,尝试使用的手机号码已经被占用!";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
            }
        }

        {
            // 从参数对象中取出电子邮箱
            String email = adminAddNewDTO.getEmail();
            // 调用adminMapper.countByEmail()执行统计
            int count = adminMapper.countByEmail(email);
            // 判断统计结果是否大于0
            if (count > 0) {
                // 是:抛出异常(ERR_CONFLICT)
                String message = "添加管理员失败,尝试使用的电子邮箱已经被占用!";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
            }
        }

        // 创建Admin对象
        Admin admin = new Admin();
        // 复制参数DTO对象中的属性到实体对象中
        BeanUtils.copyProperties(adminAddNewDTO, admin);
        // 将原密码加密
        String rawPassword = admin.getPassword();
        String encodedPassword = passwordEncoder.encode(rawPassword);
        admin.setPassword(encodedPassword);
        // 设置初始登录次数
        admin.setLoginCount(0);
        // 调用adminMapper.insert()方法插入管理员数据
        int rows = adminMapper.insert(admin);
        if (rows != 1) {
            String message = "添加管理员失败,服务器忙,请稍后再尝试!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_INSERT, message);
        }

        // 准备批量插入管理员与角色的关联数据
        Long adminId = admin.getId();
        Long[] roleIds = adminAddNewDTO.getRoleIds();
        AdminRole[] adminRoleList = new AdminRole[roleIds.length];
        for (int i = 0; i < roleIds.length; i++) {
            AdminRole adminRole = new AdminRole();
            adminRole.setAdminId(adminId);
            adminRole.setRoleId(roleIds[i]);
            adminRoleList[i] = adminRole;
        }
        rows = adminRoleMapper.insertBatch(adminRoleList);
        if (rows != roleIds.length) {
            String message = "添加管理员失败,服务器忙,请稍后再尝试!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_INSERT, message);
        }
    }

    @Override
    public void delete(Long id) {
        log.debug("开始处理【根据id删除删除管理员】的业务,参数:{}", id);
        // 检查尝试删除的数据是否存在
        Object queryResult = adminMapper.getStandardById(id);
        if (queryResult == null) {
            String message = "删除管理员失败,尝试访问的数据不存在!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 执行删除--管理员表
        log.debug("即将执行删除数据,参数:{}", id);
        int rows = adminMapper.deleteById(id);
        if (rows != 1) {
            String message = "删除管理员失败,服务器忙,请稍后再尝试!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_DELETE, message);
        }

        // 执行删除--管理员与角色的关联表
        rows = adminRoleMapper.deleteByAdminId(id);
        if (rows < 1) {
            String message = "删除管理员失败,服务器忙,请稍后再尝试!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_DELETE, message);
        }
    }

    @Override
    public void setEnable(Long id) {
        updateEnableById(id, 1);
    }

    @Override
    public void setDisable(Long id) {
        updateEnableById(id, 0);
    }

    @Override
    public List<AdminListItemVO> list() {
        log.debug("开始处理【查询管理员列表】的业务,参数:无");
        List<AdminListItemVO> list = adminMapper.list();
        return list;
    }

    private void updateEnableById(Long id, Integer enable) {
        String[] enableText = {"禁用", "启用"};
        log.debug("开始处理【{}管理员】的业务,ID:{},目标状态:{}", enableText[enable], id, enable);
        // 检查数据是否存在
        AdminStandardVO queryResult = adminMapper.getStandardById(id);
        if (queryResult == null) {
            String message = enableText[enable] + "管理员失败,尝试访问的数据不存在!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 检查当前状态是否与参数表示的状态相同
        if (queryResult.getEnable().equals(enable)) {
            String message = enableText[enable] + "管理员失败,当前管理员已经处于"
                    + enableText[enable] + "状态!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        // 准备执行更新
        Admin admin = new Admin();
        admin.setId(id);
        admin.setEnable(enable);
        log.debug("即将修改数据,参数:{}", admin);
        adminMapper.update(admin);
    }

}

Controller

package cn.tedu.csmall.passport.controller;

import cn.tedu.csmall.passport.pojo.dto.AdminAddNewDTO;
import cn.tedu.csmall.passport.pojo.dto.AdminLoginDTO;
import cn.tedu.csmall.passport.pojo.vo.AdminListItemVO;
import cn.tedu.csmall.passport.security.AdminDetails;
import cn.tedu.csmall.passport.security.LoginPrincipal;
import cn.tedu.csmall.passport.service.IAdminService;
import cn.tedu.csmall.passport.web.JsonResult;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.util.List;

/**
 * 处理管理员相关请求的控制器
 *
 * @author java@tedu.cn
 * @version 0.0.1
 */
@Slf4j
@RestController
@RequestMapping("/admins")
@Api(tags = "管理员管理模块")
public class AdminController {

    @Autowired
    private IAdminService adminService;

    public AdminController() {
        log.debug("创建控制器对象:AdminController");
    }

    // http://localhost:9081/admins/login
    @ApiOperation("管理员登录")
    @ApiOperationSupport(order = 50)
    @PostMapping("/login")
    public JsonResult login(AdminLoginDTO adminLoginDTO) {
        log.debug("开始处理【管理员登录】的请求,参数:{}", adminLoginDTO);
        String jwt = adminService.login(adminLoginDTO);
        return JsonResult.ok(jwt);
    }

    // http://localhost:9081/admins/add-new
    @ApiOperation("添加管理员")
    @ApiOperationSupport(order = 100)
    @PreAuthorize("hasAuthority('/ams/admin/add-new')")
    @PostMapping("/add-new")
    public JsonResult addNew(AdminAddNewDTO adminAddNewDTO) {
        log.debug("开始处理【添加管理员】的请求,参数:{}", adminAddNewDTO);
        adminService.addNew(adminAddNewDTO);
        return JsonResult.ok();
    }

    // http://localhost:9081/admins/9527/delete
    @ApiOperation("根据id删除删除管理员")
    @ApiOperationSupport(order = 200)
    @ApiImplicitParam(name = "id", value = "管理员ID", required = true, dataType = "long")
    @PreAuthorize("hasAuthority('/ams/admin/delete')")
    @PostMapping("/{id:[0-9]+}/delete")
    public JsonResult delete(@PathVariable Long id,
                             @ApiIgnore @AuthenticationPrincipal LoginPrincipal loginPrincipal) {
        log.debug("开始处理【根据id删除删除管理员】的请求,参数:{}", id);
        log.debug("当事人:{}", loginPrincipal);
        log.debug("当事人的ID:{}", loginPrincipal.getId());
        log.debug("当事人的用户名:{}", loginPrincipal.getUsername());
        adminService.delete(id);
        return JsonResult.ok();
    }

    // http://localhost:9081/admins/9527/enable
    @ApiOperation("启用管理员")
    @ApiOperationSupport(order = 310)
    @ApiImplicitParam(name = "id", value = "管理员ID", required = true, dataType = "long")
    @PreAuthorize("hasAuthority('/ams/admin/update')")
    @PostMapping("/{id:[0-9]+}/enable")
    public JsonResult setEnable(@PathVariable Long id) {
        log.debug("开始处理【启用管理员】的请求,参数:{}", id);
        adminService.setEnable(id);
        return JsonResult.ok();
    }

    // http://localhost:9081/admins/9527/disable
    @ApiOperation("禁用管理员")
    @ApiOperationSupport(order = 311)
    @ApiImplicitParam(name = "id", value = "管理员ID", required = true, dataType = "long")
    @PreAuthorize("hasAuthority('/ams/admin/update')")
    @PostMapping("/{id:[0-9]+}/disable")
    public JsonResult setDisable(@PathVariable Long id) {
        log.debug("开始处理【禁用管理员】的请求,参数:{}", id);
        adminService.setDisable(id);
        return JsonResult.ok();
    }

    // http://localhost:9081/admins
    @ApiOperation("查询管理员列表")
    @ApiOperationSupport(order = 420)
    @PreAuthorize("hasAuthority('/ams/admin/read')")
    @GetMapping("")
    public JsonResult list() {
        log.debug("开始处理【查询管理员列表】的请求,参数:无");
        List<AdminListItemVO> list = adminService.list();
        return JsonResult.ok(list);
    }

}



版权声明:本文为weixin_62186043原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。