6

I use Spring Security with Waffle in my service. When I connect to the service locally (Browser and Tomcat are started up on the same computer), everything works very well (Browser doesn't ask login and password). When I connect to the service from another computer, Browser always asks login and password.

This is my web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee" 
         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
   http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         id="WebApp_ID" version="2.5">
    <display-name>Struts 2 Spring Security 4</display-name>

    <!--SPRING SECURITY-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring-security/context.xml
        </param-value>
    </context-param>

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter> 

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!--SPRING SECURITY--> 

    <filter>
        <filter-name>SecurityFilter</filter-name>
        <filter-class>waffle.servlet.NegotiateSecurityFilter</filter-class>
        <init-param>
            <param-name>waffle.servlet.spi.NegotiateSecurityFilterProvider/protocols</param-name>
                <param-value>
                    Negotiate
                    NTLM                    
                </param-value>
        </init-param>
    </filter>

    <filter-mapping>
      <filter-name>SecurityFilter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>  


    <!-- Struts 2-->
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>       
    </filter-mapping>    
    <!-- Struts 2-->

    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

    <listener>
        <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
    </listener>

    <!-- Struts Tiles Listener -->
    <listener>
        <listener-class>
            org.apache.struts2.tiles.StrutsTilesListener
        </listener-class>
    </listener>
    <!-- Struts Tiles Listener -->

    <listener>
        <listener-class>
            ru.dpd.vms.pss.scheduler.SchedulerListener
        </listener-class>
    </listener>

    <context-param>
        <param-name>org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG</param-name>
        <param-value>
            /WEB-INF/tiles.xml
        </param-value>
    </context-param>    

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <session-config>
        <session-timeout>120</session-timeout>
    </session-config>

</web-app>

This is Spring Context:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:sec="http://www.springframework.org/schema/security"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">

    <sec:http   auto-config="true"
                use-expressions="true" 
                request-matcher="regex"
                entry-point-ref="negotiateSecurityFilterEntryPoint" >

        <sec:csrf disabled="true"/>

        <sec:custom-filter ref="waffleNegotiateSecurityFilter" before="BASIC_AUTH_FILTER" />
        <sec:custom-filter ref="customFilter" after="BASIC_AUTH_FILTER"/>


Here is some <sec:intercept-url/> 

    </sec:http>


    <bean id="basicSecurityFilterProvider" class="waffle.servlet.spi.BasicSecurityFilterProvider">
        <constructor-arg ref="waffleWindowsAuthProvider" />
    </bean>

    <bean id="waffleSecurityFilterProviderCollection" class="waffle.servlet.spi.SecurityFilterProviderCollection">
    <constructor-arg>
        <list>
            <ref bean="negotiateSecurityFilterProvider" />
            <ref bean="basicSecurityFilterProvider" />               
        </list>
    </constructor-arg>
    </bean>

    <bean id="negotiateSecurityFilterProvider" class="waffle.servlet.spi.NegotiateSecurityFilterProvider">
        <constructor-arg ref="waffleWindowsAuthProvider" />
    </bean>

    <bean id="negotiateSecurityFilterEntryPoint" class="waffle.spring.NegotiateSecurityFilterEntryPoint">
        <property name="Provider" ref="waffleSecurityFilterProviderCollection" />
    </bean>


    <sec:authentication-manager alias="authenticationProvider">
        <sec:authentication-provider ref="waffleSpringAuthenticationProvider" />
    </sec:authentication-manager>


    <bean id="waffleWindowsAuthProvider" class="waffle.windows.auth.impl.WindowsAuthProviderImpl" />


    <bean id="waffleSpringAuthenticationProvider" class="waffle.spring.WindowsAuthenticationProvider">
        <property name="allowGuestLogin" value="false" />
        <property name="principalFormat" value="fqn" />
        <property name="roleFormat" value="both" />
        <property name="authProvider" ref="waffleWindowsAuthProvider" />

    </bean>

    <bean id="waffleNegotiateSecurityFilter" class="waffle.spring.NegotiateSecurityFilter">
        <property name="Provider" ref="waffleSecurityFilterProviderCollection" />
        <property name="AllowGuestLogin" value="false" />

        <property name="PrincipalFormat" value="fqn" />
        <property name="RoleFormat" value="both" />

    </bean>

    <bean id="customFilter" class="ru.yyy.vms.pss.ntlm.CustomFilter"></bean>
</beans>

I will really glad any advices. Thank you.

1) What happens when you cancel the login box (screenshot) enter image description here 2) What happens if you enter some (probably fake) credentials (screenshot) Site shows up in this case. I wouldn't want to publish it. 3) What shows up in the debugger's Network tab (screenshot + copied plain text) successful login

Request URL: http://yyy/wyyy/welcome.do
Request Method: GET
Status Code: 200 OK
Remote Address: 10.239.254.213:8088
Referrer Policy: no-referrer-when-downgrade
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: text/html;charset=UTF-8
Date: Wed, 07 Nov 2018 07:07:08 GMT
Expires: 0
Pragma: no-cache
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=E9CCCF0A98F62D56A43EBC383D759DE8; Path=/wyyy/; HttpOnly
Transfer-Encoding: chunked
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7
Authorization: Negotiate TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAGAvAjAAAADw==
Connection: keep-alive
Cookie: JSESSIONID=AA48EC52FF03298E8217D5A4DF9D3D73
Host: yyy
Upgrade-Insecure-Requests: 1

failed login

Request URL: http://yyy/wyyy/welcome.do
Request Method: GET
Status Code: 401 Unauthorized
Remote Address: 10.239.254.213:8088
Referrer Policy: no-referrer-when-downgrade
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: close
Content-Language: en
Content-Length: 994
Content-Type: text/html;charset=utf-8
Date: Wed, 07 Nov 2018 07:15:14 GMT
Expires: 0
Pragma: no-cache
Server: Apache-Coyote/1.1
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
WWW-Authenticate: Basic realm="BasicSecurityFilterProvider"
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7
Connection: keep-alive
Cookie: JSESSIONID=657AC285B9FF43405FADD51026088F4D
Host: yyy
Upgrade-Insecure-Requests: 1
Сергей
  • 176
  • 1
  • 12
  • Are all the computers (clients and server) in the same domain? – Progman Nov 06 '18 at 10:39
  • @Progman Yes, it is. – Сергей Nov 06 '18 at 11:27
  • What is the result when you try it with different browsers? Which browser fail and for which browsers is it working and the "login" is without the password prompt? – Progman Nov 06 '18 at 11:29
  • @Progman Result is the same with the different browsers. Google Chrome 70 and IE 11 are working without passwords (the same computer). Google Chrome 70 and IE 10 ask password at the other (different than Tomcat) computer. – Сергей Nov 06 '18 at 11:46
  • Open up browser debugger (e.g. Chrome Developer Tools -> Network tab) and see what it tells you. Remember to disable the request filter – jannis Nov 06 '18 at 11:47
  • @jannis Before browser tells me something, it asks password. And I don't understand what I can see after when I login. – Сергей Nov 06 '18 at 12:00
  • If you open the debbuger, go to the page and click cancel you'll probably be able to investigate. The other question is what do you get in the browser window when you enter something to the login box and what do you get when you click cancel. Answering these will most probably tell you where does the login request come from and answer your question. – jannis Nov 06 '18 at 12:05
  • @jannis I try to investigate my problem but I know this topic not very well. Could you help me? If I publish my Headers will you give me any recommendations? – Сергей Nov 06 '18 at 13:32
  • Just update your question with the stuff I mentioned, i.e: 1) What happens when you cancel the login box (screenshot) 2) What happens if you enter some (probably fake) credentials (screenshot) 3) What shows up in the debugger's Network tab (screenshot + copied plain text) – jannis Nov 06 '18 at 14:45
  • @jannis I posted requested information. – Сергей Nov 07 '18 at 07:30
  • Looking at the your update it seems that the server requests (using NTLM) the user to authenticate with some SSO solution (Active Directory?). Not much more can be said without knowing Waffle and it seems their docs are not that exhaustive. – jannis Nov 07 '18 at 10:03
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/183239/discussion-between--and-jannis). – Сергей Nov 07 '18 at 12:31
  • See that authentication is via NTLM based on the configuration. You may [Check this](https://sysadminspot.com/windows/google-chrome-and-ntlm-auto-logon-using-windows-authentication/) – resatz Apr 18 '19 at 08:48

1 Answers1

0

Hi You need to activate windows integrated authentication or add your site to local intranet on each computer,

https://specopssoft.com/blog/configuring-chrome-and-firefox-for-windows-integrated-authentication/

https://itkb.csulb.edu/display/help/Adding+Sites+to+Local+Intranet+in+Browser+Settings

or else you can do the below steps,

1) Install Apache Web Server and configure to use NTLM authentication using modntlm

2) Configure mod_jk to your Selvlet container (JBoss or Tomcat) http://tomcat.apache.org/connectors-doc/generic_howto/proxy.html After the successful authentication Apache sends the REMOTE_USER header to the servlet container. The header (according the name) contains a user name of the authenticated user Ensure you configure tomcatAuthentication="false" to allow Apache to allow apache to send the REMOTE_USER header

3) Implement and configure in Spring Security your own PreAuthenticatedProcessingFilter: http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#d0e6167

It should be very similar to the Request-Header Authentication filter: http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#d0e6295

In addition, you should omit a domain name from the user name. The user name is sent in the REMOTE_USER header after NTLM authentication.

Srinivasan Sekar
  • 2,049
  • 13
  • 22
  • Hi, I need to get the client User ID without any authentication. I have a ldap active directory.i have searched a lot. tried waffle filter but not getting any clarification. I am new to this please kindly help me with this. – Karthick Anbazhagan May 07 '19 at 14:16