1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package waffle.shiro.negotiate;
25
26 import java.security.Principal;
27
28
29
30
31
32
33
34
35
36
37
38
39 import javax.security.auth.Subject;
40
41 import org.apache.shiro.authc.AuthenticationException;
42 import org.apache.shiro.authc.AuthenticationInfo;
43 import org.apache.shiro.authc.AuthenticationToken;
44 import org.apache.shiro.realm.AuthenticatingRealm;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 import waffle.servlet.WindowsPrincipal;
49 import waffle.windows.auth.IWindowsAuthProvider;
50 import waffle.windows.auth.IWindowsIdentity;
51 import waffle.windows.auth.IWindowsSecurityContext;
52 import waffle.windows.auth.impl.WindowsAuthProviderImpl;
53
54
55
56
57 public class NegotiateAuthenticationRealm extends AuthenticatingRealm {
58
59
60
61
62 private static final Logger LOGGER = LoggerFactory.getLogger(NegotiateAuthenticationRealm.class);
63
64
65 private final IWindowsAuthProvider windowsAuthProvider;
66
67
68
69
70 public NegotiateAuthenticationRealm() {
71 this.windowsAuthProvider = new WindowsAuthProviderImpl();
72 }
73
74 @Override
75 public boolean supports(final AuthenticationToken token) {
76 return token instanceof NegotiateToken;
77 }
78
79 @Override
80 protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken t) {
81
82 final NegotiateToken token = (NegotiateToken) t;
83 final byte[] inToken = token.getIn();
84
85 if (token.isNtlmPost()) {
86
87 this.windowsAuthProvider.resetSecurityToken(token.getConnectionId());
88 }
89
90 final IWindowsSecurityContext securityContext;
91 try {
92 securityContext = this.windowsAuthProvider.acceptSecurityToken(token.getConnectionId(), inToken,
93 token.getSecurityPackage());
94 } catch (final Exception e) {
95 NegotiateAuthenticationRealm.LOGGER.warn("error logging in user");
96 throw new AuthenticationException(e);
97 }
98
99 final byte[] continueTokenBytes = securityContext.getToken();
100 token.setOut(continueTokenBytes);
101 if (continueTokenBytes != null) {
102 NegotiateAuthenticationRealm.LOGGER.debug("continue token bytes: {}",
103 Integer.valueOf(continueTokenBytes.length));
104 } else {
105 NegotiateAuthenticationRealm.LOGGER.debug("no continue token bytes");
106 }
107
108 if (securityContext.isContinue() || token.isNtlmPost()) {
109 throw new AuthenticationInProgressException();
110 }
111
112 final IWindowsIdentity windowsIdentity = securityContext.getIdentity();
113 securityContext.dispose();
114
115 NegotiateAuthenticationRealm.LOGGER.debug("logged in user: {} ({})", windowsIdentity.getFqn(),
116 windowsIdentity.getSidString());
117
118 final Principal principal = new WindowsPrincipal(windowsIdentity);
119 token.setPrincipal(principal);
120
121 final Subject subject = new Subject();
122 subject.getPrincipals().add(principal);
123 token.setSubject(subject);
124
125 return token.createInfo();
126 }
127
128 }