Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring引导,具有用于单点登录的只读会话_Java_Spring Boot_Spring Security_Single Sign On_Spring Session - Fatal编程技术网

Java Spring引导,具有用于单点登录的只读会话

Java Spring引导,具有用于单点登录的只读会话,java,spring-boot,spring-security,single-sign-on,spring-session,Java,Spring Boot,Spring Security,Single Sign On,Spring Session,我们有一个遗留的Spring应用程序a,它不使用Spring引导来处理身份验证,并使用Spring会话将会话写入Redis。Redis中的数据存储为XML 我们现在想引入一个新的应用程序B,使用spring boot 2.2.6.RELEASE和spring session Corn-RC1,如果用户已使用角色_ADMIN登录,该应用程序应该可以使用。也就是说,这可以被视为一种非常粗糙的单点登录方式。用户永远不应该能够在B中进行身份验证。如果可能的话,如果要禁用身份验证,它应该只检查现有用户是否

我们有一个遗留的Spring应用程序a,它不使用Spring引导来处理身份验证,并使用Spring会话将会话写入Redis。Redis中的数据存储为XML

我们现在想引入一个新的应用程序B,使用spring boot 2.2.6.RELEASE和spring session Corn-RC1,如果用户已使用角色_ADMIN登录,该应用程序应该可以使用。也就是说,这可以被视为一种非常粗糙的单点登录方式。用户永远不应该能够在B中进行身份验证。如果可能的话,如果要禁用身份验证,它应该只检查现有用户是否在会话存储库redis中进行了身份验证,并且具有角色\u ADMIN。A和B都位于同一个域下,因此浏览器将传播cookie。我尝试了各种不同的方法来实现这一点,例如:

@配置 @启用Web安全性 类服务BStringSecurityConfig:WebSecurityConfigureAdapter{ @自动连线 趣味配置GlobalAuth:AuthenticationManagerBuilder{ auth.inMemoryAuthentication } 覆盖配置HTTP:HttpSecurity{ http .批准请求 .anyRequest.hasRoleADMIN 和 .formLogin 和 .httpBasic.disable } } 但这将显示默认登录屏幕:

我还尝试完全删除此部分:

@Autowired
fun configureGlobal(auth: AuthenticationManagerBuilder) {
    auth.inMemoryAuthentication()
}
但是它会生成一个默认的用户和密码,并且它似乎不会调用configure方法,或者不管怎样,配置都不起作用


如何解决这个问题?

您需要的是在应用程序B上禁用formLogin和httBasic,并在spring的身份验证过滤器AnonymousAuthenticationFilter或UsernamePasswordAuthenticationFilter之前添加一个过滤器。在自定义过滤器中,您将从请求对象中提取cookie/头/令牌,并基于此,访问redis缓存以获取会话详细信息。然后,此筛选器将验证会话并创建类型为org.springframework.security.core.Authentication的对象,并在当前SpringSecurityContext中设置该对象

下面是这方面的sudo代码

ServiceBStringSecurityConfig

作者点

AuthTokenFilter


如前所述,这是sudo代码,因此可能需要进行一些调整。然而,基于令牌的身份验证的一般要点保持不变

只是澄清一下,您希望登录页面仅在用户尝试访问应用程序A时显示。如果他们尝试在没有任何形式的身份验证的情况下访问应用程序B,则不应将其重定向到登录页面?如果用户被重定向到应用程序A的登录页面,则无所谓,但这将是一个很好的奖励:从不在B上显示登录页面是我追求的。
@Configuration
@EnableWebSecurity
public class ServiceBSpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
    http.cors().and().csrf().disable()
        .exceptionHandling().authenticationEntryPoint(authEntryPoint()).and()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
        .httpBasic().disabled().and()
        .formLogin().disabled().and()
        .authorizeRequests().anyRequest().hasRole("ADMIN")

    http.addFilterBefore(authTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    public AuthTokenFilter authTokenFilter() {
        return new AuthTokenFilter();
    }

    @Bean
    public AuthEntryPoint authEntryPoint() {
        return new AuthEntryPoint()
    }
}
public class AuthEntryPoint implements AuthenticationEntryPoint {

    private static final Logger logger = LoggerFactory.getLogger(AuthEntryPoint.class);

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException authException) throws IOException, ServletException {
        // Very generic authEntryPoint which simply returns unauthorized
        // Could implement additional functionality of forwarding the Application A login-page
        logger.error("Unauthorized error: {}", authException.getMessage());
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Error: Unauthorized");
    }
}
public class AuthTokenFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // extract some sort of token or cookie value from request
        token = request.getHeader("Token");
        if (token != null) {
            // Validate the token by retrieving session from redis cache
            // Create org.springframework.security.core.Authentication from the token
            Authentication auth = authFactory.getAuthentication(token);

            // Set the spring security context with the auth
            SecurityContextHolder.getContext().setAuthentication(auth);
        } else {
            // Do something if token not present at all
        }
        // Continue to to filter chain
        filterChain.doFilter(request, response);
    }
}