#java #spring-security #single-sign-on #openam
#java #spring-безопасность #единый вход #openam
Вопрос:
Я пытаюсь разработать веб-приложение, используя интерфейс с angular2 и серверную часть REST с spring boot.
Мне нужно управлять 3 типами аутентификации: — базовое сопоставление логина и пароля с базой данных — аутентификация ldap — аутентификация единого входа
Когда пользователь проходит проверку подлинности, серверная часть генерирует JWT и отправляет его во внешний интерфейс. Все запросы должны содержать jwt в заголовке для связи с REST.
На данный момент моя конфигурация веб-безопасности :
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableTransactionManagement
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
private static final String LDAP_AUTHENTIFICATION = "ldap";
private static final String SSO_AUTHENTIFICATION = "sso";
@Autowired
private DataBaseAuthentificationProvider authProvider;
@Value("${ldap.provider.url}")
private String ldapProviderUrl;
@Value("${ldap.user.dn.patterns}")
private String userDnPatterns;
@Value("${authentification.type}")
private String authentificationType;
public WebSecurityConfiguration() {
/*
* Ignores the default configuration, useless in our case (session
* management, etc..)
*/
super(true);
}
/**
* Configure AuthenticationManagerBuilder to use the specified
* DetailsService.
*
* @param auth
* the {@link AuthenticationManagerBuilder} to use
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
if (StringUtils.equals(authentificationType, LDAP_AUTHENTIFICATION)) { // LDAP
auth.ldapAuthentication().userDnPatterns(userDnPatterns).contextSource().url(ldapProviderUrl);
} else if (StringUtils.equals(authentificationType, SSO_AUTHENTIFICATION)) { // SSO
} else { // Database
auth.authenticationProvider(authProvider);
}
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
/*
* Overloaded to expose Authenticationmanager's bean created by
* configure(AuthenticationManagerBuilder). This bean is used by the
* AuthenticationController.
*/
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
/*
* the secret key used to signe the JWT token is known exclusively by
* the server. With Nimbus JOSE implementation, it must be at least 256
* characters longs.
*/
String secret = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("secret.key"),
Charset.defaultCharset());
httpSecurity.addFilterAfter(jwtTokenAuthenticationFilter("/**", secret), ExceptionTranslationFilter.class)
.addFilterBefore(new SimpleCORSFilter(), CorsFilter.class)
/*
* Exception management is handled by the
* authenticationEntryPoint (for exceptions related to
* authentications) and by the AccessDeniedHandler (for
* exceptions related to access rights)
*/
.exceptionHandling().authenticationEntryPoint(new SecurityAuthenticationEntryPoint())
.accessDeniedHandler(new RestAccessDeniedHandler()).and()
/*
* anonymous() consider no authentication as being anonymous
* instead of null in the security context.
*/
.anonymous().and()
/* No Http session is used to get the security context */
.sessionManagement().sessionCreationPolicy(STATELESS).and().authorizeRequests()
/*
* All access to the authentication service are permitted
* without authentication (actually as anonymous)
*/
.antMatchers("/auth/**").permitAll()
/*
* All the other requests need an authentication. Role access is
* done on Methods using annotations like @PreAuthorize
*/
.anyRequest().authenticated().and().addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class).csrf()
.csrfTokenRepository(csrfTokenRepository()).disable();
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN"); // this is the name angular
// uses by default.
return repository;
}
private JwtTokenAuthenticationFilter jwtTokenAuthenticationFilter(String path, String secret) {
return new JwtTokenAuthenticationFilter(path, secret);
}
Критической точкой является SSO :
Поведение, которое я хотел бы, заключается в следующем :
Клиент запрашивает защищенный ресурс REST:
- если пользователь уже зарегистрирован OpenAM => вернуть запрошенный ресурс
- если пользователь еще не зарегистрирован => пользователь перенаправляется на OpenAM и предоставляет свои учетные данные => пользователь может получить доступ к ресурсу
Сначала я установил OpenAM на виртуальной машине, создал провайдеров SAMLv2 и получил свой idp.xml .
Я пытаюсь использовать https://github.com/vdenotaris/spring-boot-security-saml-sample чтобы добавить аутентификацию единого входа, но это не удается.
Кто-нибудь может дать мне инструкции по интеграции этого в мою конфигурацию веб-безопасности?
Спасибо!
Комментарии:
1. В чем ваша ошибка? Недавно я установил сервер OpenAM и испытал некоторое разочарование, но, наконец, смог заставить его работать (с OpenSAML)
2. Нет ошибки Я не понимаю, как интегрировать opnsaml в мою конфигурацию аутентификации, чтобы иметь 3 типа аутентификации.
3. Привет, вам удалось решить вашу проблему? Можете ли вы опубликовать несколько указателей?
Ответ №1:
Я бы придерживался использования JWT, а не SAML, это усложняет работу без каких-либо преимуществ, есть множество примеров того, как защитить службу REST с помощью JWT, а openam поддерживает OIDC, который предоставляет токены JWT.
Некоторые полезные ссылки: