Spring Security-api gateway pattern-bug?[英] Spring Security - api gateway pattern - bug?

本文是小编为大家收集整理的关于Spring Security-api gateway pattern-bug?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我们创建了一个模拟Spring Security-API GATE模式教程的应用程序( https://spring.io/guides/tutorials/spring-security-security-and-angular-js/#_the_patiway_patterway_pattern_angular_js_angular_js_and_and_spring_security_security_part_iv ).唯一的变化是我们使用MySQL数据库而不是Redis.

使用localhost:8080作为根,我们有Localhost:8080/login(login page),Localhost:8080/ui(jQuery Client)和localhost:8080/api(Restful Web Services,Business Logic等)

我们发现会话处理和转发到各个实体的工作原理.这意味着会话会按预期创建,转发如预期的等.有一个例外.如果我登录,然后登录,然后直接转到Localhost:8080/UI,它将转发给我到登录页面.您登录,然后将您转发回Localhost:8080/ui,​​但会显示"访问被拒绝"!

跟踪数据库和客户端中的会话后,我发现数据库中存在两个会话.一个具有权限,没有权限.客户保留一个没有!

的客户

还有其他人遇到这个问题吗?有没有办法绕过这个?

这是我通过的列表步骤,数据库会话跟踪和客户端验证.

    session_id                               principal_name  Client
    ------------------------------------------------------------
1)  go to localhost:8080                    
    9229045c-27e0-410a-8711-45c56576d647    -                X

2)  login                   
    2275db1c-fca4-4a2f-be73-e440599499d6    root             X

3)  logout                  
    cc917e68-b1c0-46a4-bbe3-6705ccf7a5fa    -                X

4)  go to localhost:8080/ui --> forwards to localhost:8080/login
    cc917e68-b1c0-46a4-bbe3-6705ccf7a5fa    -                X

5)  login -> forwards to  localhost:8080/ui -> Access Denied                    
    90d7931d-b265-42e2-a225-286bcf7d159c    -                X
d2fae0ac-9cf9-4287-8e38-51f64b0ab28d root

推荐答案

好吧,经过数小时后,我们找到了似乎不一致的行为的解决方案.意思是有时您会登录并保留适当的会话,并且可以进行Localhost:8080/UI页面,并且不会获取Whitelabel错误页面...有时您仍然会得到它.

在网关服务器上...
1)添加了requestMethod.post

@Controller
public class HomeController {
    @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST }, path = "/")
    public String home() {
        return "redirect:" + RequestMappings.UI;
    }
}

2)更改了配置文件,特别是
a)添加.successforwardurl("/")
b)添加.loginProcessingurl("/login")
c)添加.logoutsuccessurl("/登录?登录")

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.headers()
        .frameOptions().sameOrigin()
    .and().formLogin()
        .loginPage(RequestMappings.LOGIN)
        .failureHandler(failureHandler())
        .successForwardUrl("/")
        .permitAll()
        .loginProcessingUrl("/login")
    .and().logout()
        .logoutSuccessUrl("/login?logout")
    .and().authorizeRequests()
        .antMatchers("/login").permitAll()
        .antMatchers(RequestMappings.CHANGE_PASSWORD).permitAll()
        .anyRequest().authenticated()
    .and().csrf()
        .csrfTokenRepository(csrfTokenRepository())
    .and().addFilterAfter(csrfHeaderFilter(), SessionManagementFilter.class);
}

现在,仍然有一种方法可以获取白页错误.如果在登录之前,您直接转到Localhost:8080/UI….它会将您转发到Localhost:8080/登录页面.您登录.您将在Localhost:8080/UI/查看预期的所有内容.如果您删除了最后一个前向斜线,则将获得白页错误.然后从那里开始,可以在缓存中弄乱.但是,如果您回到根本上,则可以按正常登录,一切都会正常工作.

我认为发生了什么事是locin localhost:8080/ui呼叫被缓存,并且因为index.html页面从未加载一旦登录并返回,您就通过了授权检查,但是试图加载……嗯,什么都没有,然后引发错误.至少那是我最好的猜测.

无论如何,欢呼!感谢您的帮助,这使我们从正确的轨道开始!

其他推荐答案

很可能,当您直接返回UI应用程序时,它仍在使用旧会话ID,当您登录时,它将您再次使用旧会话ID重定向到UI.

也可能是Tomcat上仍然是一个旧问题,请检查此线程以查看如何正确清除您的cookie: https://straypixels.net/clearing-cookies-in-spring-tomcat/

基本上,按下SimpleUrlLogoutSuccessHandler:

public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
    //This search may or may not actually be necessary, you might be able to just
    // create a new cookie with the right name
    for(Cookie cookie : request.getCookies()) {
        if(cookie.getName() == "JSESSIONID") {
            //Clear one cookie
            cookie.setName("");
            cookie.setMaxAge(0);
            cookie.setPath(request.getContextPath());
            response.addCookie(cookie);
            //Clear the other cookie
            Cookie cookieWithSlash = cookie.clone();
            cookieWithSlash.setPath(request.getContextPath() + "/");
            response.addCookie(cookieWithSlash);
        }
    }
    //This is actually a filter; continue along the chain
    super.onLogoutSuccess(request, response, authentication);
}

本文地址:https://www.itbaoku.cn/post/1937816.html

问题描述

We've created an application that mimics the Spring Security - API Gate Pattern tutorial (https://spring.io/guides/tutorials/spring-security-and-angular-js/#_the_api_gateway_pattern_angular_js_and_spring_security_part_iv). The only variation is that we're using a MySQL database rather than Redis.

Using localhost:8080 as the root, we have localhost:8080/login (login page), localhost:8080/ui (jQuery client), and localhost:8080/api (restful web services, business logic, etc.)

We're finding session handling and forwarding to the various entities works as expected. Meaning the session gets created as expected, forwarding is happening as expected, etc. There is one exception. If I log in, then log out, then go directly to localhost:8080/ui it'll forward me to the login page. You login, and it forwards you back to the localhost:8080/ui, but will display "ACCESS DENIED"!

After tracking the sessions in the database and client I've found that there are two sessions that exist in the database. One with permissions and one without. The client retains the one without!

Has anyone else run into this problem? Is there a way to circumvent this?

Here's a list steps I went through, the database session tracking, and client verification.

    session_id                               principal_name  Client
    ------------------------------------------------------------
1)  go to localhost:8080                    
    9229045c-27e0-410a-8711-45c56576d647    -                X

2)  login                   
    2275db1c-fca4-4a2f-be73-e440599499d6    root             X

3)  logout                  
    cc917e68-b1c0-46a4-bbe3-6705ccf7a5fa    -                X

4)  go to localhost:8080/ui --> forwards to localhost:8080/login
    cc917e68-b1c0-46a4-bbe3-6705ccf7a5fa    -                X

5)  login -> forwards to  localhost:8080/ui -> Access Denied                    
    90d7931d-b265-42e2-a225-286bcf7d159c    -                X
d2fae0ac-9cf9-4287-8e38-51f64b0ab28d root

推荐答案

Alright, after many hours we found a solution to what seemed to be inconsistent behavior. Meaning sometimes you'd log in and it'd retain the proper session and you could go the the localhost:8080/ui page and not get the Whitelabel Error page... sometimes you'd still get it.

On the Gateway server...
1) Added RequestMethod.POST

@Controller
public class HomeController {
    @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST }, path = "/")
    public String home() {
        return "redirect:" + RequestMappings.UI;
    }
}

2) Changed configure file, specifically
a) added .successForwardUrl(“/”)
b) added .loginProcessingUrl(“/login”)
c) added .logoutSuccessUrl("/login?logout")

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.headers()
        .frameOptions().sameOrigin()
    .and().formLogin()
        .loginPage(RequestMappings.LOGIN)
        .failureHandler(failureHandler())
        .successForwardUrl("/")
        .permitAll()
        .loginProcessingUrl("/login")
    .and().logout()
        .logoutSuccessUrl("/login?logout")
    .and().authorizeRequests()
        .antMatchers("/login").permitAll()
        .antMatchers(RequestMappings.CHANGE_PASSWORD).permitAll()
        .anyRequest().authenticated()
    .and().csrf()
        .csrfTokenRepository(csrfTokenRepository())
    .and().addFilterAfter(csrfHeaderFilter(), SessionManagementFilter.class);
}

Now, there still is a way to get the whitepage error. If, before ever logging in, you go directly to localhost:8080/ui…. It’ll forward you to the localhost:8080/login page. You log in. You’ll be at localhost:8080/ui/ looking at everything as expected. If you remove the last forward slash then you’ll get the whitepage error. Then from there things can get mucked up in the cache. But if you go back to the root, you can login as normal and everything will work as normal.

I think what is going on is that the pre-login localhost:8080/ui call is being cached and because the index.html page was never loaded once you log back in and go back you pass the authorization check, but it tries to load… well, nothing, then throws an error. At least that’s my best guess.

Anyways, cheers! Thanks for the help, which started us off on the right track!

其他推荐答案

Most likely, when you go directly back to your UI application, it is still using the old session ID and when you log in, it is redirecting you to the UI again with the old session ID.

It could also be that it is still an old issue on Tomcat, check this thread to see how to properly clear your cookies: https://straypixels.net/clearing-cookies-in-spring-tomcat/

Bascially, extend the SimpleUrlLogoutSuccessHandler like this:

public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
    //This search may or may not actually be necessary, you might be able to just
    // create a new cookie with the right name
    for(Cookie cookie : request.getCookies()) {
        if(cookie.getName() == "JSESSIONID") {
            //Clear one cookie
            cookie.setName("");
            cookie.setMaxAge(0);
            cookie.setPath(request.getContextPath());
            response.addCookie(cookie);
            //Clear the other cookie
            Cookie cookieWithSlash = cookie.clone();
            cookieWithSlash.setPath(request.getContextPath() + "/");
            response.addCookie(cookieWithSlash);
        }
    }
    //This is actually a filter; continue along the chain
    super.onLogoutSuccess(request, response, authentication);
}