These are chat archives for spring-cloud/spring-cloud

21st
May 2015
Leon Radley
@leon
May 21 2015 05:50

Now that zuul is working properly it’s not a problem to do requests between the apps
A problem that I have is that I need to be able to check if I’m logged in from a wordpress site
By exposing an api on the auth server that is protected by the normal security layer I can do a angular http request with “withCredentials”: true and get back the user info
My problem is that If I’m not logged in, the auth server is trying to redirect to /login.

Can I somehow force the auth server to return a 401 instead of a 302 for when a ajax request comes in?

Dave Syer
@dsyer
May 21 2015 05:56
You said "redirect to /login" and 401
It can't be both
Leon Radley
@leon
May 21 2015 05:57
what bean is responsible for doing the redirect?
Dave Syer
@dsyer
May 21 2015 05:57
There is an error handler in the security filter chain
AuthentucatiinEntryPoint (not a bean in general)
But you can customize it.
it has request matchers attached to it
Is the Wordpress app hitting with an identifiable signature (url pattern, header etc)?
Leon Radley
@leon
May 21 2015 06:01
yes, it’s calling a specific url, and I can add what ever headers I want
though I could add a default header to all ajax request
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
Dave Syer
@dsyer
May 21 2015 06:02
Have a look at the Spring Security docs
That header works for HTTP basic auth I think
Leon Radley
@leon
May 21 2015 06:03
ahh
Dave Syer
@dsyer
May 21 2015 06:03
Not sure it has any effect by default on this
Leon Radley
@leon
May 21 2015 06:03
it should :)
Dave Syer
@dsyer
May 21 2015 06:03
But you can look into where it is used and copy that in your own authentication entry point
Leon Radley
@leon
May 21 2015 06:04
I’ll give it a go, thanks!
Leon Radley
@leon
May 21 2015 06:16

got it working

public class ApiAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {

    private static final Logger log = LoggerFactory.getLogger(ApiAuthenticationFailureHandler.class);

    private final RequestMatcher apiMatcher = new AntPathRequestMatcher("/intapi/**");

    public ApiAuthenticationEntryPoint(String loginFormUrl) {
        super(loginFormUrl);
    }

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        if (apiMatcher.matches(request)) {
            log.debug("API Authentication Failed", authException);
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication Failed: " + authException.getMessage());
        } else {
            super.commence(request, response, authException);
        }
    }
}

and then registering it with

http
    .exceptionHandling()
        // Custom AuthenticationEndPoint that checks if we are a a ajax request
        .authenticationEntryPoint(new ApiAuthenticationEntryPoint("/signin"))
Leon Radley
@leon
May 21 2015 08:28

@dsyer I’m still having troubles with a combined SSO and Resource Server.
If the sso is configured with

@Override
public void match(RequestMatchers matchers) {
    matchers.antMatchers("/**");
}

@Override
public void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .anyRequest().authenticated()
            .and()
        .csrf()
            .csrfTokenRepository(csrfTokenRepository())
            .and()
        .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
}

the the resource server is configured with

@Override
public void configure(final HttpSecurity http) throws Exception {
    http
        .requestMatchers()
            .antMatchers("/api/**")
            .and()
            .authorizeRequests()
                .anyRequest().authenticated();
}

Does this mean that since SSO is active for /** that it will also operate for the resource server?

Do I need to somehow remove /api/** from beeing processed by SSO, or is the resource server’s @Order before the SSO, and will that mean that it cancels out the SSO filter?
Dave Syer
@dsyer
May 21 2015 08:46
Yes
I.e. you can probably do it either way if the @Order is right
Leon Radley
@leon
May 21 2015 08:47
What’s the best way of checking in which order the filters are run?
Dave Syer
@dsyer
May 21 2015 08:48
DEBUG logging probably
We should make an endpoint for that
Leon Radley
@leon
May 21 2015 08:48
yes that would be very helpful
Dave Syer
@dsyer
May 21 2015 08:49
The SSO filter is high by default (after the actuator security filter if there is one)
Leon Radley
@leon
May 21 2015 08:49
something like a security trace where you would see where the Authentication gets added
Dave Syer
@dsyer
May 21 2015 08:49
You can definitely get that from logs
The resource server filter is lower by default
So I'd expect it to work as you showed your code unless you modified something
You can see the filters being applied in DEBUG logs though
Leon Radley
@leon
May 21 2015 08:51
It is working, but I’m getting double headers, but maybe that is another problem
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
maybe I should disable the headers for the resource server with http.headers().disable()
Since they seems to get added by the sso
that seems to do the trick
all duplicate headers are gone except ´X-Application-Context´
Dave Syer
@dsyer
May 21 2015 09:54
Weird
Someone reported double headers as a Zuul filter bug ages ago
We never reproduced the problem, so we assumed it had gone away I think
Leon Radley
@leon
May 21 2015 11:07
What is X-Application-Context?
Dave Syer
@dsyer
May 21 2015 11:08
It comes from Spring Boot
org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration.ApplicationContextHeaderFilter
Looks like you can switch it off with management.addApplicationContextHeader=false
Leon Radley
@leon
May 21 2015 12:00
How does the sso auth filter know where to redirect back to after it’s done?
Dave Syer
@dsyer
May 21 2015 12:01
It's a regular Spring Security filter
It remembers you in the Session by default
Leon Radley
@leon
May 21 2015 12:03
I’ve got a problem with my custom wordpress filter.
The filter checks for a cookie and redirects to /login
which causes the sso to kick in.
the problem is that I’m always getting redirected to the root “/“
so my custom filter should tell the login page where it wants to redirect back to
Dave Syer
@dsyer
May 21 2015 12:04
Don't know
If the client is javascript normally you just have to make it send the right URL to start with
Spring Security is only sending it back to where it started
Part VII in the blog (or the last chapter of tutorial) has a simple that does it with Angular
Leon Radley
@leon
May 21 2015 12:05
This is the webshop, so no angular here :(
I’ll have to try to track down where spring sets the url to remember
What does the sso Home class do?
Dave Syer
@dsyer
May 21 2015 12:08
"Home"?
Leon Radley
@leon
May 21 2015 12:08
OAuth2SsoProperties.Home
Dave Syer
@dsyer
May 21 2015 12:08
Just config for the "home" page (is it secure, what's the path)
The request is saved by ExceptionTranslationFilter (sendStartAuthentication())
Leon Radley
@leon
May 21 2015 12:09
thanks
Dave Syer
@dsyer
May 21 2015 12:09
It's regular Spring Security (nothing fancy in Spring Cloud as far as I recall)