1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
|
19 | |
package org.apache.shiro.samples.spring.realm; |
20 | |
|
21 | |
import org.apache.shiro.authc.*; |
22 | |
import org.apache.shiro.realm.jdbc.JdbcRealm; |
23 | |
import org.apache.shiro.util.ByteSource; |
24 | |
import org.apache.shiro.util.JdbcUtils; |
25 | |
import org.slf4j.Logger; |
26 | |
import org.slf4j.LoggerFactory; |
27 | |
|
28 | |
import java.sql.Connection; |
29 | |
import java.sql.PreparedStatement; |
30 | |
import java.sql.ResultSet; |
31 | |
import java.sql.SQLException; |
32 | |
|
33 | |
|
34 | |
|
35 | |
|
36 | |
|
37 | 0 | public class SaltAwareJdbcRealm extends JdbcRealm { |
38 | |
|
39 | 0 | private static final Logger log = LoggerFactory.getLogger(SaltAwareJdbcRealm.class); |
40 | |
|
41 | |
@Override |
42 | |
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { |
43 | 0 | UsernamePasswordToken upToken = (UsernamePasswordToken) token; |
44 | 0 | String username = upToken.getUsername(); |
45 | |
|
46 | |
|
47 | 0 | if (username == null) { |
48 | 0 | throw new AccountException("Null usernames are not allowed by this realm."); |
49 | |
} |
50 | |
|
51 | 0 | Connection conn = null; |
52 | 0 | AuthenticationInfo info = null; |
53 | |
try { |
54 | 0 | conn = dataSource.getConnection(); |
55 | |
|
56 | 0 | String password = getPasswordForUser(conn, username); |
57 | |
|
58 | 0 | if (password == null) { |
59 | 0 | throw new UnknownAccountException("No account found for user [" + username + "]"); |
60 | |
} |
61 | |
|
62 | 0 | SimpleAuthenticationInfo saInfo = new SimpleAuthenticationInfo(username, password, getName()); |
63 | |
|
64 | |
|
65 | |
|
66 | |
|
67 | |
|
68 | |
|
69 | 0 | saInfo.setCredentialsSalt(ByteSource.Util.bytes(username)); |
70 | |
|
71 | 0 | info = saInfo; |
72 | |
|
73 | 0 | } catch (SQLException e) { |
74 | 0 | final String message = "There was a SQL error while authenticating user [" + username + "]"; |
75 | 0 | if (log.isErrorEnabled()) { |
76 | 0 | log.error(message, e); |
77 | |
} |
78 | |
|
79 | |
|
80 | 0 | throw new AuthenticationException(message, e); |
81 | |
} finally { |
82 | 0 | JdbcUtils.closeConnection(conn); |
83 | 0 | } |
84 | |
|
85 | 0 | return info; |
86 | |
} |
87 | |
|
88 | |
private String getPasswordForUser(Connection conn, String username) throws SQLException { |
89 | |
|
90 | 0 | PreparedStatement ps = null; |
91 | 0 | ResultSet rs = null; |
92 | 0 | String password = null; |
93 | |
try { |
94 | 0 | ps = conn.prepareStatement(authenticationQuery); |
95 | 0 | ps.setString(1, username); |
96 | |
|
97 | |
|
98 | 0 | rs = ps.executeQuery(); |
99 | |
|
100 | |
|
101 | 0 | boolean foundResult = false; |
102 | 0 | while (rs.next()) { |
103 | |
|
104 | |
|
105 | 0 | if (foundResult) { |
106 | 0 | throw new AuthenticationException("More than one user row found for user [" + username + "]. Usernames must be unique."); |
107 | |
} |
108 | |
|
109 | 0 | password = rs.getString(1); |
110 | |
|
111 | 0 | foundResult = true; |
112 | |
} |
113 | |
} finally { |
114 | 0 | JdbcUtils.closeResultSet(rs); |
115 | 0 | JdbcUtils.closeStatement(ps); |
116 | 0 | } |
117 | |
|
118 | 0 | return password; |
119 | |
} |
120 | |
|
121 | |
} |