View Javadoc
1   /*
2    * SPDX-License-Identifier: MIT
3    * See LICENSE file for details.
4    *
5    * Copyright 2010-2026 The Waffle Project Contributors: https://github.com/Waffle/waffle/graphs/contributors
6    */
7   package waffle.spring;
8   
9   import com.sun.jna.platform.win32.Win32Exception;
10  
11  import java.util.Locale;
12  
13  import org.slf4j.Logger;
14  import org.slf4j.LoggerFactory;
15  import org.springframework.security.authentication.AuthenticationProvider;
16  import org.springframework.security.authentication.AuthenticationServiceException;
17  import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
18  import org.springframework.security.core.Authentication;
19  import org.springframework.security.core.GrantedAuthority;
20  
21  import waffle.servlet.WindowsPrincipal;
22  import waffle.windows.auth.IWindowsAuthProvider;
23  import waffle.windows.auth.IWindowsIdentity;
24  import waffle.windows.auth.PrincipalFormat;
25  
26  /**
27   * A Waffle authentication provider for Spring-security.
28   */
29  public class WindowsAuthenticationProvider implements AuthenticationProvider {
30  
31      /** The Constant LOGGER. */
32      private static final Logger LOGGER = LoggerFactory.getLogger(WindowsAuthenticationProvider.class);
33  
34      /** The principal format. */
35      private PrincipalFormat principalFormat = PrincipalFormat.FQN;
36  
37      /** The role format. */
38      private PrincipalFormat roleFormat = PrincipalFormat.FQN;
39  
40      /** The allow guest login. */
41      private boolean allowGuestLogin = true;
42  
43      /** The auth provider. */
44      private IWindowsAuthProvider authProvider;
45  
46      /** The granted authority factory. */
47      private GrantedAuthorityFactory grantedAuthorityFactory = WindowsAuthenticationToken.DEFAULT_GRANTED_AUTHORITY_FACTORY;
48  
49      /** The default granted authority. */
50      private GrantedAuthority defaultGrantedAuthority = WindowsAuthenticationToken.DEFAULT_GRANTED_AUTHORITY;
51  
52      /**
53       * Instantiates a new windows authentication provider.
54       */
55      public WindowsAuthenticationProvider() {
56          WindowsAuthenticationProvider.LOGGER.debug("[waffle.spring.WindowsAuthenticationProvider] loaded");
57      }
58  
59      @Override
60      public Authentication authenticate(final Authentication authentication) {
61          final UsernamePasswordAuthenticationToken auth = (UsernamePasswordAuthenticationToken) authentication;
62          IWindowsIdentity windowsIdentity;
63          try {
64              windowsIdentity = this.authProvider.logonUser(auth.getName(), auth.getCredentials().toString());
65          } catch (final Win32Exception e) {
66              throw new AuthenticationServiceException(e.getMessage(), e);
67          }
68          WindowsAuthenticationProvider.LOGGER.debug("logged in user: {} ({})", windowsIdentity.getFqn(),
69                  windowsIdentity.getSidString());
70  
71          if (!this.allowGuestLogin && windowsIdentity.isGuest()) {
72              WindowsAuthenticationProvider.LOGGER.warn("guest login disabled: {}", windowsIdentity.getFqn());
73              throw new GuestLoginDisabledAuthenticationException(windowsIdentity.getFqn());
74          }
75  
76          final WindowsPrincipal windowsPrincipal = new WindowsPrincipal(windowsIdentity, this.principalFormat,
77                  this.roleFormat);
78          WindowsAuthenticationProvider.LOGGER.debug("roles: {}", windowsPrincipal.getRolesString());
79  
80          final WindowsAuthenticationToken token = new WindowsAuthenticationToken(windowsPrincipal,
81                  this.grantedAuthorityFactory, this.defaultGrantedAuthority);
82  
83          WindowsAuthenticationProvider.LOGGER.info("successfully logged in user: {}", windowsIdentity.getFqn());
84          return token;
85      }
86  
87      /**
88       * Supports.
89       *
90       * @param authentication
91       *            the authentication
92       *
93       * @return true, if successful
94       */
95      @Override
96      public boolean supports(final Class<? extends Object> authentication) {
97          return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
98      }
99  
100     /**
101      * Gets the principal format.
102      *
103      * @return the principal format
104      */
105     public PrincipalFormat getPrincipalFormat() {
106         return this.principalFormat;
107     }
108 
109     /**
110      * Sets the principal format enum.
111      *
112      * @param value
113      *            the new principal format enum
114      */
115     public void setPrincipalFormatEnum(final PrincipalFormat value) {
116         this.principalFormat = value;
117     }
118 
119     /**
120      * Sets the principal format.
121      *
122      * @param value
123      *            the new principal format
124      */
125     public void setPrincipalFormat(final String value) {
126         this.setPrincipalFormatEnum(PrincipalFormat.valueOf(value.toUpperCase(Locale.ENGLISH)));
127     }
128 
129     /**
130      * Gets the role format.
131      *
132      * @return the role format
133      */
134     public PrincipalFormat getRoleFormat() {
135         return this.roleFormat;
136     }
137 
138     /**
139      * Sets the role format enum.
140      *
141      * @param value
142      *            the new role format enum
143      */
144     public void setRoleFormatEnum(final PrincipalFormat value) {
145         this.roleFormat = value;
146     }
147 
148     /**
149      * Sets the role format.
150      *
151      * @param value
152      *            the new role format
153      */
154     public void setRoleFormat(final String value) {
155         this.setRoleFormatEnum(PrincipalFormat.valueOf(value.toUpperCase(Locale.ENGLISH)));
156     }
157 
158     /**
159      * Checks if is allow guest login.
160      *
161      * @return true, if is allow guest login
162      */
163     public boolean isAllowGuestLogin() {
164         return this.allowGuestLogin;
165     }
166 
167     /**
168      * Sets the allow guest login.
169      *
170      * @param value
171      *            the new allow guest login
172      */
173     public void setAllowGuestLogin(final boolean value) {
174         this.allowGuestLogin = value;
175     }
176 
177     /**
178      * Gets the auth provider.
179      *
180      * @return the auth provider
181      */
182     public IWindowsAuthProvider getAuthProvider() {
183         return this.authProvider;
184     }
185 
186     /**
187      * Sets the auth provider.
188      *
189      * @param value
190      *            the new auth provider
191      */
192     public void setAuthProvider(final IWindowsAuthProvider value) {
193         this.authProvider = value;
194     }
195 
196     /**
197      * Gets the granted authority factory.
198      *
199      * @return the granted authority factory
200      */
201     public GrantedAuthorityFactory getGrantedAuthorityFactory() {
202         return this.grantedAuthorityFactory;
203     }
204 
205     /**
206      * Sets the granted authority factory.
207      *
208      * @param value
209      *            the new granted authority factory
210      */
211     public void setGrantedAuthorityFactory(final GrantedAuthorityFactory value) {
212         this.grantedAuthorityFactory = value;
213     }
214 
215     /**
216      * Gets the default granted authority.
217      *
218      * @return the default granted authority
219      */
220     public GrantedAuthority getDefaultGrantedAuthority() {
221         return this.defaultGrantedAuthority;
222     }
223 
224     /**
225      * Sets the default granted authority.
226      *
227      * @param value
228      *            the new default granted authority
229      */
230     public void setDefaultGrantedAuthority(final GrantedAuthority value) {
231         this.defaultGrantedAuthority = value;
232     }
233 }