浏览代码

@IPU_REQ_0043@weihf@添加spring session校验,使用ipu-cache.xml配置session所用redis。

weihf 4 年之前
父节点
当前提交
5a9c984478

+ 12 - 0
ipu-rest-scaffold/pom.xml

@ -47,6 +47,7 @@
47 47
		<ipu-db>3.2-SNAPSHOT</ipu-db>
48 48
		<ipu-rest>3.2-SNAPSHOT</ipu-rest>
49 49
		<junit>4.12</junit>
50
		<spring.session>1.3.5.RELEASE</spring.session>
50 51
	</properties>
51 52
52 53
	<dependencies>
@ -62,6 +63,17 @@
62 63
			<artifactId>ipu-portal</artifactId>
63 64
			<version>${ipu-rest}</version>
64 65
		</dependency>
66
		<!-- 添加springboot使用redis管理session的依赖 -->
67
		<dependency>
68
		    <groupId>org.springframework.boot</groupId>
69
            <artifactId>spring-boot-starter-data-redis</artifactId>
70
		</dependency>
71
        <dependency>
72
            <groupId>org.springframework.session</groupId>
73
            <artifactId>spring-session-data-redis</artifactId>
74
            <version>${spring.session}</version>
75
        </dependency>
76
65 77
	</dependencies>
66 78
67 79
	<build>

+ 11 - 1
ipu-rest-scaffold/src/main/java/com/ai/ipu/server/RestScaffoldStart.java

@ -1,9 +1,11 @@
1 1
package com.ai.ipu.server;
2 2
3
3 4
import com.ai.ipu.basic.util.IpuBaseException;
4 5
import com.ai.ipu.restful.boot.IpuRestApplication;
5 6
import com.ai.ipu.server.handler.AuthHandler;
6 7
import com.ai.ipu.server.handler.HandlerManager;
8
import com.ai.ipu.server.util.RedisUtil;
7 9
/**
8 10
 * @author huangbo@asiainfo.com
9 11
 * @team IPU
@ -21,8 +23,16 @@ public class RestScaffoldStart {
21 23
		try{
22 24
			IpuBaseException.registerCode(EXCEPTION_MESSAGES_CONFIG);
23 25
		}catch(Exception e) {}
26
		//将ipu-cache配置作为springboot配置
27
		String[] newArgs;
28
		try {
29
			newArgs = RedisUtil.initRedis(args);
30
		} catch (Exception e) {
31
			e.printStackTrace();
32
			newArgs = args.clone();
33
		}
24 34
		/*启动*/
25
	    IpuRestApplication.start(args);
35
	    IpuRestApplication.start(newArgs);
26 36
	}
27 37
28 38
    private static void defineHandler() {

+ 14 - 0
ipu-rest-scaffold/src/main/java/com/ai/ipu/server/config/RedisSessionConfig.java

@ -0,0 +1,14 @@
1
package com.ai.ipu.server.config;
2

3
import org.springframework.context.annotation.Configuration;
4
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
5

6
/**
7
 * 添加@EnableRedisHttpSession来开启spring session支持
8
 */
9
@Configuration
10
// maxInactiveIntervalInSeconds 默认是1800秒过期,这里测试修改为60秒
11
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 60)
12
public class RedisSessionConfig {
13

14
}

+ 54 - 0
ipu-rest-scaffold/src/main/java/com/ai/ipu/server/config/RedisSessionInterceptor.java

@ -0,0 +1,54 @@
1
package com.ai.ipu.server.config;
2

3

4
import javax.servlet.http.HttpServletRequest;
5
import javax.servlet.http.HttpServletResponse;
6

7

8
import org.springframework.beans.factory.annotation.Autowired;
9
import org.springframework.web.servlet.HandlerInterceptor;
10
import org.springframework.web.servlet.ModelAndView;
11

12
import com.ai.ipu.basic.util.IpuException;
13
import com.ai.ipu.server.util.RedisUtil;
14

15

16
/**
17
 * 登录状态拦截器RedisSessionInterceptor
18
 */
19
public class RedisSessionInterceptor implements HandlerInterceptor {
20

21
    @Autowired
22
    private RedisUtil redisUtil;
23

24
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
25
			throws Exception {
26
		// 无论访问的地址是不是正确的,都进行登录验证,登录成功后的访问再进行分发,404的访问自然会进入到错误控制器中
27
		if (redisUtil.getSessionId(request) != null) {
28
			try {
29
				// 验证当前请求的session是否是已登录的session
30
				String loginSessionId = (String) redisUtil.getRedisSessionId(request);
31
				System.out.println("用户已登录,sessionId为: " + loginSessionId);
32
				if (redisUtil.isValidSession(request)) {
33
					return true;
34
				}
35
			} catch (Exception e) {
36
				e.printStackTrace();
37
			}
38
		}
39
		throw new IpuException("404-用户未登录!");
40
	}
41

42
	
43
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
44
			ModelAndView modelAndView) throws Exception {
45
        
46
	}
47

48
	@Override
49
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
50
			throws Exception {
51

52
	}
53
	
54
}

+ 26 - 0
ipu-rest-scaffold/src/main/java/com/ai/ipu/server/config/WebSecurityConfig.java

@ -0,0 +1,26 @@
1
package com.ai.ipu.server.config;
2

3
import org.springframework.context.annotation.Bean;
4
import org.springframework.context.annotation.Configuration;
5
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
6
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
7

8
/**
9
 * Session配置拦截器
10
 */
11
@Configuration
12
public class WebSecurityConfig extends WebMvcConfigurerAdapter {
13

14
    @Bean
15
	public RedisSessionInterceptor getSessionInterceptor() {
16
		return new RedisSessionInterceptor();
17
	}
18
    
19
	public void addInterceptors(InterceptorRegistry registry) {
20
		// 所有已api开头的访问都要进入RedisSessionInterceptor拦截器进行登录验证,并排除login接口(全路径)。必须写成链式,分别设置的话会创建多个拦截器。
21
		// 必须写成getSessionInterceptor(),否则SessionInterceptor中的@Autowired会无效
22
		registry.addInterceptor(getSessionInterceptor()).addPathPatterns("/**").excludePathPatterns("/login");
23
		super.addInterceptors(registry);
24
	}
25

26
}

+ 9 - 1
ipu-rest-scaffold/src/main/java/com/ai/ipu/server/control/AuthController.java

@ -1,5 +1,7 @@
1 1
package com.ai.ipu.server.control;
2 2
3
import javax.servlet.http.HttpServletRequest;
4
3 5
import org.slf4j.Logger;
4 6
import org.slf4j.LoggerFactory;
5 7
import org.springframework.beans.factory.annotation.Autowired;
@ -12,6 +14,7 @@ import com.ai.ipu.data.impl.JsonMap;
12 14
import com.ai.ipu.server.handler.AuthHandler;
13 15
import com.ai.ipu.server.handler.HandlerManager;
14 16
import com.ai.ipu.server.service.AuthService;
17
import com.ai.ipu.server.util.RedisUtil;
15 18
16 19
@Controller
17 20
public class AuthController {
@ -20,7 +23,10 @@ public class AuthController {
20 23
    /**自动实例化AuthServiceImpl*/
21 24
    @Autowired
22 25
    private AuthService authService;
23
    
26
    @Autowired
27
    private HttpServletRequest request;
28
    @Autowired
29
    private RedisUtil redisUtil;
24 30
    /**
25 31
     * 登录
26 32
     * @param input
@ -37,6 +43,8 @@ public class AuthController {
37 43
        JMap result = new JsonMap();
38 44
        if(authService.login(username, password)){
39 45
            result.put("msg", "校验成功");
46
            String sessionId = "12345678";
47
            redisUtil.saveSessionId(request, sessionId);
40 48
        }else{
41 49
            AuthHandler handler = HandlerManager.takeAuthHandler();
42 50
            result.put("msg", handler.authFailMessage(username));

+ 107 - 0
ipu-rest-scaffold/src/main/java/com/ai/ipu/server/util/RedisOperUtil.java

@ -0,0 +1,107 @@
1
package com.ai.ipu.server.util;
2

3

4
import java.util.concurrent.TimeUnit;
5

6
import org.springframework.beans.factory.annotation.Autowired;
7
import org.springframework.data.redis.core.StringRedisTemplate;
8
import org.springframework.stereotype.Component;
9

10
import com.ai.ipu.basic.string.StringUtil;
11
import com.ai.ipu.basic.util.IpuException;
12
import com.ai.ipu.basic.util.IpuUtility;
13

14
import com.ai.ipu.cache.ICache;
15

16
@Component
17
public class RedisOperUtil implements ICache{
18
    @Autowired
19
    private StringRedisTemplate redisTemplate;
20

21
    /**
22
     * 存
23
     */
24
    @Override
25
    public boolean put(Object key, Object value) throws Exception {
26
        boolean result = true;
27
        try{
28
            if (key instanceof String)
29
                redisTemplate.opsForValue().set(key.toString(), String.valueOf(value));
30
            else
31
            	IpuUtility.error("key只支持String,保存数据到缓存操作失败"); 
32
        }catch (NullPointerException e)
33
		{
34
			if (StringUtil.isEmpty((String)key))
35
				IpuUtility.error("由于key值为空,导致保存数据到缓存操作失败", e);
36
			IpuUtility.error("由于value值为空,导致保存数据到缓存操作失败", e);
37
			result = false;
38
		}
39
        return result;
40
    }
41

42
    /**
43
     * 取
44
     */
45
    @Override
46
    public Object get(Object key) throws Exception {      
47
        
48
        return redisTemplate.opsForValue().get(key);
49
    }
50

51
    /**
52
     * 移除
53
     */
54
    @Override
55
    public boolean remove(Object key) throws Exception {
56
        throw new IpuException("不支持删除操作");
57
    }
58

59
    /**
60
     * 清除
61
     */
62
    @Override
63
    public void clear() throws Exception {
64
        ;
65
    }
66

67
    /**
68
     * key是否存在
69
     */
70
    @Override
71
    public boolean keyExists(String key) { 	
72
        return redisTemplate.opsForValue().get(key) == null?false:true;
73
    }
74

75
    /**
76
     * 设置数据
77
     * @param key
78
     * @param value
79
     * @param timeoutSeconds
80
     * @return
81
     * @throws Exception
82
     */
83
    @Override
84
    public boolean put(Object key, Object value, int timeoutSeconds) throws Exception {
85
        boolean result = true;
86
        try {
87
            if (key instanceof String)
88
            	redisTemplate.opsForValue().set(key.toString(), String.valueOf(value), timeoutSeconds, TimeUnit.SECONDS);
89
            else
90
            	IpuUtility.error("key只支持String,保存数据到缓存操作失败"); 
91
        }catch (NullPointerException e)
92
		{
93
			if (StringUtil.isEmpty((String)key))
94
				IpuUtility.error("由于key值为空,导致保存数据到缓存操作失败", e);
95
			IpuUtility.error("由于value值为空,导致保存数据到缓存操作失败", e);
96
			result = false;
97
		}
98
        return result;
99
    }
100

101
    @Override
102
    public void close() throws Exception {
103
    	;
104
    }
105

106

107
}

+ 129 - 0
ipu-rest-scaffold/src/main/java/com/ai/ipu/server/util/RedisUtil.java

@ -0,0 +1,129 @@
1
package com.ai.ipu.server.util;
2

3
import java.util.List;
4
import java.util.Map;
5

6
import javax.servlet.http.HttpServletRequest;
7
import javax.servlet.http.HttpSession;
8

9
import org.jsoup.helper.StringUtil;
10
import org.springframework.beans.factory.annotation.Autowired;
11
import org.springframework.stereotype.Component;
12

13
import com.ai.ipu.basic.util.IpuException;
14
import com.ai.ipu.cache.CacheFactory;
15
import com.ai.ipu.cache.config.IpuCacheConfig;
16
import com.ai.ipu.cache.util.IpuCacheConstant;
17

18
@Component
19
public class RedisUtil{    
20
    private static final String DEFAULT_CACHE_NAME = "ssn";
21
    @Autowired
22
    private RedisOperUtil redis;
23
    
24
	public static String[] initRedis(String[] args) throws Exception {
25
		//将ipu-cache配置作为springboot配置
26
		String[] argv = new String[args.length+9];
27
        String cacheName = DEFAULT_CACHE_NAME;
28
		int i=0;		
29
		for (String arg : args) {
30
			if (arg.contains("--redis.cache.name")&&arg.contains("=")) {
31
				cacheName = arg.substring(arg.indexOf("=")+1);
32
				argv[i++] = " ";
33
			}
34
			else
35
				argv[i++] = arg;
36
		}
37
		String cacheType = IpuCacheConfig.getCacheType(cacheName);
38
		if (!CacheFactory.DEFAULT_CACHE_TYPE.endsWith(cacheType))
39
			throw new IpuException("只支持redis保存spring session信息!请检查ipu-cache.xml里的type");
40
		
41
		String jedisType = IpuCacheConfig.getCacheDefaultAttr(cacheName,
42
                IpuCacheConstant.Redis.CLIENT_TYPE, IpuCacheConstant.ClientType.JEDIS_CLIENT);
43
		
44
		argv[i++] = "--spring.session.store-type="+CacheFactory.DEFAULT_CACHE_TYPE;
45
		List<Map<String,String>> clusterList = IpuCacheConfig.getCacheServers(cacheName);
46
        if (null == clusterList || clusterList.isEmpty())
47
            throw new IllegalArgumentException("请确认ipu-cache.xml里server是否配置正确");
48
        
49
		if (IpuCacheConstant.ClientType.JEDIS_CLIENT.equalsIgnoreCase(jedisType))
50
        {
51
        	//只取第一个redis地址
52
            Map<String, String> server = clusterList.get(0);
53
        	argv[i++] = "--spring.redis.database=0";
54
        	argv[i++] = "--spring.redis.host=" + server.get(IpuCacheConstant.Redis.IP);
55
        	argv[i++] = "--spring.redis.port=" + server.get(IpuCacheConstant.Redis.PORT);
56
        }
57
        else
58
        {
59
        	//拼集群节点
60
        	StringBuffer nodes = new StringBuffer();
61
        	Map<String, String> server;
62
        	int j=0;
63
            for (; j < clusterList.size(); j++) {
64
                server = clusterList.get(j);
65
                if (j == clusterList.size()-1)
66
                    nodes.append(server.get(IpuCacheConstant.Redis.IP)).append(":").append(server.get(IpuCacheConstant.Redis.PORT));
67
                else
68
                	nodes.append(server.get(IpuCacheConstant.Redis.IP)).append(":").append(server.get(IpuCacheConstant.Redis.PORT)).append(",");
69
            }
70
    		argv[i++] = "--spring.redis.cluster.nodes=" + nodes.toString();
71
    		argv[i++] = "--spring.redis.cluster.timeout=5";
72
    		argv[i++] = "--spring.redis.cluster.max-redirects=3";
73
        }
74

75
		//设置访问密码
76
		String auth = IpuCacheConfig.getCacheAttr(cacheName, IpuCacheConstant.Redis.AUTH);
77
        if (StringUtil.isBlank(auth))
78
        	argv[i++] = "--spring.redis.password= ";
79
        else
80
        	argv[i++] = "--spring.redis.password=" + auth;
81
        
82
        //设置连接池参数
83
        int poolSize = IpuCacheConstant.RedisConstant.DEFAULT_POOL_SIZE;
84
        int maxIdle  = IpuCacheConstant.RedisConstant.DEFAULT_MAX_IDLE;
85
        int minIdle  = IpuCacheConstant.RedisConstant.DEFAULT_MIN_IDLE;
86
        
87
        String strPoolSize = IpuCacheConfig.getCacheAttr(cacheName, IpuCacheConstant.Redis.POOL_SIZE);
88
        String strMaxIdle = IpuCacheConfig.getCacheAttr(cacheName, IpuCacheConstant.Redis.MAX_IDLE);
89
        String strMinIdle = IpuCacheConfig.getCacheAttr(cacheName, IpuCacheConstant.Redis.MIN_IDLE);        
90
        if(!StringUtil.isBlank(strPoolSize)){
91
            poolSize = Integer.parseInt(strPoolSize);
92
        }
93
        if (!StringUtil.isBlank(strMaxIdle)){
94
            maxIdle = Integer.parseInt(strMaxIdle);
95
        }
96
        if (!StringUtil.isBlank(strMinIdle)){
97
            minIdle = Integer.parseInt(strMinIdle);
98
        }
99
		argv[i++] = "--spring.redis.pool.max-active=" + poolSize;
100
		argv[i++] = "--spring.redis.pool.max-idle=" + maxIdle;
101
		argv[i++] = "--spring.redis.pool.max-wait=-1";
102
		argv[i++] = "--spring.redis.pool.min-idle=" + minIdle;
103

104
        return argv;        
105
	}
106
	
107
	public Object getSessionId(HttpServletRequest request) {
108
		HttpSession session = request.getSession();
109
		return session.getAttribute("loginSessionId");
110
	}	
111
	
112
	public void saveSessionId(HttpServletRequest request, Object sessionId) throws Exception {
113
		HttpSession session = request.getSession();
114
		session.setAttribute("loginSessionId", sessionId);
115
		redis.put("loginUser:"+sessionId, session.getId());
116
	}	
117
	
118
	public Object getRedisSessionId(HttpServletRequest request) throws Exception {
119
		String sessionId = (String)getSessionId(request);
120
		return redis.get("loginUser:"+sessionId);
121
	}	
122
	
123
	public boolean isValidSession(HttpServletRequest request) throws Exception {
124
		HttpSession session = request.getSession();
125
		String sessionId = (String)getSessionId(request);
126
		String redisSessionId = (String)redis.get("loginUser:"+sessionId);
127
		return session.getId().equals(redisSessionId)?true:false;
128
	}
129
}