4

在进行一些公司内部系统开发中,经常会需要对接公司内部统一的权限管理系统进行权限角色验证等等。在实际开发过程中可以借助Spring的Session Repository实现权限验证功能。
实现步骤如下:

一、添加自定义Session注解EnableUserHttpSession

package com.web.common.session;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
 * 用戶Session
 *
 */
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target({java.lang.annotation.ElementType.TYPE})
@Documented
@Import(UserHttpSessionConfiguration.class)
@Configuration
public @interface EnableUserHttpSession {
    /**
     * session 生效最大時間
     *
     * @return
     */
    int maxInactiveIntervalInSeconds() default 1800;
}

二、添加自定义Session Configuration配置UserHttpSessionConfiguration

package com.web.common.session;

import java.util.Map;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportAware;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration;

import com.pingan.manpan.user.service.AuthService;

/**
 * Session配置
 */
@Configuration
public class UserHttpSessionConfiguration extends SpringHttpSessionConfiguration implements ImportAware {

    //session 最大生存时间
    private Integer maxInactiveIntervalInSeconds = 1800;

    // @Bean配置UserSessionRepository
    @Bean
    public UserSessionRepository sessionRepository(AuthService authService) {
        UserSessionRepository repository = new UserSessionRepository(authService);
        repository.setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds);
        return repository;
    }

/*
 * ImportAware 在注解解析完成后调用 setImportMetadata 注解获取导入
 *(@Configuration)配置的注解的元数据
 */
    @Override
    public void setImportMetadata(AnnotationMetadata importMetadata) {
        Map<String, Object> enableAttrMap =
                importMetadata.getAnnotationAttributes(EnableHaofangUserHttpSession.class.getName());
        AnnotationAttributes enableAttrs = AnnotationAttributes.fromMap(enableAttrMap);
        this.maxInactiveIntervalInSeconds = enableAttrs.getNumber("maxInactiveIntervalInSeconds");
    }
}

三、自定义Session Repository:UserSessionRepository

package com.web.common.session;

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

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.session.ExpiringSession;
import org.springframework.session.SessionRepository;

import com.user.dto.VisitorDTO;
import com.user.service.AuthService;
import com.web.common.constant.WebConstants;
import com.web.common.handler.WebExceptionHandler;

/**
 * 用户session获取
 *
 */
public class UserSessionRepository
        implements SessionRepository<UserSessionRepository.UserSession> {
    static Logger LOG = LoggerFactory.getLogger(UserSessionRepository.class);

    /**
     * 生效时间
     */
    private Integer defaultMaxInactiveInterval;

    /**
     * 权限系统访问服务类
     */
    private AuthService authService;

    /**
     * 构造方法
     *
     * @param authService
     */
    public UserSessionRepository(AuthService authService) {
        super();
        this.authService = authService;
    }

    /**
     * 设置最大生效时间
     *
     * @param defaultMaxInactiveInterval
     */
    public void setDefaultMaxInactiveInterval(int defaultMaxInactiveInterval) {
        this.defaultMaxInactiveInterval = defaultMaxInactiveInterval;
    }

    @Override
    public UserSession createSession() {
        UserSession UserSession = new UserSession();
        UserSession.setNew(true);
        return UserSession;
    }

    @Override
    public void save(UserSession session) {
        if (session.isNew()) {
            String preToken = (String) session.getAttribute(WebConstants.PRE_TOKEN_KEY);
            LOG.info("session save,pretoken:{}",preToken);
            VisitorDTO visitor = authService.getLoginInfoByPreToken(preToken);
            if (visitor != null) {
                session.setToken(visitor.getToken());
                session.setNew(false);
            }
        }
    }

    @Override
    public UserSession getSession(String id) {
        UserSession session = new UserSession();
        // 判断id是否有效
        VisitorDTO visitor = authService.getLoginInfoByToken(id);
        if ((visitor == null)) {
            session.setToken("");
            session.setNew(true);
            return session;
        }
        session.setToken(id);
        session.setAttribute("visitor", visitor);
        session.setNew(false);
        return session;
    }

    @Override
    public void delete(String id) {
        // 用户登出
        if (StringUtils.isNotBlank(id)) {
            authService.logout(id);
        }
    }

    /**
     * 封装相关session
     */
    final class UserSession implements ExpiringSession {

        private Map<String, Object> attributeMap = new HashMap<>();
        private String token;
        private boolean isNew = false;

        public UserSession() {
        }

        public void setNew(boolean aNew) {
            isNew = aNew;
        }

        public boolean isNew() {
            return isNew;
        }

        public void setToken(String token) {
            this.token = token;
        }

        @Override
        public String getId() {
            return this.token;
        }

        @Override
        public Set<String> getAttributeNames() {
            return attributeMap.keySet();
        }

        @Override
        public void setAttribute(String attributeName, Object attributeValue) {
            attributeMap.put(attributeName, attributeValue);
        }

        @Override
        public void removeAttribute(String attributeName) {
            attributeMap.remove(attributeName);
        }

        /*
         * (non-Javadoc)
         *
         * @see org.springframework.session.Session#getAttribute(java.lang.String)
         */
        @Override
        public Object getAttribute(String attributeName) {
            return attributeMap.get(attributeName);
        }

        /*
         * (non-Javadoc)
         *
         * @see org.springframework.session.ExpiringSession#getCreationTime()
         */
        @Override
        public long getCreationTime() {
            // TODO Auto-generated method stub
            return 0;
        }

        /*
         * (non-Javadoc)
         *
         * @see org.springframework.session.ExpiringSession#setLastAccessedTime(long)
         */
        @Override
        public void setLastAccessedTime(long lastAccessedTime) {
            // TODO Auto-generated method stub

        }

        /*
         * (non-Javadoc)
         *
         * @see org.springframework.session.ExpiringSession#getLastAccessedTime()
         */
        @Override
        public long getLastAccessedTime() {
            // TODO Auto-generated method stub
            return 0;
        }

        /*
         * (non-Javadoc)
         *
         * @see org.springframework.session.ExpiringSession#setMaxInactiveIntervalInSeconds(int)
         */
        @Override
        public void setMaxInactiveIntervalInSeconds(int interval) {
            // TODO Auto-generated method stub

        }

        /*
         * (non-Javadoc)
         *
         * @see org.springframework.session.ExpiringSession#getMaxInactiveIntervalInSeconds()
         */
        @Override
        public int getMaxInactiveIntervalInSeconds() {
            // TODO Auto-generated method stub
            return 0;
        }

        /*
         * (non-Javadoc)
         *
         * @see org.springframework.session.ExpiringSession#isExpired()
         */
        @Override
        public boolean isExpired() {
            // TODO Auto-generated method stub
            return false;
        }
    }
}

四、在Spring WEB配置中启用Spring Session

package com.pingan.manpan.web.common.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.web.http.SessionRepositoryFilter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import com.web.common.interceptor.AuthorizationInterceptor;

/**
 * WEB相关配置
 *
 */
@Configuration
public class WebConfiguration extends WebMvcConfigurationSupport {

    @Autowired
    private AuthorizationInterceptor authorizationInterceptor;

    @Autowired
    private SessionRepositoryFilter sessionRepositoryFilter;

    /**
     * 登陆权限验证拦截器
     *
     * @return
     */   
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authorizationInterceptor).addPathPatterns(WebConstants.BASE_API_PATH + "/**");
    }


    /**
     * session wrapper对应Filter注册启用Spring Session
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean sessionRepositoryFilterRegistrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(sessionRepositoryFilter);
        filterRegistrationBean.addUrlPatterns(WebConstants.BASE_API_PATH + "/*");
        return filterRegistrationBean;
    }

}

houshiqun689
83 声望3 粉丝

棒棒的的码农