xml配置:
1 <bean id="dataSource"
2 class="org.springframework.jdbc.datasource.DriverManagerDataSource">
3 <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
4 <property name="url" value="jdbc:oracle:thin:@xxx.xxx.xxx.xxx:1521:orcl" />
5 <property name="username" value="cba" />
6 <property name="password" value="***" />
7 </bean>
在weblogic/jboss中配置好JNDI数据源后,上述节点改为:
1 <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
2 <property name="jndiName">
3 <value>java:/ssoDS</value>
4 </property>
5 </bean>
其中:第3行的java:/ssoDS即为web容器中配置好的jndi数据源名称
其它地方不用任何修改,使用示例如下:
1 <beans:bean id="userDetailsDao" class="infosky.ckg.sso.dao.impl.UserDetailsDaoImpl">
2 <beans:property name="dataSource" ref="dataSource" />
3 <!-- 登录错误尝试次数 -->
4 <beans:property name="maxAttempts" value="5" />
5 </beans:bean>
UserDetailsDao接口如下:
1 package infosky.ckg.sso.dao;
2
3 import infosky.ckg.sso.model.UserAttempts;
4
5 public interface UserDetailsDao {
6
7 void updateFailAttempts(String username);
8
9 void resetFailAttempts(String username);
10
11 UserAttempts getUserAttempts(String username);
12
13 }
对应的实现类:
1 package infosky.ckg.sso.dao.impl;
2
3 import infosky.ckg.sso.dao.UserDetailsDao;
4 import infosky.ckg.sso.model.UserAttempts;
5
6 import java.sql.ResultSet;
7 import java.sql.SQLException;
8 import java.util.Date;
9
10 import javax.annotation.PostConstruct;
11 import javax.sql.DataSource;
12
13 import org.springframework.beans.factory.annotation.Autowired;
14 import org.springframework.dao.EmptyResultDataAccessException;
15 import org.springframework.jdbc.core.RowMapper;
16 import org.springframework.jdbc.core.support.JdbcDaoSupport;
17 import org.springframework.stereotype.Repository;
18 import org.springframework.security.authentication.LockedException;
19
20 @Repository
21 public class UserDetailsDaoImpl extends JdbcDaoSupport implements
22 UserDetailsDao {
23
24 private static final String SQL_USERS_UPDATE_LOCKED = "UPDATE t_users SET d_accountnonlocked = ? WHERE d_username = ?";
25 private static final String SQL_USERS_COUNT = "SELECT COUNT(*) FROM t_users WHERE d_username = ?";
26
27 private static final String SQL_USER_ATTEMPTS_GET = "SELECT d_username username,d_attempts attempts,d_lastmodified lastmodified FROM t_user_attempts WHERE d_username = ?";
28 private static final String SQL_USER_ATTEMPTS_INSERT = "INSERT INTO t_user_attempts (d_username, d_attempts, d_lastmodified) VALUES(?,?,?)";
29 private static final String SQL_USER_ATTEMPTS_UPDATE_ATTEMPTS = "UPDATE t_user_attempts SET d_attempts = d_attempts + 1, d_lastmodified = ? WHERE d_username = ?";
30 private static final String SQL_USER_ATTEMPTS_RESET_ATTEMPTS = "UPDATE t_user_attempts SET d_attempts = 0, d_lastmodified = null WHERE d_username = ?";
31
32 private int maxAttempts = 3;
33
34 @Autowired
35 private DataSource dataSource;
36
37 @PostConstruct
38 private void initialize() {
39 setDataSource(dataSource);
40 }
41
42 @Override
43 public void updateFailAttempts(String username) {
44 UserAttempts user = getUserAttempts(username);
45 if (user == null) {
46 if (isUserExists(username)) {
47 // if no record, insert a new
48 getJdbcTemplate().update(SQL_USER_ATTEMPTS_INSERT,
49 new Object[] { username, 1, new Date() });
50 }
51 } else {
52
53 if (isUserExists(username)) {
54 // update attempts count, +1
55 getJdbcTemplate().update(SQL_USER_ATTEMPTS_UPDATE_ATTEMPTS,
56 new Object[] { new Date(), username });
57 }
58
59 if (user.getAttempts() + 1 >= maxAttempts) {
60 // locked user
61 getJdbcTemplate().update(SQL_USERS_UPDATE_LOCKED,
62 new Object[] { false, username });
63 // throw exception
64 throw new LockedException("登录错误次数太多,该用户已被锁定!");
65 }
66
67 }
68 }
69
70 @Override
71 public void resetFailAttempts(String username) {
72 getJdbcTemplate().update(SQL_USER_ATTEMPTS_RESET_ATTEMPTS,
73 new Object[] { username });
74
75 }
76
77 @Override
78 public UserAttempts getUserAttempts(String username) {
79 try {
80
81 UserAttempts userAttempts = getJdbcTemplate().queryForObject(
82 SQL_USER_ATTEMPTS_GET, new Object[] { username },
83 new RowMapper<UserAttempts>() {
84 public UserAttempts mapRow(ResultSet rs, int rowNum)
85 throws SQLException {
86
87 UserAttempts user = new UserAttempts();
88 user.setUsername(rs.getString("username"));
89 user.setAttempts(rs.getInt("attempts"));
90 user.setLastModified(rs.getDate("lastModified"));
91
92 return user;
93 }
94
95 });
96 return userAttempts;
97
98 } catch (EmptyResultDataAccessException e) {
99 return null;
100 }
101
102 }
103
104 private boolean isUserExists(String username) {
105
106 boolean result = false;
107
108 int count = getJdbcTemplate().queryForObject(SQL_USERS_COUNT,
109 new Object[] { username }, Integer.class);
110 if (count > 0) {
111 result = true;
112 }
113
114 return result;
115 }
116
117 public int getMaxAttempts() {
118 return maxAttempts;
119 }
120
121 public void setMaxAttempts(int maxAttempts) {
122 this.maxAttempts = maxAttempts;
123 }
124
125 }
注意:34,35行在运行时,系统会自动注入dataSource对象