首页 > 解决方案 > Spring Security 无法识别哪个登录用户

问题描述

我将 Spring Security 添加到我的 Spring Boot 应用程序,但之后,身份验证过程服务器在下一个请求中无法识别同一用户。我将 Angular 5 用于 UI,也许 UI 端的这个问题可能会被要求不包括 cookie。帮助我,请理解为什么 Spring Security 无法识别已登录的用户。

在网页配置中:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers("/rest/user/login").permitAll();
    http.csrf().disable()
            .authenticationProvider(authenticationProvider())
            .exceptionHandling()
            .authenticationEntryPoint(unauthorizedHandler)
            .and()
            .formLogin()
            .permitAll()
            .loginProcessingUrl("/rest/user/login")
            .usernameParameter("username")
            .passwordParameter("password")
            .successHandler(logInSuccessHandler)
            .failureHandler(authFailureHandler)
            .and()
            .logout().permitAll()
            .logoutRequestMatcher(new AntPathRequestMatcher("/rest/user/logout", "POST"))
            .logoutSuccessHandler(logoutHandler)
            .and()
            .sessionManagement()
            .maximumSessions(1);

    http.authorizeRequests().anyRequest().authenticated();
}

会话管理器已激活.sessionManagement().maximumSessions(1);

并且身份验证完成成功我的实现通过登录名和密码UserDetailsService正确返回对象。User但是对这个控制器的下一个请求:

@GetMapping("/rest/list")
public RestList list() {
    ...
}

重定向到:

@Component
public class UnauthorizedHandler implements AuthenticationEntryPoint {
    @Override
    public void commence(
            HttpServletRequest request,
            HttpServletResponse response,
            AuthenticationException authException) throws IOException {

        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());
    }
}

我有登录检查器:

@Component
public class LoggedInChecker {
    public User getLoggedInUser() {
        User user = null;

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null) {
            Object principal = authentication.getPrincipal();
            // principal can be "anonymousUser" (String)
            if (principal instanceof UserDetailsImpl) {
                UserDetailsImpl userDetails = (UserDetailsImpl) principal;
                user = userDetails.getUser();
            }
        }
        return user;
    }
}

我用这个检查器UserService

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private LoggedInChecker loggedInChecker;

    @Override
    public User getUserByUsername(String username) {
        return userRepository.findByUsername(username);
    }

    @Override
    public List<String> getPermissions(String username) {
        User user = userRepository.findByUsername(username);
        return nonNull(user) ? user.getRoles().stream().map(Role::getRole).collect(toList()) : Lists.newArrayList();
    }

    @Override
    public User getCurrentUser() {
        return loggedInChecker.getLoggedInUser();
    }

    @Override
    public Boolean isCurrentUserLoggedIn() {
        // This place must call but nothing happening
        return nonNull(loggedInChecker.getLoggedInUser());
    }
}

我以为 Spring 会自动调用我UserSevice的检查授权。但是如何指定HttpSecurity有关会话的保存信息?

在 Angular 方面,我使用HttpClient

@Injectable()
export class CoreApi {
  private baseUrl = 'http://localhost:8080/rest/';

  constructor(public http: HttpClient) {
  }

  public get(url: string = ''): Observable<any> {
    return this.http.get(this.getUrl(url));
  }
}

也许您知道如何指定 Spring Security 来检查身份验证LoggedInChecker或其他方式,让我知道。谢谢你!

标签: javaspringspring-bootspring-securityangular5

解决方案


推荐阅读