Центральный сервер аутентификации с несколькими клиентами, использующими учетные данные для пароля владельца ресурса. - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть следующие настройки:

  • Центральный сервер авторизации, написанный с пружинной загрузкой, который работает в данный момент (я могу свернуться и получить токен доступа, хранилище токенов jdbc и т. Д.)
  • Несколько приложений, принадлежащих одному разработчику, совместно использующих одну и ту же клиентскую базу в разных доменах.IE: John Doe для app1 - это то же самое, что John Doe для app2.

У меня есть существующее приложение (app1 выше), которое является jsf 2.2 с пружинной защитой, настроенной для целей входа в систему.Это приложение сейчас работает автономно, со своей собственной базой пользователей.

Это поток, который я пытаюсь получить: Учетная запись пароля владельца ресурса OAuth Flow

Итак, мыхотел бы:

  1. Пользователь заходит в приложение 1
  2. Пользователь вводит пользователя и пароль на страницу входа в приложение 1
  3. Пользователь нажимает кнопку "войти"
  4. В некотором родеКонфигурация в Spring будет принимать запрос loginByUsername, получать токен доступа с центрального сервера oauth
  5. Теперь у нас есть доступ к app1 - у пользователя может быть одна из трех ролей (ADMIN, USER, SUPERUSER).
  6. Когда они зайдут (скажем) в app1 / views / createEntry.xhtml, мы подтвердим, что токен доступа, который у нас есть, все еще активен на сервере аутентификации.
  7. Сервер ресурсов технически будет ресурсами на сервере app1 (верно?)

Я новичок в этом процессе oauth2.0 (и действительно весной), но я думаю,это поток, который я хочу.Как мне настроить это с помощью Spring Security?Я видел параметр безопасности с именем oauth2login (), который, как мне кажется, мы МОЖЕМ желать, но я думаю, что это больше потока кода авторизации.

Я не нашел очень хороший пример этого с использованием пароляпоток.

Я доверяю каждому из приложений в этом процессе, следовательно, поток паролей.Мы контролируем сеть, которая поддерживает трафик между сервером авторизации и другими приложениями.

Редактировать : SSO не подходит из-за требований и нашей клиентской базы.Приложения настолько уникальны, что это не имеет смысла, но пользователь должен иметь возможность войти в любое из наших приложений с этими учетными данными.

Edit 2 : Извините за второе редактирование.Я хотел бы добавить, что я добавил конфигурацию ресурса в app1, и на самом деле кажется, что она работает - я что-то защитил / views / *, и когда я пытаюсь перейти на их, я получаю ожидаемое сообщение «Требуется полная аутентификация».

Редактировать 3 : Я думаю, что я добился определенного прогресса -

Сначала я создал компонент Spring, который реализует AuthenticationProvider, а затем переписал метод authenticate, чтобы я создалобъект ResourceOwnerPasswordResourceDetails со всеми моими свойствами (идентификатор клиента, секрет клиента, тип предоставления, область и т. д.) и вызвал сервер авторизации для получения токена.Я был очень рад видеть, как обновляется мой журнал для сервера авторизации.

Следующий шаг, который мне нужно выяснить, - это как создать расширение org.springframework.security.core.userdetails.User, чтобы я мог сохранитьпривилегии для пользователя.

Также - я пока не могу понять, как хранится токен.Я знаю, что сервер аутентификации генерирует токен и сохраняет его в jdbc, но где / как токен хранится на стороне клиента?

1 Ответ

0 голосов
/ 13 декабря 2018

Для тех, кому было любопытно, вот как я настроил провайдера аутентификации на своем клиенте (app1).У меня все еще есть проблемы с сервером ресурсов (я задам отдельный вопрос), но вот что я сделал:

Пользовательский аутентификатор:

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private AppUserDAO appUserDAO;

    private String accessTokenUri = "http://localhost:8080/oauth/token";
    private String clientId = "clientid";
    private String clientSecret = "clientsecret";

    public AccessTokenProvider userAccessTokenProvider() {
        ResourceOwnerPasswordAccessTokenProvider accessTokenProvider = new ResourceOwnerPasswordAccessTokenProvider();
        return accessTokenProvider;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        final String username = authentication.getName();
        final String password = authentication.getCredentials().toString();

        List<String> scopes = new ArrayList<String>();
        scopes.add("read");

        final ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();

        resource.setUsername(username);
        resource.setPassword(password);
        resource.setAccessTokenUri(accessTokenUri);
        resource.setClientId(clientId);
        resource.setClientSecret(clientSecret);
        resource.setGrantType("password");
        resource.setScope(scopes);

        // Generate an access token
        final OAuth2RestTemplate template = new OAuth2RestTemplate(resource, new DefaultOAuth2ClientContext(new DefaultAccessTokenRequest()));
        template.setAccessTokenProvider(userAccessTokenProvider());

        OAuth2AccessToken accessToken = null;

        try {
            accessToken = template.getAccessToken();
            System.out.println("Grabbed access token from " + accessTokenUri);
        }
        catch (OAuth2AccessDeniedException e) {
            if (e.getCause() instanceof ResourceAccessException) {
                final String errorMessage = String.format(
                        "While authenticating user '%s': " + "Unable to access accessTokenUri '%s'.", username,
                        accessTokenUri);
                throw new AuthenticationServiceException(errorMessage, e);
            }
            throw new BadCredentialsException(String.format("Access denied for user '%s'.", username), e);
        }
        catch (OAuth2Exception e) {
            throw new AuthenticationServiceException(
                    String.format("Unable to perform OAuth authentication for user '%s'.", username), e);
        }

        // Determine roles for user
        List<GrantedAuthority> grantList = ...

        // Create custom user for the principal
        User user = .....

        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user, null /*dont store password*/, grantList);

        return token;
    }

    @Override
    public  boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}

Конфигурация безопасности:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomAuthenticationProvider authProvider;

    ....

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authProvider);
    }   
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...