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