Я не могу получить текущий пользовательский объект из Spring Security Context - PullRequest
0 голосов
/ 08 октября 2018

Я использую провайдера аутентификации LDAP (активный каталог) + фильтр авторизации JWT.

У меня есть пользовательский объект, реализующий UserDetails, также мой пользовательский сервис расширяет UserDetailsService.Но когда я делаю:

Usuario principal = (Usuario) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

Principal - это просто строка (имя пользователя), а не мой объект пользователя.

Это моя конфигурация:

SecurityConfig:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final LdapProperties ldapProperties;
    private final LdapUserMapper ldapUserMapper;
    private final UserService userService;


    public SecurityConfig(LdapProperties ldapProperties, LdapUserMapper ldapUserMapper, UserService userService) {
        this.ldapProperties = ldapProperties;
        this.ldapUserMapper = ldapUserMapper;
        this.userService = userService;
    }


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

        // Entry points
        http.authorizeRequests()
                .antMatchers(HttpMethod.POST, "/login").permitAll()
                .antMatchers(HttpMethod.GET, "/v2/api-docs",
                        "/configuration/ui",
                        "/swagger-resources",
                        "/configuration/security",
                        "/swagger-ui.html",
                        "/webjars/**",
                        "/swagger-resources/**",
                        "/swagger-ui.html").permitAll()
                        //TODO review
                .anyRequest().authenticated();

//        JwtWebSecurityConfigurer... TODO ?

        // Filters
        http.addFilter(new AuthenticationFilter(authenticationManager()));  // ldap
        http.addFilter(new AuthorizationFilter(authenticationManager()));   // jwt
        http.cors();
        http.csrf().disable();

        // No session will be created or used by spring security
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        // Need to provide Authorization header
        http.httpBasic();

    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(ldapAuthenticationProvider());
        auth.userDetailsService(userService);
    }





    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration corsConfiguration = new CorsConfiguration().applyPermitDefaultValues();
        corsConfiguration.setAllowedMethods(Arrays.asList(CorsConfiguration.ALL));
        //TODO configure properly
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfiguration);
        return source;
    }


    @Bean
    public AbstractLdapAuthenticationProvider ldapAuthenticationProvider() {

        String urls = "";
        for (String url : ldapProperties.getUrls()) {
            urls += url + " ";
        }
        urls = urls.trim();

        ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(
                ldapProperties.getBaseEnvironment().get("domain"),
                urls,
                ldapProperties.getBase()
        );
        provider.setUserDetailsContextMapper(ldapUserMapper); 
        provider.setConvertSubErrorCodesToExceptions(true);   
        // comment to connect as anonymous
        provider.authenticate(
                new UsernamePasswordAuthenticationToken(ldapProperties.getUsername(), ldapProperties.getPassword())
        );
        return provider;
    }
}

LdapUserMapper:

@Component
public class LdapUserMapper implements UserDetailsContextMapper {

    private final UserService userService;

    @Autowired
    public LdapUserMapper(UserService userService) {
        this.userService = userService;
    }


    @Override
    public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {

        Usuario result = (Usuario) userService.loadUserByUsername(username);
        //TODO compare roles ? set bloqueado ? ...
        return result;
    }

    @Override
    public void mapUserToContext(UserDetails userDetails, DirContextAdapter dirContextAdapter) {

    }
}

1 Ответ

0 голосов
/ 16 октября 2018

Это был мой фильтр авторизации.

    @Override
    protected void doFilterInternal(HttpServletRequest req,
                                    HttpServletResponse res,
                                    FilterChain chain) throws IOException, ServletException {

        String token = req.getHeader("Authorization");
        if (token != null && token.startsWith("Bearer ")) {
            token = token.replace("Bearer ", "");
            Authentication authentication = getAuthentication(token);
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }

        chain.doFilter(req, res);
    }

    private UsernamePasswordAuthenticationToken getAuthentication(final String token) {

        try {
            DecodedJWT decodedToken = JWT.require(Algorithm.HMAC512(jwtSecret)).build().verify(token);
            String username = decodedToken.getSubject();
            return new UsernamePasswordAuthenticationToken(username , null, new ArrayList<>());
        } catch (JWTVerificationException ex) {
            log.error(ex.getMessage());
        }

        return null;
    }

Я не знал, что передаю имя пользователя только как объект Principal.Поэтому я изменил это на следующее:

Usuario usuario = (Usuario) userService.loadUserByUsername(decodedToken.getSubject());

Я также удалил

auth.userDetailsService(userService);

Из AuthenticationManagerBuilder config.Это было неправильно.Мой поставщик аутентификации - LDAP, а не DB.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...