1
2
3
4
5
6
7
8
9
10
11
12
13
14 package waffle.shiro;
15
16 import org.apache.shiro.authc.AuthenticationException;
17 import org.apache.shiro.authc.AuthenticationInfo;
18 import org.apache.shiro.authc.AuthenticationToken;
19 import org.apache.shiro.authc.SimpleAuthenticationInfo;
20 import org.apache.shiro.authc.UsernamePasswordToken;
21 import org.apache.shiro.authc.credential.CredentialsMatcher;
22 import org.apache.shiro.authc.credential.HashingPasswordService;
23 import org.apache.shiro.authc.credential.PasswordMatcher;
24 import org.apache.shiro.authc.credential.PasswordService;
25 import org.apache.shiro.authz.AuthorizationInfo;
26 import org.apache.shiro.crypto.hash.Hash;
27 import org.apache.shiro.realm.AuthorizingRealm;
28 import org.apache.shiro.subject.PrincipalCollection;
29 import org.apache.shiro.util.ByteSource;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 import waffle.windows.auth.IWindowsAuthProvider;
34 import waffle.windows.auth.IWindowsIdentity;
35 import waffle.windows.auth.impl.WindowsAuthProviderImpl;
36
37
38
39
40
41 public abstract class AbstractWaffleRealm extends AuthorizingRealm {
42
43
44 private static final Logger LOGGER = LoggerFactory.getLogger(AbstractWaffleRealm.class);
45
46
47 private static final String REALM_NAME = "WAFFLE";
48
49
50 private IWindowsAuthProvider provider = new WindowsAuthProviderImpl();
51
52
53
54
55 @Override
56 protected final AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken authToken) {
57 AuthenticationInfo authenticationInfo = null;
58 if (authToken instanceof UsernamePasswordToken) {
59 final UsernamePasswordToken token = (UsernamePasswordToken) authToken;
60 final String username = token.getUsername();
61 IWindowsIdentity identity = null;
62 try {
63 AbstractWaffleRealm.LOGGER.debug("Attempting login for user {}", username);
64 identity = this.provider.logonUser(username, new String(token.getPassword()));
65 if (identity.isGuest()) {
66 AbstractWaffleRealm.LOGGER.debug("Guest identity for user {}; denying access", username);
67 throw new AuthenticationException("Guest identities are not allowed access");
68 }
69 final Object principal = new WaffleFqnPrincipal(identity);
70 authenticationInfo = this.buildAuthenticationInfo(token, principal);
71 AbstractWaffleRealm.LOGGER.debug("Successful login for user {}", username);
72 } catch (final RuntimeException e) {
73 AbstractWaffleRealm.LOGGER.debug("Failed login for user {}: {}", username, e.getMessage());
74 AbstractWaffleRealm.LOGGER.trace("{}", e);
75 throw new AuthenticationException("Login failed", e);
76 } finally {
77 if (identity != null) {
78 identity.dispose();
79 }
80 }
81 }
82 return authenticationInfo;
83 }
84
85
86
87
88
89
90
91
92
93
94 private AuthenticationInfo buildAuthenticationInfo(final UsernamePasswordToken token, final Object principal) {
95 AuthenticationInfo authenticationInfo;
96 final HashingPasswordService hashService = this.getHashService();
97 if (hashService != null) {
98 final Hash hash = hashService.hashPassword(token.getPassword());
99 final ByteSource salt = hash.getSalt();
100 authenticationInfo = new SimpleAuthenticationInfo(principal, hash, salt, AbstractWaffleRealm.REALM_NAME);
101 } else {
102 final Object creds = token.getCredentials();
103 authenticationInfo = new SimpleAuthenticationInfo(principal, creds, AbstractWaffleRealm.REALM_NAME);
104 }
105 return authenticationInfo;
106 }
107
108
109
110
111 @Override
112 protected final AuthorizationInfo doGetAuthorizationInfo(final PrincipalCollection principals) {
113 final WaffleFqnPrincipal principal = principals.oneByType(WaffleFqnPrincipal.class);
114 return principal == null ? null : this.buildAuthorizationInfo(principal);
115 }
116
117
118
119
120
121
122
123
124 protected abstract AuthorizationInfo buildAuthorizationInfo(final WaffleFqnPrincipal principal);
125
126
127
128
129
130
131
132
133 void setProvider(final IWindowsAuthProvider value) {
134 this.provider = value;
135 }
136
137
138
139
140
141
142 private HashingPasswordService getHashService() {
143 final CredentialsMatcher matcher = this.getCredentialsMatcher();
144 if (matcher instanceof PasswordMatcher) {
145 final PasswordMatcher passwordMatcher = (PasswordMatcher) matcher;
146 final PasswordService passwordService = passwordMatcher.getPasswordService();
147 if (passwordService instanceof HashingPasswordService) {
148 return (HashingPasswordService) passwordService;
149 }
150 }
151 return null;
152 }
153 }