具有Spring Security的多基本身份验证

时间:2020-07-28 08:39:15

标签: java spring spring-security

我想使用基本身份验证,但我不仅需要在UserDetailsService中使用用户名,还需要在标头中使用某些信息(标头包含用户类型)。
这是因为我有2个具有相同名称但具有varios类型的用户。例如,我有name:user1 type:USER psw: 1name:user1 type:PLAYER psw:1。因此,当我以第一用户身份登录时,我应该使用name=user1type=USER在db用户中进行搜索,但是UserDetailsService只有这种方法loadUserByUsername(String login)
那我该怎么办呢?

我的UserDetailsService

public class UserDetailsService implements org.springframework.security.core.userdetails.UserDetailsService {

    private final UserService userService;

    @Override
    @Transactional
    public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {
        return userService.findUserDetailsByLogin(login).orElseThrow(() -> new UsernameNotFoundException(login));
    }
}

2 个答案:

答案 0 :(得分:1)

我的解决方案是使用静态上下文。使用CustomFilter创建一个上下文,然后在loadUserByUsername方法中使用它

@Component
@RequiredArgsConstructor
public class TypeFilter extends OncePerRequestFilter {
   private final TypeService typeService;
   private final ObjectMapper mapper;

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
        throws ServletException, IOException {
    String uri = request.getRequestURI();
    if (!uri.contains("/login") && !uri.contains("/password")) {
        chain.doFilter(request, response);
        return;
    }

    String headerValue = request.getHeader(TYPE);

    if (StringUtils.isBlank(headerValue)) {
       response.setStatus(HttpStatus.BAD_REQUEST.value());
        return;
    }

    try {
        Type type = type Service.findByValue(headerValue);
        TypeContext.setCurrentType(type);
        chain.doFilter(request, response);
    } catch (MyException e) {
       response.setStatus(HttpStatus.BAD_REQUEST.value());
    }
}

}

我的配置:

 @Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .addFilterBefore(typeFilter, BasicAuthenticationFilter.class)

然后我在UserDeatilsService中使用上下文:

public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {
    Type type = TypeContext.getCurrentType();
    return userService.findUser(login, type).orElseThrow(() -> new UsernameNotFoundException(login));
}

答案 1 :(得分:-1)

您可以将loadUserByUsername(String login)方法扭曲为其他方法。并使用@RequestHeader("YourHeader")提取所需的其他信息。