• java 通过 token + filter 自动设置操作人信息


    由于项目使用 spring cloud + oauth2 +reids 来认证,每次微服务中需要自己手动代码获取登录用户信息比较麻烦,所以想到统一通过 filter 来实现

    步骤如下:

    1.定义操作人基本信息接口

    IBaseOperator.java

    import java.util.Date;
    
    /**
     * 基础操作人信息
     */
    public interface IBaseOperator {
        void setOperatedByUserName(String operatedByUserName);
        String getOperatedByUserName();
        void setOperatedOn(Date operatedOn);
        Date getOperatedOn();
    }
    

      

    IOperator.java
    package com.dimpt.common.interfaces;
    
    /**
     * 操作人信息
     */
    public interface IOperator extends IBaseOperator {
        void setOperatedByUserId(String operatedByUserId);
        String getOperatedByUserId();
    
        void setOperatedByRealName(String operatedByRealName);
        String getOperatedByRealName();
    }
    

      2.拦截器

    OperaterFilter.java 

    import java.io.IOException;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import com.dimpt.common.http.BodyRequestWrapper;
    import com.dimpt.common.http.ParameterRequestWrapper;
    import com.dimpt.common.interfaces.IOperator;
    import com.dimpt.common.security.CustomerUser;
    import com.dimpt.common.util.JsonUtils;
    import com.dimpt.common.util.components.UserUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.util.StringUtils;
    
    /**
     * @RequestBody 注解参数中新增 {@link IOperator} 数据
     */
    @Component
    public class OperaterFilter implements Filter {
    
        private static final Logger logger = LoggerFactory.getLogger(OperaterFilter.class);
    
        @Autowired
        UserUtils userUtils;
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }
    
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
                throws IOException, ServletException {
    
            HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
    
            CustomerUser customerUser = userUtils.getCustomerUser();
            if (customerUser != null) {
    
                CustomerUser.User user = customerUser.getUserDetails();
    
                //region 设置 ServletRequest 的登录用户参数
                HashMap m = new HashMap(httpServletRequest.getParameterMap());
                m.put("operatedByUserId",user.getUserId());
                m.put("operatedByUserName",user.getUserName());
                m.put("operatedByRealName",user.getName());
                m.put("operatedOn",new Date());
                ParameterRequestWrapper parameterRequestWrapper = new ParameterRequestWrapper(httpServletRequest, m);
                httpServletRequest = parameterRequestWrapper;
                //endregion
    
                //设置 @RequestBody 的登录用户数据
                BodyRequestWrapper bodyReaderHttpServletRequestWrapper = new BodyRequestWrapper(httpServletRequest);
                String bodyString = bodyReaderHttpServletRequestWrapper.getBodyString();
                if(!StringUtils.isEmpty(bodyString))
                {
                    Map bodyMap = JsonUtils.toMap(bodyString);
                    bodyMap.put("operatedByUserId",user.getUserId());
                    bodyMap.put("operatedByUserName",user.getUserName());
                    bodyMap.put("operatedByRealName",user.getName());
                    bodyMap.put("operatedOn",new Date());
                    String newBodyString = JsonUtils.toString(bodyMap);
                    bodyReaderHttpServletRequestWrapper.setBodyString(newBodyString);
                    httpServletRequest = bodyReaderHttpServletRequestWrapper;
                }
            }
    
            filterChain.doFilter(httpServletRequest, servletResponse);
        }
    
    
        @Override
        public void destroy() {
        }
    }
    

      

    BodyRequestWrapper.java
    import java.io.*;
    import java.nio.charset.Charset;
    import javax.servlet.ReadListener;
    import javax.servlet.ServletInputStream;
    import javax.servlet.ServletRequest;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    
    /**
     * @RequestBody 参数的 HttpServletRequestWrapper
     */
    @SuppressWarnings("unchecked")
    public class BodyRequestWrapper extends HttpServletRequestWrapper{
        private byte[] body;
        private String bodyString;
    
        public byte[] getBody() {
            return body;
        }
    
        public String getBodyString() {
            return bodyString;
        }
    
        public BodyRequestWrapper(HttpServletRequest request) throws IOException {
            super(request);
            bodyString = getBodyString(request);
            body = bodyString.getBytes(Charset.forName("UTF-8"));
        }
    
        /**
         * 获取请求Body
         *
         * @param request
         * @return
         */
        public String getBodyString(final ServletRequest request) {
            StringBuilder sb = new StringBuilder();
            InputStream inputStream = null;
            BufferedReader reader = null;
            try {
                inputStream = cloneInputStream(request.getInputStream());//将获取到的请求参数重新塞入request里面去
                reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
                String line = "";
                while ((line = reader.readLine()) != null) {
                    sb.append(line);
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            finally {
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    }
                    catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (reader != null) {
                    try {
                        reader.close();
                    }
                    catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return sb.toString();
        }
    
        public void setBodyString(String bodyString) throws UnsupportedEncodingException {
            bodyString=bodyString;
            this.body = bodyString.getBytes("UTF-8");
        }
    
        /**
         * Description: 复制输入流</br>
         *
         * @param inputStream
         * @return</br>
         */
        public InputStream cloneInputStream(ServletInputStream inputStream) {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            try {
                while ((len = inputStream.read(buffer)) > -1) {
                    byteArrayOutputStream.write(buffer, 0, len);
                }
                byteArrayOutputStream.flush();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            InputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
            return byteArrayInputStream;
        }
        @Override
        public BufferedReader getReader() throws IOException {
            return new BufferedReader(new InputStreamReader(getInputStream()));
        }
    
        @Override
        public ServletInputStream getInputStream() throws IOException {
    
            final ByteArrayInputStream bais = new ByteArrayInputStream(body);
    
            return new ServletInputStream() {
    
                @Override
                public int read() throws IOException {
                    return bais.read();
                }
    
                @Override
                public boolean isFinished() {
                    return false;
                }
    
                @Override
                public boolean isReady() {
                    return false;
                }
    
                @Override
                public void setReadListener(ReadListener readListener) {
                }
            };
        }
    }
    

      

    ParameterRequestWrapper.java
    import java.util.Enumeration;
    import java.util.Map;
    import java.util.Vector;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    
    /**
     * HttpServletRequest 参数的 HttpServletRequestWrapper
     */
    @SuppressWarnings("unchecked")
    public class ParameterRequestWrapper extends HttpServletRequestWrapper
    {
    
        private Map params;
    
        public ParameterRequestWrapper(HttpServletRequest request, Map newParams)
        {
            super(request);
            this.params = newParams;
        }
    
        public Map getParameterMap()
        {
            return params;
        }
    
        public Enumeration getParameterNames()
        {
            Vector l = new Vector(params.keySet());
            return l.elements();
        }
    
        public String[] getParameterValues(String name)
        {
            Object v = params.get(name);
            if (v == null)
            {
                return null;
            }
            else if (v instanceof String[])
            {
                return (String[])v;
            }
            else if (v instanceof String)
            {
                return new String[] {(String)v};
            }
            else
            {
                return new String[] {v.toString()};
            }
        }
    
        public String getParameter(String name)
        {
            Object v = params.get(name);
            if (v == null)
            {
                return null;
            }
            else if (v instanceof String[])
            {
                String[] strArr = (String[])v;
                if (strArr.length > 0)
                {
                    return strArr[0];
                }
                else
                {
                    return null;
                }
            }
            else if (v instanceof String)
            {
                return (String)v;
            }
            else
            {
                return v.toString();
            }
        }
    }
    

      



    CustomerUser.java
    import lombok.Getter;
    import lombok.Setter;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.userdetails.User;
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    
    public class CustomerUser extends User {
    
        private static final long serialVersionUID = -814031798199130344L;
        /**
         * 登录用户的基本信息
         */
        @Getter
        @Setter
        private User userDetails;
    
        public CustomerUser(String username, String password, Collection<? extends GrantedAuthority> authorities) {
            super(username, password, authorities);
        }
    
        public CustomerUser(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
            super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
        }
    
        public class User implements Serializable {
            private static final long serialVersionUID = 6253500539624699762L;
            public User(){}
            /**
             * 用户id
             */
            private String userId="";
            /**
             * 用户名,大写
             */
            private String userName="";
            /**
             * 邮箱,大写
             */
            private String email="";
            /**
             * 姓名
             */
            private String name="";
            /**
             * 手机
             */
            private String phone="";
            /**
             * 用户状态
             */
            private int userState;
            /*
             * 性别 0:女  1:男
             */
            private int sex;
            /**
             * 备注
             */
            private String remark;
            /**
             * 用户角色(角色码)
             */
            private List<String> roles = new ArrayList<>();
            /**
             * 用户权限(权限码)
             */
            private List<String> permissions = new ArrayList<>();
            /**
             * 有权访问的系统(系统id)
             */
            private List<String> storeIds = new ArrayList<>();
    
            public String getUserId() {
                return userId;
            }
    
            public void setUserId(String userId) {
                this.userId = userId;
            }
    
            public String getUserName() {
                return userName;
            }
    
            public void setUserName(String userName) {
                this.userName = userName;
            }
    
            public String getEmail() {
                return email;
            }
    
            public void setEmail(String email) {
                this.email = email;
            }
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            public String getPhone() {
                return phone;
            }
    
            public void setPhone(String phone) {
                this.phone = phone;
            }
    
            public int getUserState() {
                return userState;
            }
    
            public void setUserState(int userState) {
                this.userState = userState;
            }
    
            public int getSex() {
                return sex;
            }
    
            public void setSex(int sex) {
                this.sex = sex;
            }
    
            public String getRemark() {
                return remark;
            }
    
            public void setRemark(String remark) {
                this.remark = remark;
            }
    
            public List<String> getRoles() {
                return roles;
            }
    
            public void setRoles(List<String> roles) {
                this.roles = roles;
            }
    
            public List<String> getPermissions() {
                return permissions;
            }
    
            public void setPermissions(List<String> permissions) {
                this.permissions = permissions;
            }
    
            public List<String> getStoreIds() {
                return storeIds;
            }
    
            public void setStoreIds(List<String> storeIds) {
                this.storeIds = storeIds;
            }
        }
    }

    UserUtils.java
    import com.dimpt.common.security.CustomerUser;
    import com.dimpt.common.util.TokenUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.DependsOn;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.oauth2.common.OAuth2AccessToken;
    import org.springframework.security.oauth2.provider.OAuth2Authentication;
    import org.springframework.security.oauth2.provider.token.TokenStore;
    import org.springframework.stereotype.Component;
    import org.springframework.util.StringUtils;
    import org.springframework.web.context.request.RequestAttributes;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    import javax.servlet.http.HttpServletRequest;
    
    /**
     * @Description
     * @Author 胡俊敏
     * @Date 2019/10/25 15:45
     */
    @Component
    @DependsOn("tokenStore")
    public class UserUtils {
    
        @Autowired
        private TokenStore tokenStore;
    
        private String getToken()
        {
            RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
            if(requestAttributes==null)
                return null;
            HttpServletRequest req = ((ServletRequestAttributes) requestAttributes).getRequest();
            return TokenUtils.getToken(req);
        }
    
    
        /**
         * 获取授权服务登录的用户信息
         * @return
         */
        public UserDetails getUserDetails()
        {
            OAuth2Authentication oAuth2Authentication = tokenStore.readAuthentication(getToken());
            return getUserDetails(oAuth2Authentication);
        }
    
        /**
         * 获取授权服务登录的用户信息
         * @param token
         * @return
         */
        public UserDetails getUserDetails(OAuth2AccessToken token)
        {
            OAuth2Authentication oAuth2Authentication = tokenStore.readAuthentication(token);
            return getUserDetails(oAuth2Authentication);
        }
    
        /**
         * 获取授权服务登录的用户信息
         * @param token
         * @return
         */
        public UserDetails getUserDetails(String token)
        {
            OAuth2Authentication oAuth2Authentication = tokenStore.readAuthentication(token);
            return getUserDetails(oAuth2Authentication);
        }
    
        /**
         * 获取授权服务登录的用户信息
         * @return
         */
        public CustomerUser getCustomerUser()
        {
            String token = getToken();
            if(StringUtils.isEmpty(token))
                return null;
            OAuth2Authentication oAuth2Authentication = tokenStore.readAuthentication(token);
            return getCustomerUser(oAuth2Authentication);
        }
    
        /**
         * 获取授权服务登录的用户信息
         * @param token
         * @return
         */
        public CustomerUser getCustomerUser(OAuth2AccessToken token)
        {
            OAuth2Authentication oAuth2Authentication = tokenStore.readAuthentication(token);
            return getCustomerUser(oAuth2Authentication);
        }
    
        /**
         * 获取授权服务登录的用户信息
         * @param token
         * @return
         */
        public CustomerUser getCustomerUser(String token)
        {
            OAuth2Authentication oAuth2Authentication = tokenStore.readAuthentication(token);
            return getCustomerUser(oAuth2Authentication);
        }
    
        /**
         * 根据token获取用户名
         * @param token
         * @return
         */
        public String getUserName(String token)
        {
            UserDetails userDetails = getUserDetails(token);
            if(userDetails==null)
                return null;
            else
                return userDetails.getUsername();
        }
    
        /**
         * 根据token获取用户名
         * @param token
         * @return
         */
        public String getUserId(String token)
        {
            CustomerUser userDetails = getCustomerUser(token);
            if(userDetails==null)
                return null;
            else
                return userDetails.getUserDetails().getUserId();
        }
        /**
         * 根据token获取用户名
         * @return
         */
        public String getUserName()
        {
            UserDetails userDetails = getUserDetails();
            if(userDetails==null)
                return null;
            else
                return userDetails.getUsername();
        }
    
        /**
         * 根据token获取用户名
         * @return
         */
        public String getUserId()
        {
            CustomerUser userDetails = getCustomerUser();
            if(userDetails==null)
                return null;
            else
                return userDetails.getUserDetails().getUserId();
        }
    
        private UserDetails getUserDetails(OAuth2Authentication oAuth2Authentication)
        {
            if(oAuth2Authentication==null) return null;
            return (UserDetails) oAuth2Authentication.getPrincipal();
        }
    
        private CustomerUser getCustomerUser(OAuth2Authentication oAuth2Authentication)
        {
            if(oAuth2Authentication==null) return null;
            return (CustomerUser) oAuth2Authentication.getPrincipal();
        }
    }
    

      

    UserServiceDetail.java
    import com.dimpt.domain.entity.user.UserEntity;
    import com.dimpt.domain.enums.UserState;
    import com.dimpt.domain.mapper.service.user.UserService;
    import com.dimpt.common.security.CustomerUser;
    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 org.springframework.util.StringUtils;
    import java.util.*;
    
    /**
     * @Description
     * @Author 胡俊敏
     * @Date 2019/10/24 11:09
     */
    @Service
    public class UserServiceDetail implements UserDetailsService {
    
        @Autowired
        private UserService userService;
    
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            UserEntity user = userService.findByUserName(username);
    
            if (user == null) {
                throw new UsernameNotFoundException(username);
            }
    
            Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
    
            
            //role 鉴权
            List<String> roleCodes = userService.findRoleCodes(user.getUserId());
            if(roleCodes!=null &&!roleCodes.isEmpty()) {
                for (String code : roleCodes) {
                    //角色必须是ROLE开头
                    if (!code.startsWith("{ROLE}")) {
                        code = "{ROLE}_" + code;
                    }
                    GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(code);
                    grantedAuthorities.add(grantedAuthority);
                }
            }
         
    
    
            // 可用性 :true:可用 false:不可用
            boolean enabled = true;
            // 过期性 :true:没过期 false:过期
            boolean accountNonExpired = true;
            // 有效性 :true:凭证有效 false:凭证无效
            boolean credentialsNonExpired = true;
            // 锁定性 :true:未锁定 false:已锁定
            boolean accountNonLocked = user.getUserState()== UserState.Active;
            CustomerUser customerUser = new CustomerUser(user.getUserName(),user.getPassWord(),enabled,accountNonExpired,credentialsNonExpired,accountNonLocked,grantedAuthorities);
            //设置 SecurityUser
            CustomerUser.User securityUser = customerUser.new User();
            securityUser.setUserId(user.getUserId());
            securityUser.setUserName(user.getUserName());
            securityUser.setEmail(user.getEmail());
            securityUser.setName(user.getName());
            securityUser.setPhone(user.getPhone());
            securityUser.setSex(user.getSex());
            securityUser.setUserState(user.getUserState().getValue());
            //#TODO
            //设置用户角色
            securityUser.setRoles(Collections.EMPTY_LIST);
            //设置用户权限
            securityUser.setPermissions(Collections.EMPTY_LIST);
            //设置有权限访问的系统
            securityUser.setStoreIds(Collections.EMPTY_LIST);
            customerUser.setUserDetails(securityUser);
            return customerUser;
        }
    }
    

      

    FilterConfig.java
    import com.dimpt.common.filter.OperaterFilter;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class FilterConfig {
        @Autowired
        private OperaterFilter operatorFilter;
    
        @Bean
        public FilterRegistrationBean registerOperatorFilter() {
            FilterRegistrationBean registration = new FilterRegistrationBean();
            registration.setFilter(operatorFilter);
            registration.addUrlPatterns("/*");
            registration.setName("operatorFilter");
            registration.setOrder(1);  //值越小,Filter越靠前。
            return registration;
        }
    }
    

      

    BaseOperatorAwareCommand.java
    import com.dimpt.common.interfaces.IOperator;
    import io.swagger.annotations.ApiModelProperty;
    import lombok.Getter;
    import lombok.Setter;
    
    import java.util.Date;
    
    /**
     * 携带操作人信息的命令基类
     */
    @Getter
    @Setter
    public abstract class BaseOperatorAwareCommand implements IOperator {
    
        /**
         * 操作人的用户Id。本字段应根据当前登录用户取值(不应理会前端传入的数据)
         */
        @ApiModelProperty(hidden = true)
        private String operatedByUserId;
    
        /**
         * 操作人真实姓名。本字段应根据当前登录用户取值(不应理会前端传入的数据)
         */
        @ApiModelProperty(hidden = true)
        private String operatedByRealName;
    
        /**
         * 操作人用户名。本字段应根据当前登录用户取值(不应理会前端传入的数据)
         */
        @ApiModelProperty(hidden = true)
        private String operatedByUserName;
    
        /**
         * 操作时间
         */
        @ApiModelProperty(hidden = true)
        private Date operatedOn;
    }
    

      

    DeploymentByResourceCommand.java
    import com.dimpt.domain.command.BaseOperatorAwareCommand;
    import io.swagger.annotations.ApiModel;
    import io.swagger.annotations.ApiModelProperty;
    import lombok.Getter;
    import lombok.Setter;
    
    @Getter
    @Setter
    @ApiModel(description= "发布流程")
    public class DeploymentByResourceCommand extends BaseOperatorAwareCommand {
        @ApiModelProperty(value = "添加bpmn文件",notes = "必须是 Resource 能识别到的路径",required = true)
        private String bpmpResourcePath;
    
        @ApiModelProperty(value = "添加png文件",notes = "必须是 Resource 能识别到的路径")
        private String pngResourcePath;
    
        @ApiModelProperty(value = "流程名称",required = true)
        private String name;
    }
    

      

    具体使用如下:

     @RequestMapping("/deploymentByResource")
        @ApiOperation(value = "发布流程",notes = "项目内部资源文件部署")
        public JsonResult deploymentByResource(@RequestBody DeploymentByResourceCommand command)
        {
            securityUtils.logInAs(command.getOperatedByUserName());
    
            DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
    
            //创建Deployment对象
            deploymentBuilder = deploymentBuilder.addClasspathResource(command.getBpmpResourcePath());
    
            //添加png文件
            if(!StringUtils.isEmpty(command.getPngResourcePath()))
                deploymentBuilder = deploymentBuilder.addClasspathResource(command.getPngResourcePath());
    
            //部署
            Deployment deployment = deploymentBuilder.name(command.getName()).deploy();
            return JsonResult.success(deployment);
        }
    

      

    command.getOperatedByUserName()

    command.operatedByUserId()

    command.operatedByRealName()

    command.getOperatedOn()

  • 相关阅读:
    【microstation CE二次开发】不打开microstation,以COM方式启动Microstation
    【microstation CE二次开发】环境搭建
    Node安装与卸载命令汇总
    Maven进行clean时报错,解决方法
    Django 报ckeditor/skins/moono/skin.js 404
    Handler dispatch failed; nested exception is java.lang.AbstractMethodError: Method com/mchange/v2/c3p0/impl/NewProxyResultSet.isClosed()Z is abstract
    精准测试系列分享之一:JaCoCo 企业级应用的优缺点分析
    Java 中常见的细粒度锁实现
    JVM 的运行时数据区域分布
    Java 细粒度锁续篇
  • 原文地址:https://www.cnblogs.com/hujunmin/p/12778469.html
Copyright © 2020-2023  润新知