Spring Security Token Auth Manager с автоматическим подключением - PullRequest
0 голосов
/ 15 октября 2018

У меня проблема с попыткой интегрировать аутентификацию токена с Spring Security в существующий проект Spring + Hibernate.

Я создал Entity для пользователя (User), DAO (UserDAO) и Сервиса(UserService).Затем я создал фильтр и применил его в web.xml:

<filter>
    <filter-name>springSecurityTokenFilter</filter-name>
    <filter-class>com.ivt.da.security.TokenAuthenticationFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>springSecurityTokenFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Вот код фильтра:

public class TokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

public TokenAuthenticationFilter() {
    super("/**");
    this.setAuthenticationManager(new TokenAuthenticationManager()); // <-------- here's a problem
    setAuthenticationSuccessHandler((request, response, authentication) ->
    {
        SecurityContextHolder.getContext().setAuthentication(authentication);
        request.getRequestDispatcher(request.getServletPath() + request.getPathInfo()).forward(request, response);
    });
    setAuthenticationFailureHandler((request, response, authenticationException) -> {
        response.getOutputStream().print(authenticationException.getMessage());
    });
}

@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
        throws AuthenticationException, IOException, ServletException {
    String token = request.getHeader("token");
    if (token == null)
        token = request.getParameter("token");
    if (token == null) {
        TokenAuthentication authentication = new TokenAuthentication(null);
        authentication.setAuthenticated(false);
        return authentication;
    }
    TokenAuthentication tokenAuthentication = new TokenAuthentication(token);
    Authentication authentication = getAuthenticationManager().authenticate(tokenAuthentication);
    return authentication;
}

@Override
public void doFilter(ServletRequest req, ServletResponse res,
                     FilterChain chain) throws IOException, ServletException {
    super.doFilter(req, res, chain);
}

Проблема заключается в том, что мне нужно установить собственный диспетчер проверки подлинности.Но созданный мной Диспетчер использует службу, которая должна быть подключена автоматически:

@Service
public class TokenAuthenticationManager implements AuthenticationManager {

@Autowired
private UserService usersService;

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    try {
        if (authentication instanceof TokenAuthentication) {
            TokenAuthentication readyTokenAuthentication = processAuthentication((TokenAuthentication) authentication);
            return readyTokenAuthentication;
        } else {
            authentication.setAuthenticated(false);
            return authentication;
        }
    } catch (Exception ex) {
        if(ex instanceof AuthenticationServiceException)
            throw ex;
    }
    return null;
}

private TokenAuthentication processAuthentication(TokenAuthentication authentication) throws AuthenticationException {
    String token = authentication.getToken();
    String key = Base64.getEncoder().encodeToString("here gonna be a secret key".getBytes());
    DefaultClaims claims;
    // ...
    // tokenParsingThings
    // ...
    Date expiredDate = new Date(claims.get("token_expiration_date", Long.class));
    if (expiredDate.after(new Date()))
        return buildFullTokenAuthentication(authentication, claims);
    else
        throw new AuthenticationServiceException("Token expired date error");
}

@Transactional
public TokenAuthentication buildFullTokenAuthentication(TokenAuthentication authentication, DefaultClaims claims) {
    User user = usersService.loadUserByUsername(claims.get("USERNAME", String.class)); // <--- NPE, cuz service has not been autowired
    if (user.isEnabled()) {
        Role role = user.getRole();
        List<String> roles = new ArrayList<>();
        roles.add(role.getRole());
        Collection<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority(role.getRole()));
        TokenAuthentication fullTokenAuthentication =
                new TokenAuthentication(authentication.getToken(), authorities, true, user);
        return fullTokenAuthentication;
    } else {
        throw new AuthenticationServiceException("User disabled");
    }
}

Я знаю, что она не подключает Службу автоматически, потому что я создаю объект Manager с использованием оператора new вФильтр конструктор.Однако я не могу внедрить (или могу?) Настройку Auth Manager, используя также @Autowire, поскольку класс Filter не является компонентом, который допускает использование этой аннотации.

Класс обслуживания должен быть подключен автоматически, поскольку онDAO внедрен, и DAO имеет сессию и так далее, поэтому я не могу просто создать UserServiceImpl вручную, используя new

Кроме того, важно использовать конфигурацию XML, потому что весь проектиспользует XML-конфиги.

Есть ли способ сделать TokenAuthenticationManager доступным со всем, что внутри автоматически подключено?Может быть, я могу передать параметр TokenAuthenticationManager в фильтр в качестве аргумента конструктора или что-то в этом роде.Пожалуйста, помогите с этим.

Заранее спасибо

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