在Spring

时间:2017-11-22 12:08:22

标签: java spring spring-mvc authentication spring-security

我正在使用Spring Security对用户进行身份验证。我需要解决在ApplicationConfiguration中经过身份验证的用户提供正确的数据,但由于某种原因,以下代码返回null

 Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

修改 我基本上想要将服务注入控制器。 (PackagesBaseService

这个服务是抽象的,所以在我的bean定义中(在配置类中)我需要解决PackagesBaseServiceTablePackagesServiceDeskPackagesService的实例。这取决于哪个用户已通过身份验证(此要求无法更改)。

我知道我甚至可以在我的控制器中测试Authenticated用户并在那里实例化我的服务,但我想避免这种情况。

我能够从其他任何地方检索使用此功能的Auth用户。

为什么我无法在配置文件中使用它?它是否与bean加载的顺序有关?

我该如何解决这个问题?

实施

配置:

@Bean
public PackagesBaseService packagesBaseService()
{
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

    if (authentication != null && !(authentication instanceof AnonymousAuthenticationToken)) {

        if (authentication.getName() == env.getProperty("tableFactory.username")) {
            return new TablePackagesService();
        }

        if (authentication.getName() == env.getProperty("deskFactory.username")) {
            return new DeskPackagesService();
        }

        // thrown Exception
    }

    // thrown Exception

}

控制器:

@Autowired
PackagesBaseService packagesService;

public MultiPackagesResponse data(@RequestParam("fromId") int fromId)
{
    MultiPackagesResponse response = packagesService.getPackages(fromId);

    return response;
}

1 个答案:

答案 0 :(得分:1)

您需要与工厂一起使用才能使用用户上下文。这个可能看起来像这样: 定义工厂bean:

@Service
public class PackageBaseServiceFactory {

    public final HashMap < String,
    PackageBaseService > packageBaseServiceCache = new HashMap();

    public PackageBaseService getPackageService() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null && !(authentication instanceof AnonymousAuthenticationToken)) {
            PackageBaseService packageBaseService = packageBaseServiceCache.get(authentication.getName());
            if (packageBaseService == null) {
                packageBaseService = initPackagesBaseService(authentication.getName());
            }
            return packageBaseService;
        }
    }

    private PackageBaseService initPackagesBaseService(String authenticationName) {
        PackageBaseService packageBaseService;
        if (authenticationName == env.getProperty("tableFactory.username")) {
            packageBaseService = new TablePackagesService();

        } else if (authenticationName == env.getProperty("deskFactory.username")) {
            packageBaseService = new DeskPackagesService();
        } else {
            throw new IllegalStateException(); //or whatever you do
        }
        return packageBaseServiceCache.put(authenticationName, packageBaseService);
    }
}

并以这种方式使用

@Autowired
PackageBaseServiceFactory packageBaseServiceFactory;

public MultiPackagesResponse data( @ RequestParam("fromId")int fromId) {
    MultiPackagesResponse response = packageBaseServiceFactory.getPackageService().getPackages(fromId);

    return response;
}