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