Как Spring Security Filter работает с пользовательской аутентификацией и как сочетать ее с Servlet Filter? - PullRequest
1 голос
/ 10 июля 2019

Итак, у меня есть вопрос относительно Spring Security.Поэтому я хочу проверить аутентификацию с использованием настраиваемого заголовка, который затем я хочу проверить токен, указанный в настраиваемом заголовке, для повторного значения и установить объект данных в качестве учетных данных при пользовательской реализации токена абстрактной аутентификации.Я уже следовал учебному пособию в этой сети: https://shout.setfive.com/2015/11/02/spring-boot-authentication-with-custom-http-header/,, но я не могу обновить интерфейс аутентификации в SecurityContextHolder.getContext () (я устанавливаю учетные данные в своей реализации интерфейса аутентификации, но когда я получаю его вслужба, учетные данные нулевые).

Я также обнаружил другие проблемы, я на самом деле хочу заказать фильтр следующим образом:

ExceptionHandlerFilter (to catch exception error in the filter) -> Other filter or CustomWebSecurityConfigurerAdapter. 

Но когда URL-адрес совпадает с antMatcher, я обнаружил, чтоПриложение ExceptionHandlerFilter было пропущено приложением.

Я был очень смущен этим и не смог найти лучшего руководства по реализации пользовательской аутентификации с использованием Spring Security.Поэтому я хочу спросить, можете ли вы, ребята, рассказать мне, как работает Spring Security и как его объединить с фильтром?

Вот мой первый фильтр, который перехватывает исключение

@Component
@Order(0)
public class ExceptionHandlerFilter extends OncePerRequestFilter {

    private JaminExceptionHandler exceptionHandler;
    private ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    public ExceptionHandlerFilter(JaminExceptionHandler exceptionHandler) {
        this.exceptionHandler = exceptionHandler;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        try {
            filterChain.doFilter(request, response);
        } catch (Throwable exception) {
            ResponseEntity<?> responseEntity = this.exceptionHandler.handleException(exception, request);

            response.setStatus(responseEntity.getStatusCode().value());
            response.setHeader("Content-Type", "application/json");
            response.getWriter().write(this.objectMapper.writeValueAsString(responseEntity.getBody()));
        }
    }
}

Вот мой AuthФильтр

@Component
public class AuthFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        String token = request.getHeader("J-Auth");

        if (token != null) {
            Authentication auth = new JaminAuthenticationToken(token);
            SecurityContextHolder.getContext().setAuthentication(auth);
            filterChain.doFilter(request, response);
        } else {
            throw new JaminException("Not authorized", JaminExceptionType.NOT_AUTHORIZED, HttpStatus.UNAUTHORIZED);
        }
    }
}

Поставщик аутентификации

@Component
public class JaminAuthenticationProvider implements AuthenticationProvider {

    private RedisTemplate<String, String> authRedis;

    private ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    public JaminAuthenticationProvider(@Qualifier("authRedis") RedisTemplate<String, String> authRedis) {
        this.authRedis = authRedis;
    }

    private UserDTO getUserDTO(String token) throws IOException {
        String userData = this.authRedis.opsForValue().get(token);

        if (userData == null) {
            throw new JaminException("Not authorized", JaminExceptionType.NOT_AUTHORIZED, HttpStatus.UNAUTHORIZED);
        }

        return this.objectMapper.readValue(userData, UserDTO.class);
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        JaminAuthenticationToken auth = (JaminAuthenticationToken) authentication;

        try {
            UserDTO userDTO = this.getUserDTO(auth.getToken());
            auth.setCredentials(userDTO);

            return auth;
        } catch (IOException e) {
            e.printStackTrace();
        }

        throw new JaminException("Not authorized", JaminExceptionType.NOT_AUTHORIZED, HttpStatus.UNAUTHORIZED);
    }

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

WebSecurityConfigurerAdapter

@Configuration
@EnableWebSecurity
@Order(1)
public class JaminSecurityAdapter extends WebSecurityConfigurerAdapter {

    @Autowired
    private JaminAuthenticationProvider jaminAuthenticationProvider;

    private void disableDefaultSecurity(HttpSecurity http) throws Exception {
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.csrf().disable();
        http.formLogin().disable();
        http.logout().disable();
        http.httpBasic().disable();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        this.disableDefaultSecurity(http);
        http.antMatcher("/auth/check")
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .addFilterBefore(new AuthFilter(), BasicAuthenticationFilter.class);
//        http.authorizeRequests().anyRequest().permitAll();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(jaminAuthenticationProvider);
    }
}

1 Ответ

0 голосов
/ 10 июля 2019

Spring Security имеет несколько «до и после» шагов .Есть несколько обработчиков, которые могут помочь.Я не знаю ваш код, но если вы можете получить вашу аутентификацию в порядке, возможно, вам просто нужно расширить SuccessHandler и установить аутентификацию там, как я делал в моем блог-проекте :

if(checkEmail(authentication)) {

    val adminRole = SimpleGrantedAuthority("ROLE_ADMIN")
    val oldAuthorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities()
    val updateAuthorities = mutableListOf<GrantedAuthority>()
    updateAuthorities.add(adminRole)
    updateAuthorities.addAll(oldAuthorities)

    SecurityContextHolder.getContext().setAuthentication(UsernamePasswordAuthenticationToken(authentication.getPrincipal(),
                                                                                                authentication.getCredentials(),
                                                                                                updateAuthorities))
}

А насчет фильтров, может быть, вы можете найти свой ответ здесь.Я не люблю использовать фильтры и перехватчики, но иногда они действительно необходимы.

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