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

如何拥有单独的身份验证源?(一个用于Oauth2,一个用于基于表单的登录)

唐博文
2023-03-14

我正在编写一个小的应用程序,它有一个链接到数据库的身份验证,这个身份验证将由Oauth2方面(由@enableAuthorizationServer和@enableResourceServer注释的类)管理。在同一个应用程序中,管理页面有另一个身份验证,该页面将链接到另一个不同的数据库,并将使用常规的基于表单的身份验证。

为此,我编写了以下Web安全配置类:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig{

    @Configuration
    @Order(5)
    public static class AdminSecurityConfig extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {

            http.logout().logoutRequestMatcher(new AntPathRequestMatcher("/admin_logout"))
                    .invalidateHttpSession(true).logoutSuccessUrl("/admin/login.html");

            http.authorizeRequests()
                    .antMatchers("/admin/login.html").permitAll().antMatchers("/admin/protected.html")
                    .hasRole("ADMIN")
                    .and().formLogin().loginPage("/admin/login.html")
                    .loginProcessingUrl("/admin_login").defaultSuccessUrl("/admin/protected.html");

        }

        @Override
        public void configure(AuthenticationManagerBuilder auth) throws Exception {
            //Data source for form based auth
            auth.inMemoryAuthentication().withUser("adminuser").password("adminpassword").roles("ADMIN");
        }
    }
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        //Data source for Oauth
        auth.inMemoryAuthentication().withUser("myuser").password("mypassword").roles("USER").and().withUser("test")
                .password("testpassword").roles("USER");
    }
}

其他相关组成部分有:

授权服务器配置:

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter{

    @Autowired
    AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager).tokenEnhancer(tokenEnhancer())
        .tokenStore(tokenStore());
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients
            .inMemory()
                .withClient("client")
                .secret("secret")
                .authorizedGrantTypes("password", "refresh_token")
                .scopes("read", "write")
                .resourceIds("resource").accessTokenValiditySeconds(60);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception
    {
       oauthServer.checkTokenAccess("isAuthenticated()");    
    }

    @Bean
    public TokenEnhancer tokenEnhancer() {
        return new CustomTokenEnhancer();
    }

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

}

资源服务器配置:

@Configuration
@EnableResourceServer
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER-1)
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter{

    @Autowired
    TokenStore tokenStore;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.resourceId("resource").tokenStore(tokenStore);
    }
    @Override
    public void configure(final HttpSecurity http) throws Exception {
     http.authorizeRequests().antMatchers("/api/**").authenticated();
 }
}

您还可以在这里签出代码:https://github.com/cenobyte321/spring-oauth2-tokenenhancer-test/tree/webspeciallogin(分支:webspeciallogin)

问题是AdminSecurityConfig类中的所有内容都被忽略了,我可以在不登录的情况下进入Protected.html页面,并且没有创建指定的登录和注销处理URL。

另一方面,基于Oauth2的登录没有问题。我还没有弄清楚如何在Oauth2中指定AuthenticationManagerBuilder,大多数在线资源建议使用Oauth正确读取的configureGlobal注入方法,这就是为什么在上面的代码中设置它。

如何在一个启用oauth2的应用程序中配置两个彼此独立的身份验证源?

问候。

共有1个答案

仲绍晖
2023-03-14

你需要两件事:

>

  • 确保AdminSecurityConfig的优先级高于ResourceServerConfiguration。虽然@enableResourceServer注释的文档说它将用硬编码顺序3注册WebSecurityConfigurerAdapter,但它实际上在ResourceServerOrderProcessor中被重写,顺序为-10。因此,请确保AdminSecurityConfig的顺序低于-10。
  • 确保将AdminSecurityConfig中的HttpSecurity请求匹配器配置限制为与管理服务器相关联的URL,如下所示:

    http.requestMatchers().antMatchers("/admin/**", "/admin_login", "/admin_logout")
        .and()
            .authorizeRequests()
            .antMatchers("/admin/protected.html").hasRole("ADMIN")
            .antMatchers("/admin/login.html").permitAll()
        .and()
            .formLogin().loginPage("/admin/login.html")
            .loginProcessingUrl("/admin_login")
            .defaultSuccessUrl("/admin/protected.html")
        .and()
            .logout().logoutRequestMatcher(new AntPathRequestMatcher("/admin_logout"))
            .invalidateHttpSession(true).logoutSuccessUrl("/admin/login.html")
            ;
    

    注意嵌入代码的第一行http.requestmatchers().antmatchers(“/admin/**”,“/admin_login”,“/admin_logout”)

    参见Dave Syer(Spring Security的作者之一)对类似问题的回答以供参考。

    我在GitHub上为您的示例项目做了一个pull请求。

  •  类似资料:
    • 我正在尝试为自己构建一个仪表板,为我使用的一些应用程序提供基于SAML的身份验证。 从我作为测试平台构建的: 我正在使用一个登录名作为我要使用的应用程序的身份提供者。 举个例子:对于Netflix,我被重新路由到Netflix页面,我的用户ID和密码被预先填入其中,就像密码管理器的工作方式一样。(它使用OneLogin的扩展名) Netflix是否允许基于SAML的单点登录身份验证?我无法从谷歌搜

    • 本文向大家介绍拥有一个属于自己的javascript表单验证插件,包括了拥有一个属于自己的javascript表单验证插件的使用技巧和注意事项,需要的朋友参考一下 自己编写了一个表单验证插件,使用起来很简单,以后还可以扩展更多的功能,比如ajax验证。 每个需要验证的表单元素下面有一个span标签,这个标签的class有一个valid表示需要验证,如果有nullable则表示可为空;rule表示验

    • 我正在Spring Boot应用程序中学习Spring Security性,我试图了解默认情况下使用Spring Security性的身份验证方式。我知道Spring Security默认情况下使用基于表单的身份验证,但我使用基本身份验证对Postman进行了测试,结果正常。 我有一个非常简单的Spring Boot应用程序。 Rest控制器: 我在pom中添加了Spring Security依赖

    • 我之前已经在另一个项目中完成了通过Azure AD访问的资源的OAuth2过程,但无法解决如何请求授权代码和令牌以对git存储库进行编程操作的问题。docs.microsoft.com上的留档不清楚要访问哪些endpoint。例如,在与git存储库相关的页面上写有以下URL用于身份验证代码: https://app.vssps.visualstudio.com/oauth2/authorize 但

    • 在控制台中写入函数:anonymousUser true[ROLE_ANONYMOUS] 并且应该是user1 true[ROLE_USER]user1