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