1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codelibs.fess.sso.spnego;
17
18 import java.io.File;
19 import java.util.Enumeration;
20
21 import javax.annotation.PostConstruct;
22 import javax.servlet.FilterConfig;
23 import javax.servlet.ServletContext;
24 import javax.servlet.http.HttpServletResponse;
25
26 import org.codelibs.core.io.ResourceUtil;
27 import org.codelibs.fess.app.web.base.login.ActionResponseCredential;
28 import org.codelibs.fess.app.web.base.login.SpnegoCredential;
29 import org.codelibs.fess.exception.FessSystemException;
30 import org.codelibs.fess.exception.SsoLoginException;
31 import org.codelibs.fess.mylasta.direction.FessConfig;
32 import org.codelibs.fess.sso.SsoAuthenticator;
33 import org.codelibs.fess.util.ComponentUtil;
34 import org.codelibs.spnego.SpnegoFilterConfig;
35 import org.codelibs.spnego.SpnegoHttpFilter;
36 import org.codelibs.spnego.SpnegoHttpFilter.Constants;
37 import org.codelibs.spnego.SpnegoHttpServletResponse;
38 import org.codelibs.spnego.SpnegoPrincipal;
39 import org.lastaflute.web.login.credential.LoginCredential;
40 import org.lastaflute.web.servlet.filter.RequestLoggingFilter;
41 import org.lastaflute.web.util.LaRequestUtil;
42 import org.lastaflute.web.util.LaResponseUtil;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46 public class SpnegoAuthenticator implements SsoAuthenticator {
47 private static final Logger logger = LoggerFactory.getLogger(SpnegoAuthenticator.class);
48
49 protected org.codelibs.spnego.SpnegoAuthenticator authenticator = null;
50
51 @PostConstruct
52 public void init() {
53 if ("spnego".equals(ComponentUtil.getFessConfig().getSsoType())) {
54 try {
55
56 final SpnegoFilterConfig config = SpnegoFilterConfig.getInstance(new SpengoConfig());
57
58
59 authenticator = new org.codelibs.spnego.SpnegoAuthenticator(config);
60 } catch (final Exception e) {
61 throw new FessSystemException("Failed to initialize SPNEGO.", e);
62 }
63 }
64 }
65
66
67
68
69 @Override
70 public LoginCredential getLoginCredential() {
71 return LaRequestUtil
72 .getOptionalRequest()
73 .map(request -> {
74 final HttpServletResponse response = LaResponseUtil.getResponse();
75 final SpnegoHttpServletResponse spnegoResponse = new SpnegoHttpServletResponse(response);
76
77
78 final SpnegoPrincipal principal;
79 try {
80 principal = authenticator.authenticate(request, spnegoResponse);
81 } catch (final Exception e) {
82 final String msg = "HTTP Authorization Header=" + request.getHeader(Constants.AUTHZ_HEADER);
83 logger.error(msg);
84 throw new SsoLoginException(msg, e);
85 }
86
87
88 if (spnegoResponse.isStatusSet()) {
89 return new ActionResponseCredential(() -> {
90 throw new RequestLoggingFilter.RequestClientErrorException("Your request is not authorized.",
91 "401 Unauthorized", HttpServletResponse.SC_UNAUTHORIZED);
92 });
93 }
94
95
96 if (null == principal) {
97 final String msg = "Principal was null.";
98 logger.error(msg);
99 throw new SsoLoginException(msg);
100 }
101
102 if (logger.isDebugEnabled()) {
103 logger.debug("principal=" + principal);
104 }
105
106 final String[] username = principal.getName().split("@", 2);
107 return new SpnegoCredential(username[0]);
108 }).orElseGet(() -> null);
109
110 }
111
112 protected class SpengoConfig implements FilterConfig {
113
114 protected FessConfig fessConfig = ComponentUtil.getFessConfig();
115
116 @Override
117 public String getFilterName() {
118 return SpnegoAuthenticator.class.getName();
119 }
120
121 @Override
122 public ServletContext getServletContext() {
123 throw new UnsupportedOperationException();
124 }
125
126 @Override
127 public String getInitParameter(final String name) {
128 if (SpnegoHttpFilter.Constants.LOGGER_LEVEL.equals(name)) {
129 return fessConfig.getSpnegoLoggerLevel();
130 } else if (SpnegoHttpFilter.Constants.LOGIN_CONF.equals(name)) {
131 return getResourcePath(fessConfig.getSpnegoLoginConf());
132 } else if (SpnegoHttpFilter.Constants.KRB5_CONF.equals(name)) {
133 return getResourcePath(fessConfig.getSpnegoKrb5Conf());
134 } else if (SpnegoHttpFilter.Constants.CLIENT_MODULE.equals(name)) {
135 return fessConfig.getSpnegoLoginClientModule();
136 } else if (SpnegoHttpFilter.Constants.SERVER_MODULE.equals(name)) {
137 return fessConfig.getSpnegoLoginServerModule();
138 } else if (SpnegoHttpFilter.Constants.PREAUTH_USERNAME.equals(name)) {
139 return fessConfig.getSpnegoPreauthUsername();
140 } else if (SpnegoHttpFilter.Constants.PREAUTH_PASSWORD.equals(name)) {
141 return fessConfig.getSpnegoPreauthPassword();
142 } else if (SpnegoHttpFilter.Constants.ALLOW_BASIC.equals(name)) {
143 return fessConfig.getSpnegoAllowBasic();
144 } else if (SpnegoHttpFilter.Constants.ALLOW_UNSEC_BASIC.equals(name)) {
145 return fessConfig.getSpnegoAllowUnsecureBasic();
146 } else if (SpnegoHttpFilter.Constants.PROMPT_NTLM.equals(name)) {
147 return fessConfig.getSpnegoPromptNtlm();
148 } else if (SpnegoHttpFilter.Constants.ALLOW_LOCALHOST.equals(name)) {
149 return fessConfig.getSpnegoAllowLocalhost();
150 } else if (SpnegoHttpFilter.Constants.ALLOW_DELEGATION.equals(name)) {
151 return fessConfig.getSpnegoAllowDelegation();
152 }
153 return null;
154 }
155
156 protected String getResourcePath(final String path) {
157 final File file = ResourceUtil.getResourceAsFileNoException(path);
158 if (file != null) {
159 return file.getAbsolutePath();
160 }
161 return null;
162 }
163
164 @Override
165 public Enumeration<String> getInitParameterNames() {
166 throw new UnsupportedOperationException();
167 }
168
169 }
170 }