自定义用户权限,全局用户搜索

1.自定义用户登录认证

思想:用户登录后将用户存入到ThreadLocal中,访问非白名单接口时在filter中获取用户信息,为空则抛出异常,不为空放行。

1.存用户信息

package com.ztccloud.auth.util;

import com.ztccloud.auth.entity.RecordUser;

/**
 * @program: zfd-questionaire
 * @description: session管理器
 * @author: dct
 * @create: 2022-01-26 10:56
 **/
public class SessionUtils {

    //当前线程存放用户信息
    public static ThreadLocal<RecordUser> threadLocal = new ThreadLocal<>();

    /**
     * 设置用户信息
     *
     * @param recordUser
     */
    public static void setUser(RecordUser recordUser) {
        threadLocal.set(recordUser);
    }

    /**
     * 获取用户信息
     *
     * @return
     */
    public static RecordUser getUser() {
        RecordUser user = threadLocal.get();
        return user;
    }

    /**
     * 删除用户信息
     */
    public static void distoryUser() {
        threadLocal.remove();
    }
}

对存入信息进行二次封装:

package com.ztccloud.auth.util;

import com.ztccloud.auth.entity.RecordUser;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpSession;

/**
 * @author dongchentong
 * @date 2021/11/15 18:03
 */
@Component
public class UserControl {

    public static final String SESSION_USER="user";

    public static  void  setUser(RecordUser user){
        HttpSession session = getSession();
        session.setAttribute(SESSION_USER, user);
        SessionUtils.setUser(user);
    }

    public static void removeUser() {
        HttpSession session = getSession();
        session.removeAttribute(SESSION_USER);
        SessionUtils.distoryUser();
    }

    private static HttpSession getSession() {
        HttpSession session = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest().getSession();
        return session;
    }


}

3.核心filter

package com.ztccloud.auth.filter;


import com.ztccloud.auth.entity.RecordUser;
import com.ztccloud.auth.util.SessionUtils;
import com.ztccloud.auth.util.UserControl;
import com.ztccloud.naire.exception.ErrorController;
import com.ztccloud.naire.exception.QuestionException;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

/**
 * @program: zfd-questionaire
 * @description: 用户认证拦截器
 * @author: dct
 * @create: 2022-01-26 10:48
 **/
public class AuthFilter implements Filter {

        //配置白名单
        protected static List<String> patterns = Arrays.asList("/user/login");

        @Override
        public void init(FilterConfig filterConfig) {

        }

        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws  ServletException, IOException {
            HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
            HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;

            String url = httpRequest.getRequestURI().substring(httpRequest.getContextPath().length());
            if (patterns.contains(url)|| StringUtils.containsAny(url,new String[]{"swagger","api-docs"})) {
                //在白名单中的url,放行访问
                filterChain.doFilter(httpRequest, httpResponse);
                return;
            }
            RecordUser user=(RecordUser) httpRequest.getSession().getAttribute(UserControl.SESSION_USER);
            if (user != null) {
                //若为登录状态 放行访问
                UserControl.setUser(user);
                filterChain.doFilter(httpRequest, httpResponse);
            } else {
                //提示用户未进行登录
                try {
                    throw new QuestionException("ques_user_1001","User not logged in!");
                } catch (Exception e) {
                    servletRequest.setAttribute(ErrorController.ATTRIBUTE, e);
                    servletRequest.getRequestDispatcher(ErrorController.ERROR_PATH).forward(servletRequest, servletResponse);
                }
            }

        }

        @Override
        public void destroy() {

        }

}

4.请求结束后使用监听器,释放Session中的数据

package com.ztccloud.auth.filter;

import com.ztccloud.auth.util.SessionUtils;
import org.springframework.stereotype.Component;

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;

/**
 * @program: zfd-questionaire
 * @description: 请求监听器, 释放线程内存
 * @author: dct
 * @create: 2022-01-26 14:24
 **/
@Component
public class RequestListener implements ServletRequestListener {
    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        SessionUtils.distoryUser();
    }
}

2.使用自定义注解进行方法级别权限校验

1.定义角色枚举类

package com.ztccloud.auth.node;

import java.util.HashMap;
import java.util.Map;

/**
 * @program: zfd-questionaire
 * @description: 角色枚举
 * @author: dct
 * @create: 2022-01-26 17:08
 **/
public enum UserRoles {
    /**
     * 1,管理员
     */
    ADMIN("1000","ADMIN", "超级用户"),

    /**
     * 2,二级角色
     */
    SECADMIN("2000","SECADMIN", "二级角色"),

    /**
     * 3.基础角色
     */
    DOMESTICCONSUMER("3000","DOMESTICCONSUMER", "基础角色");

    /**
     *  RoleID
     */
    private String id;
    /**
     *  RoleName
     */
    private String code;

    /**
     * 中文名称
     */
    private String name;


     UserRoles(String id, String code, String name) {
        this.id = id;
        this.code = code;
        this.name = name;
    }

}

2.定义注解类

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @program: zfd-questionaire
 * @description: 自定义注解interface
 * @author: dct
 * @create: 2022-01-26 17:32
 **/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Authorization
{
    UserRoles[] value() default{};
}

3.授权处理拦截器

import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;

/**
 * @program: zfd-questionaire
 * @description: 授权处理拦截器
 * @author: dct
 * @create: 2022-01-26 17:46
 **/

@Component("authInterceptor")
public class AuthInterceptor implements HandlerInterceptor
{
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    {
        if (handler.getClass().isAssignableFrom(HandlerMethod.class))
        {
            // 方法上是否有授权注解
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Authorization authorization = handlerMethod.getMethodAnnotation(Authorization.class);
            if(authorization == null){
                return true;
            }
            // 获取授权信息
            ArrayList<UserRoles> roles = new ArrayList<UserRoles>();
            for (int i = 0; i < authorization.value().length; i++)
            {
                roles.add(authorization.value()[i]);
            }
            // 权限检查时,若权限不匹配,需抛出异常
            AuthChecker.check(roles, request);
        }
        return true;
    }
}

4.实时权限校验

import com.ztccloud.auth.entity.Role;
import com.ztccloud.auth.util.SessionUtils;
import com.ztccloud.naire.exception.QuestionException;

import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @program: zfd-questionaire
 * @description: 实时权限检查
 * @author: dct
 * @create: 2022-01-26 17:33
 **/
public class AuthChecker {

    /**
    * @Description: 执行权限检查。根据Controller的权限和实际登录用户的权限进行匹配,从而允许或者拒 绝访问。拒绝访问时,抛出异常
    * @Param: [presetRoles, request]
    * @return: [java.util.List<com.ztccloud.auth.node.UserRoles>, javax.servlet.http.HttpServletRequest]
    * @Author: dct
    * @Date: 2022/1/26
    */
    public static void check(List<UserRoles> presetRoles, HttpServletRequest request)
    {
        // 若允许匿名访问,不做权限检查。
        List<Role> userRoles = SessionUtils.getUser().getUserRoles();
        List<String> roles = presetRoles.stream().map(UserRoles::name).collect(Collectors.toList());
        List<String> roleNames = userRoles.stream().map(Role::getRoleName).collect(Collectors.toList());
        if(!Collections.disjoint(roles,roleNames)) {
            return;
        } else {
            throw new QuestionException("ques_user_1003","Insufficient permissions");
        }
    }
}

5.注册Hanlder

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @program: zfd-questionaire
 * @description: 角色认证器注册
 * @author: dct
 * @create: 2022-01-26 21:51
 **/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/**");
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值