Авторизуйтесь с Ldap и OAtuh2 с помощью microbo services springboot - PullRequest
0 голосов
/ 19 марта 2020

Я новичок в Springboot и микро-сервисах, я был готов войти в систему с помощью ldap и затем вернуть токен jwt, ничего из другого мира, он состоит из двух микро-сервисов, один для аутентификации с помощью ldap и генерации токена и еще один для получения дополнительной информации из базы данных с именем пользователя.

Теперь новая проблема заключается в том, что меня попросили split этот two микро сервис в three, one for login with ldap, one for getting the extra info и one for the authentication and generate the token

мой код выглядит следующим образом:

В папке конфигурации у меня есть три файла

AuthorizationServerConfig. java

этот файл генерирует и конфигурирует токен

@RefreshScope
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private Environment env;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private InfoToken infoToken;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        tokenEnhancerChain.setTokenEnhancers(Arrays.asList(accessTokenConverter()));
        endpoints.authenticationManager(authenticationManager).tokenStore(tokenStore())
                .accessTokenConverter(accessTokenConverter()).tokenEnhancer(tokenEnhancerChain);
    }

    @Bean
    public JwtTokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        final JwtAccessTokenConverter converter = new JwtAccessTokenConverter() {
            @Override
            public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
                if (authentication.getOAuth2Request().getGrantType().equalsIgnoreCase("password")) {

                    ((DefaultOAuth2AccessToken) accessToken)
                            .setAdditionalInformation(infoToken.adicionalInfo(authentication.getName()));
                }
                accessToken = super.enhance(accessToken, authentication);
                ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(new HashMap<>());
                return accessToken;
            }
        };
        converter.setSigningKey(env.getProperty("config.security.oauth.jwt.key"));
        return converter;
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {

        security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()")
                .allowFormAuthenticationForClients();
        ;
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

        clients.inMemory().withClient(env.getProperty("config.security.oauth.client.id"))
                .secret(passwordEncoder.encode(env.getProperty("config.security.oauth.client.secret")))
                .scopes("read", "write").authorizedGrantTypes("password", "refresh_token")
                .accessTokenValiditySeconds(3600).refreshTokenValiditySeconds(3600);
    }
}

InfoToken. java

этот файл добавляет дополнительную информацию к токену

@Component("infoToken")
public class InfoToken {

    @Autowired
    private IUserService repo;

    public Map<String, Object> adicionalInfo(String username) {
        Map<String, Object> info = new HashMap<String, Object>();
        Map<String, Object> r = new HashMap<String, Object>();

        User user = repo.getByUsername(username);
        List<Role> roles = user.getRoles();

        for (Role role : roles) {
            r.put(role.getName(), role.getModules().stream().map(x -> x.getName()).toArray());
        }

        info.put("name", user.getName());
        info.put("lastname", user.getLastname());
        info.put("email", user.getEmail());
        info.put("roles", r);
        return info;
    }

SpringSecurityConfig. java

и, наконец, этот файл

@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userServices;

    @Value("${ldap.urls}")
    private String ldapUrls;

    @Value("${ldap.base.dn}")
    private String ldapBaseDn;

    @Value("${ldap.username}")
    private String ldapSecurityPrincipal;

    @Value("${ldap.password}")
    private String ldapPrincipalPassword;

    @Value("${ldap.user.dn.pattern}")
    private String ldapUserDnPattern;

    @Value("${ldap.enabled}")
    private String ldapEnabled;

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    @Autowired
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.ldapAuthentication().contextSource().url(ldapUrls + ldapBaseDn).managerDn(ldapSecurityPrincipal)
                .managerPassword(ldapPrincipalPassword).and().userDnPatterns(ldapUserDnPattern);
    }

    @Override
    @Bean
    protected AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/oauth/**").permitAll()
                .antMatchers(HttpMethod.GET, "/api/products/productslist", "/api/items/list", "/api/users/users")
                .permitAll()
                .antMatchers(HttpMethod.GET, "/api/products/product/{id}", "/api/item/product/{id}/{quantity}}",
                        "/api/users/users")
                .hasAnyRole("ADMIN", "USER").antMatchers("/api/products/**", "/api/item/**", "/api/users/**")
                .hasRole("ADMIN").anyRequest().authenticated().and().cors()
                .configurationSource(corsConfigurationSource());
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin("*");
        config.setAllowedMethods(Arrays.asList("DELETE", "GET", "POST", "PUT", "OPTIONS"));
        config.setAllowCredentials(true);
        config.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);

        return source;
    }

    @Bean
    public FilterRegistrationBean<CorsFilter> corsFilter() {
        FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<CorsFilter>(
                new CorsFilter(corsConfigurationSource()));
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE);

        return bean;
    }
}

В папке services . получил эти два файла

IUserService. java

Простой интерфейс * 1 044 *

public interface IUserService {

    public User getByUsername(String username);
}

UserService. java

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

@Service
public class UserService implements IUserService, UserDetailsService {

    private Logger log = LoggerFactory.getLogger(UserService.class);

    @Autowired
    private IUserFeignClient client; //this is the feign client interface where I call the user micro service to get the extra info base on the user name

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        try {

            User user = client.getByUsername(username); //this is the method i call with the feign client to get the user extra info

            List<GrantedAuthority> authorities = user.getRoles().stream()
                    .map(a -> new SimpleGrantedAuthority(a.getName()))
                    .peek(authority -> log.info("Role: " + authority.getAuthority())).collect(Collectors.toList());

            log.info("User: " + username);

            return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
                    user.getEnabled(), true, true, true, authorities);
        } catch (FeignException e) {
            log.error("User not found '" + username + "' ");
            throw new UsernameNotFoundException("User not found '" + username + "' ");
        }
    }

    @Override
    public User getByUsername(String username) {

        return client.getByUsername(username);
    }

}

эта функция в SpringSecurityConfig. java file

@Override
    @Autowired
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.ldapAuthentication().contextSource().url(ldapUrls + ldapBaseDn).managerDn(ldapSecurityPrincipal)
                .managerPassword(ldapPrincipalPassword).and().userDnPatterns(ldapUserDnPattern);
    }

Позволяет мне отправить входящий x- www-form-urlencoded в ldap Завершите сеанс и войдите в систему. Меня попросили переместить это в другой микро-сервис, где я все еще авторизируюсь с помощью ldap, но затем возвращаю true в случае успеха или false в случае неудачи.

создание результирующей структуры

enter image description here

И вот мой вопрос, как мне это сделать?

auth micro serive must получите x- www-form-urlencoded, а затем передайте его микросервису ldap, получите ответ, и если true, позвоните другой микросервису, получите дополнительную информацию, сгенерируйте токен и верните его.

У меня есть отдельная часть Микро сервис ldap уже, но я понятия не имею, как подключиться проверьте их и передайте информацию, кстати, я использую feign для соединения между микро сервисами

...