Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

waffle-negotiate not working with spring boot #460

Closed
bishnu-zwayam opened this issue Dec 21, 2016 · 24 comments
Closed

waffle-negotiate not working with spring boot #460

bishnu-zwayam opened this issue Dec 21, 2016 · 24 comments

Comments

@bishnu-zwayam
Copy link

I tried waffle negotiate but with spring boot jar, Httpservletrequest remote user returning null.
But if i deploy it in tomcat server as a war file it is returning the reote user.

@hazendaz
Copy link
Member

hazendaz commented Dec 21, 2016 via email

@bishnu-zwayam
Copy link
Author

bishnu-zwayam commented Dec 22, 2016

Thanx for reply
1)This is my project structure:
project_structure
2)web.xml
web
3) pom.xml
pom
4) controller
@RestController
@RequestMapping("/Waffle")
public class Waffle {

@RequestMapping(value="/checkWaffle",method = RequestMethod.GET)
public String checkWaffle(HttpServletRequest req){
	System.out.println(req.getRemoteUser()); // This is returning null
	return "success";
}

}
5) Application.class
@configuration
@EnableAutoConfiguration
@componentscan({"waffleTest","controllers"})
@EnableScheduling
public class Application {

public static void main(String[] args) {
	System.out.println("started");
	SpringApplication app = new SpringApplication(Application.class);
    app.run(args);
}

}
6) Application.properties
server.port=9898

  1. Now when I make jar and run it and access http:https://localhost:9898/Waffle/checkWaffle , the remoteuser is showing null
    Any help will be appreciated.
    Thank you.

@hazendaz
Copy link
Member

Couple of things. I"ve gotten this far in working now. I didn't have everything you have there but figured most of it out. So seems you are using older springboot setup and additionally using mixed versions of waffle. Neither are a cause of the issue but something I wanted to point out.

Now, I think to get this working it will require a number of things potentially. Please keep in mind I know next to nothing about spring boot so I'm simply guessing.

Things needed...

  • TomcatEmbeddedServletContainerFactory needs configured for valve and realm.
  • ApplicationSecurity needs setup with a number of things I believe from the configuration we show as examples for spring
  • Waffle spring module is likely needed in this.

These are all guesses at the moment. I've got this much coded up but still trying to figure it out and still getting null. At the moment, when I get this going, it seems to skip the valve entirely. I think that is exactly why it's null but still not completely clear what all needs to occur. I'll make my code available on my fork under demo app (waffle-springboot). Maybe that might help get it further or you might be able to assist back on what I'm doing to see if we can get this any closer.

@bishnu-zwayam
Copy link
Author

Thank you for your reply. I will try to do the things needed. It would be great if I get some information from your fork.

@hazendaz
Copy link
Member

@bishnu-zwayam
Here is where I got to -> here

At the moment, I couldn't get waffle to turn on and work so that is commented out in the Application class. What you will see is just a call to super. That will cause it to use spring default logon page. There the user is simply 'user', and if you check the logback logs which land in the folder root, it will have a long string that will give you the password for that session. Essentially that shows that 'user' does get into request. So now it's just a matter of figuring this out. I think I got as far as I could. Hopefully you can bring more spring knowledge to assist.

@bishnu-zwayam
Copy link
Author

Ok I will use your code and try to take it further. And If you get something please let me know. Thank you.

@hazendaz
Copy link
Member

hazendaz commented Jan 1, 2017

I moved this code over to a branch on my repo called 'springboot' so I can otherwise perform a release of the core code at this time.

@mgoldgeier
Copy link
Contributor

I have also been having problems getting Waffle to work with Spring Boot/Spring Security, but only when I use Internet Explorer as the browser. Chrome and Firefox seem to work OK though, so I'm not sure if the issue is the same as the one described here. I put together a very simple demo application that uses Spring Boot with Waffle. If I run this, sometimes it will work with IE and sometimes it will fail with:

waffle.spring.NegotiateSecurityFilter : error logging in user: com.sun.jna.platform.win32.Win32Exception: The token supplied to the function is invalid

Perhaps someone could take a look and see if they can see the same issue?

The demo application is at: https://github.com/mgoldgeier/waffle-spring-boot-demo

@hazendaz
Copy link
Member

@mgoldgeier I went ahead and started watching your demo and forked it. I don't have much time for next few months to work on waffle but wanted to keep tabs in case of progress of when I find time later on. Thanks for making that available.

@r0n1am
Copy link

r0n1am commented Feb 15, 2017

@mgoldgeier I have the same problem too. Also if using Waffle 1.8.3 the app will fail miserably, but it is completely different problem.

Edit:
I think the problem is that the waffle.spring.NegotiateSecurityFilter is called twice. After adding the following code in WaffleConfig.java, the Exception log is gone.

@Bean
public FilterRegistrationBean waffleNegotiateSecurityFilterRegistration (NegotiateSecurityFilter waffleNegotiateSecurityFilter) {
    FilterRegistrationBean registrationBean = new FilterRegistrationBean();
    registrationBean.setFilter(waffleNegotiateSecurityFilter);
    registrationBean.setEnabled(false);
    return registrationBean;
}

Checked with your demo application, seems worked.

@mgoldgeier
Copy link
Contributor

@r0n1am If that solves the problem, that would be great news. I haven't had a chance to look at it yet.

I don't understand why the code you mention would be necessary. Can you maybe explain what the difference would be and why/how NegotiateSecurityFilter would be getting called twice?

@r0n1am
Copy link

r0n1am commented Feb 17, 2017

@mgoldgeier I got the idea from this post and followed comment to this post.

Basically, NegotiateSecurityFilter in waffle-spring-security4 extends GenericFilterBean from Spring. When using Spring Boot, any GenericFilterBean in the context will be automatically added to the filter chain(actually all Filter will be added). In the demo app, addFilterBefore(negotiateSecurityFilter, BasicAuthenticationFilter.class); in SecurityConfig added the filter to the filter chain again, which made the filter registered twice and called twice later on.

One interesting thing is that in my testing environment, Chrome and FireFox didn't have the problem and the filter seems work fine, i.e. showed correct information from AD. I don't know why only IE 11 have the problem (only tested IE11, don't know about other versions of IE or Edge).

I think the problem might be able to solve by rearrange those config classes in the demo app. But the solution provided in the StackoverFlow worked fine, so I didn't test it anymore.

@mgoldgeier
Copy link
Contributor

@r0n1am Awesome find! I did a real quick test and this did seem to fix the issue. At the very least, you were right that the filter was being registered twice. I also noticed that I had been only having issues with IE11, but not other browsers. I assume it comes down to a matter of timing differences between the browsers.

I updated the demo app with your fix.
I haven't touched Waffle 1.8.3, but it doesn't appear to have been released yet.

@hazendaz
Copy link
Member

Closing issue as this is completed on master. Release of 1.9.0 is coming soon (most likely before christmas).

@wussup
Copy link

wussup commented Oct 12, 2018

I still have the same ("The token supplied to the function is invalid") in IE and Edge :(

Classes SecurityConfig and WaffleConfig I got from https://github.com/mgoldgeier/waffle-spring-boot-demo

waffle-spring-security4 -> 1.9.1
Spring Boot -> 1.5.8.RELEASE

EDIT:
This only take place, when I request URL by domain name, for IP address this works fine.

Logs:

2018-10-12 10:16:54.353 DEBUG 7192 --- [nio-8080-exec-6] o.s.security.web.FilterChainProxy        : /auth/ldap at position 5 of 12 in additional filter chain; firing Filter: 'NegotiateSecurityFilter'
2018-10-12 10:16:54.353 DEBUG 7192 --- [nio-8080-exec-6] waffle.spring.NegotiateSecurityFilter    : GET /uemserver/auth/ldap, contentlength: -1
2018-10-12 10:16:54.353 DEBUG 7192 --- [nio-8080-exec-6] w.s.spi.NegotiateSecurityFilterProvider  : security package: Negotiate, connection id: 0:0:0:0:0:0:0:1:56969
2018-10-12 10:16:54.353 DEBUG 7192 --- [nio-8080-exec-6] w.s.spi.NegotiateSecurityFilterProvider  : token buffer: 1575 byte(s)
2018-10-12 10:16:54.354 DEBUG 7192 --- [nio-8080-exec-6] w.s.spi.NegotiateSecurityFilterProvider  : continue token: oXkwd6ADCgEBonAEbmBsBgkqhkiG9xIBAgIDAH5dMFugAwIBBaEDAgEepBEYDzIwMTgxMDEyMDgxNjU0WqUFAgMNA/mmAwIBKakNGwtCWk1XLkdPVi5QTKohMB+gAwIBAaEYMBYbFHN2Yy5iZ2lrX3VlbS1zZXJ2aWNl
2018-10-12 10:16:54.354 DEBUG 7192 --- [nio-8080-exec-6] w.s.spi.NegotiateSecurityFilterProvider  : continue required: true
2018-10-12 10:16:54.354 DEBUG 7192 --- [nio-8080-exec-6] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2018-10-12 10:16:54.354 DEBUG 7192 --- [nio-8080-exec-6] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2018-10-12 10:16:54.354 DEBUG 7192 --- [nio-8080-exec-6] o.s.b.w.f.OrderedRequestContextFilter    : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@35787539
2018-10-12 10:16:56.034 DEBUG 7192 --- [io-8080-exec-10] o.s.b.w.f.OrderedRequestContextFilter    : Bound request context to thread: org.apache.catalina.connector.RequestFacade@35787539
2018-10-12 10:16:56.034 DEBUG 7192 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy        : /auth/ldap at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2018-10-12 10:16:56.034 DEBUG 7192 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy        : /auth/ldap at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2018-10-12 10:16:56.034 DEBUG 7192 --- [io-8080-exec-10] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2018-10-12 10:16:56.034 DEBUG 7192 --- [io-8080-exec-10] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@5f0b24f2. A new one will be created.
2018-10-12 10:16:56.034 DEBUG 7192 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy        : /auth/ldap at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2018-10-12 10:16:56.034 DEBUG 7192 --- [io-8080-exec-10] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@2f4c3c6e
2018-10-12 10:16:56.034 DEBUG 7192 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy        : /auth/ldap at position 4 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
2018-10-12 10:16:56.034 DEBUG 7192 --- [io-8080-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', GET]
2018-10-12 10:16:56.034 DEBUG 7192 --- [io-8080-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/auth/ldap'; against '/logout'
2018-10-12 10:16:56.034 DEBUG 7192 --- [io-8080-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', POST]
2018-10-12 10:16:56.034 DEBUG 7192 --- [io-8080-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /auth/ldap' doesn't match 'POST /logout
2018-10-12 10:16:56.034 DEBUG 7192 --- [io-8080-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', PUT]
2018-10-12 10:16:56.034 DEBUG 7192 --- [io-8080-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /auth/ldap' doesn't match 'PUT /logout
2018-10-12 10:16:56.034 DEBUG 7192 --- [io-8080-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', DELETE]
2018-10-12 10:16:56.034 DEBUG 7192 --- [io-8080-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /auth/ldap' doesn't match 'DELETE /logout
2018-10-12 10:16:56.034 DEBUG 7192 --- [io-8080-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : No matches found
2018-10-12 10:16:56.034 DEBUG 7192 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy        : /auth/ldap at position 5 of 12 in additional filter chain; firing Filter: 'NegotiateSecurityFilter'
2018-10-12 10:16:56.034 DEBUG 7192 --- [io-8080-exec-10] waffle.spring.NegotiateSecurityFilter    : GET /uemserver/auth/ldap, contentlength: -1
2018-10-12 10:16:56.035 DEBUG 7192 --- [io-8080-exec-10] w.s.spi.NegotiateSecurityFilterProvider  : security package: Negotiate, connection id: 0:0:0:0:0:0:0:1:56969
2018-10-12 10:16:56.035 DEBUG 7192 --- [io-8080-exec-10] w.s.spi.NegotiateSecurityFilterProvider  : token buffer: 1632 byte(s)
2018-10-12 10:16:56.035  WARN 7192 --- [io-8080-exec-10] waffle.spring.NegotiateSecurityFilter    : error logging in user: com.sun.jna.platform.win32.Win32Exception: The token supplied to the function is invalid
2018-10-12 10:16:56.035 DEBUG 7192 --- [io-8080-exec-10] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2018-10-12 10:16:56.035 DEBUG 7192 --- [io-8080-exec-10] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2018-10-12 10:16:56.035 DEBUG 7192 --- [io-8080-exec-10] o.s.b.w.f.OrderedRequestContextFilter    : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@35787539
2018-10-12 10:16:56.035 ERROR 7192 --- [io-8080-exec-10] o.s.boot.web.support.ErrorPageFilter     : Cannot forward to error page for request [/auth/ldap] as the response has already been committed. As a result, the response may have the wrong status code. If your application is running on WebSphere Application Server you may be able to resolve this problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false

@hazendaz
Copy link
Member

hazendaz commented Oct 12, 2018 via email

@wussup
Copy link

wussup commented Oct 12, 2018

@hazendaz Do you meen waffle-spring-boot-starter?

@hazendaz
Copy link
Member

hazendaz commented Oct 12, 2018 via email

@wussup
Copy link

wussup commented Oct 12, 2018

@hazendaz Same error :(

Already tried to update Spring Boot version to 2.0.5, but nothing changed

@wussup
Copy link

wussup commented Oct 25, 2018

@hazendaz Problem solved. I ran Tomcat with system user from AD, when I changed type of running to Local System, then problem dissapear. :)

PS: found here

@hazendaz
Copy link
Member

hazendaz commented Oct 25, 2018 via email

@wussup
Copy link

wussup commented Oct 26, 2018

@hazendaz Do you have any solution for Mixed Authentication with Spring Boot and Waffle?

I mean, that I would like to login with Waffle SSO for Intranet users and I would like to login with Login Form for Internet users without showing browser popup, but only my login page.

@wussup
Copy link

wussup commented Oct 26, 2018

@hazendaz Do you have any solution for Mixed Authentication with Spring Boot and Waffle?

I mean, that I would like to login with Waffle SSO for Intranet users and I would like to login with Login Form for Internet users without showing browser popup, but only my login page.

I solved it by extending NegotiateSecurityFilterEntryPoint, method commence now look like:

@Override
public void commence(final HttpServletRequest request, final HttpServletResponse response,
		final AuthenticationException authException) throws IOException, ServletException {
	if (isInternetIP(request)) {
		// Authentication failed, send error response.
		response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);

		PrintWriter writer = response.getWriter();
		writer.println("HTTP Status 401: " + authException.getMessage());
	} else {
		super.commence(request, response, authException);
	}

}

Do you know any better solution?

@hazendaz
Copy link
Member

hazendaz commented Oct 26, 2018 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants