Реализация Spring RESTful Web Services с OAuth2 - сохранение идентификатора токена как сеанса идентификации - PullRequest
0 голосов
/ 18 мая 2018

Я реализовал Spring RESTful Web Services с OAuth2 в Spring Boot с токеном id:

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.annotation.Order;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
    import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
    import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
    import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
    import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
    import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
    import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
    import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;


@Configuration
public class ResourceServerConfig {

    private static final String SERVER_RESOURCE_ID = "oauth2-server";
    private static final Logger LOG = LoggerFactory.getLogger(ResourceServerConfig.class);
    private static InMemoryTokenStore tokenStore = new InMemoryTokenStore();

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Configuration
    @EnableResourceServer
    @Order(2)
    protected class ResourceServer extends ResourceServerConfigurerAdapter {

        @Override
        public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
            LOG.info("ResourceServerSecurityConfigurer");
            resources.tokenStore(tokenStore).resourceId(SERVER_RESOURCE_ID);
        }

        @Override
        public void configure(HttpSecurity http) throws Exception {
            LOG.info("HttpSecurity");
            http.anonymous().disable().
                requestMatchers().antMatchers("/v1/**").
                and().authorizeRequests().antMatchers("/v1/**").authenticated();
        }
    }

    @Configuration
    @EnableAuthorizationServer
    @Order(1)
    protected class AuthConfig extends AuthorizationServerConfigurerAdapter {

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            LOG.info("AuthorizationServerEndpointsConfigurer");
            endpoints.userDetailsService(userDetailsService)
            .authenticationManager(authenticationManager).tokenStore(tokenStore).approvalStoreDisabled();
        }

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            LOG.info("ClientDetailsServiceConfigurer: {}", clients);
            clients.inMemory().withClient("client").authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit", "client_credentials")
                    .authorities("ROLE_CLIENT").scopes("read").resourceIds(SERVER_RESOURCE_ID).secret("secret");
        }


    }
}

Я использую балансировщик нагрузки для маршрутизации аутентификации и запроса вызовов, но id_token не одинаков для всехсерверы, поскольку id_token сохраняется только в памяти, и когда пользователь вызывает аутентификацию, он имеет id_token1 с сервера 1, а когда вызывает запрос, возможно, маршрут балансировки нагрузки на сервер 2 и здесь не существует id_token1.Вариант для решения этой проблемы - использовать Redis (например) для сохранения id_token, другой вариант также может использовать JWT.Поскольку я использую WebSphere в качестве серверного приложения , я бы хотел использовать идентификатор сеанса , чтобы сохранить id_token на всех серверах, я не думаю, что это может быть хорошей идеей, но все же я хочу реализовать это решение, не так ли?есть идеи, как можно реализовать это решение?

enter image description here

1 Ответ

0 голосов
/ 18 мая 2018

Вы уже знаете свои два варианта.Если ваша идея состоит в том, чтобы сделать приложение не имеющим состояния, я бы предложил JWT.Тем не менее, это требует дополнительной защиты JWT, чтобы вы не открывали свой токен, поскольку все будет на стороне клиента.Одним из основных преимуществ использования JWT является то, что вам не нужно беспокоиться о дополнительных серверах / ресурсах, которые вам нужно будет предоставить серверу redis.

...