当前位置: 首页 > 知识库问答 >
问题:

Spring OAUTH-web e REST的不同登录

商同
2023-03-14

你好,我有一个用Spring security保护的web应用程序,有一个登录页面。这是我的安全配置

@Configuration
@ComponentScan("it.besmart")
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{

    @Autowired
    @Qualifier("customUserDetailsService")
    UserDetailsService userDetailsService;

    @Autowired
    CustomSuccessHandler customSuccessHandler;

    @Autowired
    CustomAuthenticationFailureHandler customAuthenticationFailureHandler;

    @Autowired
    DataSource dataSource;

    @Autowired
    private ConnectionFactoryLocator connectionFactoryLocator;

    @Autowired
    private UsersConnectionRepository usersConnectionRepository;

    @Autowired
    private FacebookConnectionSignup facebookConnectionSignup;



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

    @Autowired
    public void configureGlobalService(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());

    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }


        protected void configure(HttpSecurity http) throws Exception {
            logger.debug("Webapp security configured");
            http.

            authorizeRequests()

                    .antMatchers("/",  "/register", "/registrationConfirm", "/resendRegistrationToken", "/park/**")
                    .permitAll()

                    .antMatchers("/edit/**", "/payment/**", "/plate/**", "/book/**", "/home", "/stop/**",
                            "/notification/**", "/include/**")
                    .access("hasRole('USER') or hasRole('ADMIN') or hasRole('PARK')").antMatchers("/admin/**")
                    .access("hasRole('ADMIN') or hasRole('PARK')").antMatchers("/updatePassword")
                    .hasAuthority("CHANGE_PASSWORD_PRIVILEGE")

                    .and().formLogin().loginPage("/")
                    .successHandler(customSuccessHandler).failureHandler(customAuthenticationFailureHandler)
                    .usernameParameter("email").passwordParameter("password").and().rememberMe()
                    .rememberMeParameter("remember-me").tokenRepository(persistentTokenRepository())
                    .tokenValiditySeconds(86400).and().exceptionHandling().accessDeniedPage("/Access_Denied").and()
                    .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                    .logoutSuccessUrl("/?logout=true").permitAll();
        }


        @Override
        @Bean
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }

    @Bean
    public PersistentTokenRepository persistentTokenRepository() {
        JdbcTokenRepositoryImpl db = new JdbcTokenRepositoryImpl();
        db.setDataSource(dataSource);
        return db;
    }

}

通过保护我所有的web应用程序,这工作得很好。

在同一个应用程序中,我还有一个资源/授权服务器来保护一些REST API。

@EnableResourceServer
@ComponentScan("it.besmart.easyparking")
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceServerConfig {

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

    @Autowired
    DataSource dataSource;

    private static final String RESOURCE_ID = "easyparking_api";

    @Configuration
    // @Order(2)
    public class grantCredentialsConfiguration extends ResourceServerConfigurerAdapter {
        @Override
        public void configure(HttpSecurity http) throws Exception {
            logger.debug("Api security configured");

            http

                    .requestMatchers().antMatchers("/api/oauth/**").and().authorizeRequests()
                    .antMatchers("/api/oauth/**").access("hasRole('USER')").and().formLogin().loginPage("/apilogin")
                    .permitAll();
        }

        @Override
        public void configure(ResourceServerSecurityConfigurer resources) throws Exception {

            resources.tokenStore(tokenStore()).resourceId(RESOURCE_ID);
        }
    }

    @Configuration
    // @Order(4)
    public class clientCredentialsConfiguration extends ResourceServerConfigurerAdapter {
        @Override
        public void configure(HttpSecurity http) throws Exception {
            logger.debug("Client security configured");
            http
                    .requestMatchers().antMatchers("/oauth2/**", "/api/registration", "/api/park/**").and()
                    .authorizeRequests().antMatchers("/oauth2/**", "/api/registration", "/api/park/**").authenticated();
        }

        @Override
        public void configure(ResourceServerSecurityConfigurer resources) throws Exception {

            resources.tokenStore(tokenStore()).resourceId(RESOURCE_ID);
        }
    }

    @Bean
    public TokenStore tokenStore() {
        return new JdbcTokenStore(dataSource);
    }

}
    2017-05-25 12:23:15 DEBUG o.s.security.web.FilterChainProxy[310] - /oauth/authorize?response_type=token&client_id=test&redirect_uri=https://www.getpostman.com/oauth2/callback reached end of additional filter chain; proceeding with original chain
2017-05-25 12:23:15 DEBUG o.s.s.o.p.e.FrameworkEndpointHandlerMapping[310] - Looking up handler method for path /oauth/authorize
2017-05-25 12:23:15 DEBUG o.s.s.o.p.e.FrameworkEndpointHandlerMapping[317] - Returning handler method [public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorize(java.util.Map<java.lang.String, java.lang.Object>,java.util.Map<java.lang.String, java.lang.String>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)]
2017-05-25 12:23:15 DEBUG o.s.s.w.a.ExceptionTranslationFilter[163] - Authentication exception occurred; redirecting to authentication entry point
org.springframework.security.authentication.InsufficientAuthenticationException: User must be authenticated with Spring Security before authorization can be completed.

因此,看起来像是在搜索处理程序来管理请求,而不是按照需要重定向到/api/apilogin,他发现了一个身份验证异常,所以我转到了标准登录页面...但为什么我会得到这个例外?

共有1个答案

张晔
2023-03-14

发生这种情况是因为您没有指定安全配置类的顺序。

Spring安全资源保护应从具体到一般。

SecurityConfigurationGrantCredentialsConfiguration更通用。因为两者都保护以下资源。

    null
@Configuration
@Order(2)//Generic config should have larger value (lower priority)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{
}

@Configuration
@Order(1)//Specific with lower value (higher priority)
public class grantCredentialsConfiguration extends ResourceServerConfigurerAdapter {

}

注意:由于这些登录页面不是来自不同的应用程序,它们共享SecurityContextholder或安全上下文。因此,如果您从一个登录页面登录,然后尝试转到另一个登录页面的受保护资源,您将不会被重定向到下一个登录页面。相反,您将得到403(取决于不同登录页面分配的角色)。一次只能维护一个登录会话。

下面是Github上的一个示例

https://github.com/encidousobserver/testmultipleLoginPages.git

 类似资料:
  • 问题内容: 我的logback.xml中有这个添加器 因此,目前我将所有日志保存到一个文件中。如何使它像一个文件仅保存错误日志,而另一个文件保存所有其他日志? 我想在代码中仅使用1个logger实例,如下所示: 问题答案: 开始寻找logback类别,找到过滤器。 只需将过滤器说明添加到您的附加程序即可:

  • 瞄准 允许不同类型的用户登录到各自的接口 描述 null 每个用户通过Firebase身份验证电子邮件注册 每个用户应该能够作为每个接口访问他们各自的接口,如果不同的话 每个用户都已经与各自的子节点一起保存在Firebase数据库中。例如,在“users”下面有一个“school”,在这个“school”下面是用户类型,如“student”、“parent”和“teacher”。 可视化数据库 用

  • 问题内容: 我想了解最佳实践,即如何在AngularJS中设置路由和模板,以向访问者显示不同的前台和登录区域,然后显示仪表板以在相同的基本URL(’/’)上登录用户。 这两页在结构上完全不同,并且还需要不同的资产。 为网站的两个部分设置两个不同的应用程序是否更好,但是我将如何管理这两个部分之间的会话? 还是在主体标签之间没有任何内容的“空”布局将不同的模板加载到其中,并为前部分和仪表板部分进行单独

  • 问题内容: 我已经在使用基本的日志记录配置,其中所有模块中的所有消息都存储在一个文件中。但是,我现在需要一个更复杂的解决方案: 两个文件:第一个保持不变。 第二个文件应具有一些自定义格式。 我一直在阅读该模块的文档,但目前它们对我来说很复杂。记录器,处理程序… 因此,简而言之: 如何在Python 3中登录到两个文件,即: 问题答案: 您可以执行以下操作:

  • 问题内容: 今天,我在运行此查询时在PostgreSQL 9.6中遇到无法解释的结果: 两列的预期结果:。但是,仅在2018年5月19日至2018年6月30日的时间间隔内,我能达到我的期望,而对于2018年5月20日至2018年7月1日,我将获得更多的一天: 我不明白为什么会这样,据我所知,在2018-05-20 2018-07-01之间只是一个间隔,这里的Postgres结果是错误的。 我找不到

  • 我可以看到邮件服务器上的许多ehlo命令回音如下: 我想知道“250-AUTH登录平原”和“250-AUTH=登录平原”有什么不同?谢谢