首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >具有自定义身份验证提供程序的OAUTH2用户服务

具有自定义身份验证提供程序的OAUTH2用户服务
EN

Stack Overflow用户
提问于 2021-12-02 06:20:45
回答 1查看 2.2K关注 0票数 7

我是Security和Oauth2的新手。在我的spring引导应用程序中,我使用Oauth2实现了身份验证,并进行了以下更改:

自定义Ouath2用户服务如下:

代码语言:javascript
运行
复制
  @Component
  public class CustomOAuth2UserService extends DefaultOAuth2UserService {

     private UserRepository userRepository;

     @Autowired
     public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
     }

    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
        ...
    }
 }

安全配置如下:

代码语言:javascript
运行
复制
@EnableWebSecurity
@Import(SecurityProblemSupport.class)
@ConditionalOnProperty(
        value = "myapp.authentication.type",
        havingValue = "oauth",
        matchIfMissing = true
)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
  private final CustomOAuth2UserService customOAuth2UserService;
    
  public SecurityConfiguration(CustomOAuth2UserService customOAuth2UserService) {
    this.customOAuth2UserService = customOAuth2UserService;
  }

  @Override
  public void configure(WebSecurity web) {
    web.ignoring()
        .antMatchers(HttpMethod.OPTIONS, "/**")
        .antMatchers("/app/**/*.{js,html}")
        .antMatchers("/bundle.js")
        .antMatchers("/slds-icons/**")
        .antMatchers("/assets/**")
        .antMatchers("/i18n/**")
        .antMatchers("/content/**")
        .antMatchers("/swagger-ui/**")
        .antMatchers("/swagger-resources")
        .antMatchers("/v2/api-docs")
        .antMatchers("/api/redirectToHome")
        .antMatchers("/test/**");
  }

  public void configure(HttpSecurity http) throws Exception {
    RequestMatcher csrfRequestMatcher = new RequestMatcher() {
      private RegexRequestMatcher requestMatcher =
          new RegexRequestMatcher("/api/", null);

      @Override
      public boolean matches(HttpServletRequest request) {
        return requestMatcher.matches(request);
      }
    };

    http.csrf()
        .requireCsrfProtectionMatcher(csrfRequestMatcher)
        .and()
        .authorizeRequests()
        .antMatchers("/login**").permitAll()
        .antMatchers("/manage/**").permitAll()
        .antMatchers("/api/auth-info").permitAll()
        .antMatchers("/api/**").authenticated()
        .antMatchers("/management/health").permitAll()
        .antMatchers("/management/info").permitAll()
        .antMatchers("/management/prometheus").permitAll()
        .antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
        .anyRequest().authenticated()//.and().oauth2ResourceServer().jwt()
        .and()
        .oauth2Login()
        .redirectionEndpoint()
        .baseUri("/oauth2**")
        .and()
        .failureUrl("/api/redirectToHome")
        .userInfoEndpoint().userService(oauth2UserService())
    ;
    http.cors().disable();
  }


  private OAuth2UserService<OAuth2UserRequest, OAuth2User> oauth2UserService() {
    return customOAuth2UserService;
  }
}

application.properties的内容如下:

代码语言:javascript
运行
复制
spring.security.oauth2.client.registration.keycloak.client-id=abcd
spring.security.oauth2.client.registration.keycloak.client-name=Auth Server
spring.security.oauth2.client.registration.keycloak.scope=api
spring.security.oauth2.client.registration.keycloak.provider=keycloak
spring.security.oauth2.client.registration.keycloak.client-authentication-method=basic
spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code
myapp.oauth2.path=https://internal.authprovider.com/oauth2/
spring.security.oauth2.client.provider.keycloak.token-uri=${myapp.oauth2.path}token
spring.security.oauth2.client.provider.keycloak.authorization-uri=${myapp.oauth2.path}authorize
spring.security.oauth2.client.provider.keycloak.user-info-uri=${myapp.oauth2.path}userinfo
spring.security.oauth2.client.provider.keycloak.user-name-attribute=name
myapp.authentication.type=oauth

现在,使用现有的身份验证机制,我想添加对多个身份验证提供者的支持: LDAP、Form等。

在这方面,我看了几篇文章:

  1. https://www.baeldung.com/spring-security-multiple-auth-providers
  2. Custom Authentication provider with Spring Security and Java Config

但是,我没有得到任何具体的想法,我应该做哪些改变,在现有的代码库,以实现这一点。

这里有人能帮忙吗?谢谢。

EN

Stack Overflow用户

回答已采纳

发布于 2021-12-07 11:06:15

我从您的代码开始创建了一个简化的设置,支持OAuth2和Basic。

/tenant2/**将启动基本身份验证。/** (其他一切)触发OAuth2授权代码身份验证。

实现这一目标的关键是每个身份验证类型都有一个@Configuration类。

让我们从控制器开始:

Tenant1HomeController

代码语言:javascript
运行
复制
@Controller
public class Tenant1HomeController {

    @GetMapping("/tenant1/home")
    public String home() {
        return "tenant1Home";
    }

}

Tenant2HomeController

代码语言:javascript
运行
复制
@Controller
public class Tenant2HomeController {

    @GetMapping("/tenant2/home")
    public String home() {
        return "tenant2Home";
    }

}

现在,配置类:

Tenant1SecurityConfiguration

代码语言:javascript
运行
复制
@Configuration
public class Tenant1SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/login**").permitAll()
                .antMatchers("/manage/**").permitAll()
                .antMatchers("/api/auth-info").permitAll()
                .antMatchers("/api/**").authenticated()
                .antMatchers("/management/health").permitAll()
                .antMatchers("/management/info").permitAll()
                .antMatchers("/management/prometheus").permitAll()
                .antMatchers("/management/**").hasAuthority("ADMIN")
                .antMatchers("/tenant1/**").authenticated()
                .and()
                .oauth2Login()
                .and()
                .cors()
                .disable();
    }
}

Tenant2SecurityConfiguration (注意@Order(90),这很重要

代码语言:javascript
运行
复制
@Order(90)
@Configuration
public class Tenant2SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.requestMatcher(new AntPathRequestMatcher("/tenant2/**"))
                .csrf()
                .disable()
                .authorizeRequests()
                .antMatchers("/tenant2/**").hasAuthority("BASIC_USER")
                .and()
                .httpBasic();
        http.cors().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user")
                .password("{noop}password")
                .roles("BASIC_USER");
    }
}

最后,配置:

代码语言:javascript
运行
复制
spring:
  security:
    oauth2:
      client:
        registration:
          keycloak:
            client-id: myclient
            client-secret: c6dce03e-ea13-4b76-8aab-c876f5c2c1d9
        provider:
          keycloak:
            issuer-uri: http://localhost:8180/auth/realms/myrealm

在此之后,如果我们点击http://localhost:8080/tenant2/home,将使用基本的auth弹出提示:

尝试使用http://localhost:8080/tenant1/home将您发送到Keycloak的登录表单:

更新:

使用上面的配置配置多租户应用程序是完全可行的。

关键是每个身份验证提供者与不同的一组用户(租户)一起工作,例如:

租户1 (OAuth2身份验证):

代码语言:javascript
运行
复制
@Configuration
public class Tenant1SecurityConfiguration extends WebSecurityConfigurerAdapter {

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

这个用户的第一个子集是由OAuth2提供程序(在本例中为Keycloak )联合起来的。

租户2(基本/表单/xxx身份验证):

代码语言:javascript
运行
复制
@Order(90)
@Configuration
public class Tenant2SecurityConfiguration extends WebSecurityConfigurerAdapter {

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

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(XXX)

对于第二个租户,您可以使用指向不同用户存储库(LDAP、数据库.)的userDetailsService。

票数 7
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70194951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档