2017-11-22 3 views
0

Ich verwende Spring Security, um Benutzer zu authentifizieren. Ich brauche zu lösen, welcher Benutzer in meinem ApplicationConfiguration die richtigen Daten zur Verfügung zu stellen authentifiziert hat, aber aus irgendeinem Grund, der folgende Code gibt null:erhalten authentifizierten Benutzer in der Konfigurationsklasse im Frühjahr

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

EDIT: Ich möchte im Grunde zu injizieren ein Service in einen Controller. (PackagesBaseService)

Dieser Service ist abstrakt, so in meiner Bean-Definition (In Konfigurationsklasse) Ich brauche zu lösen, wenn PackagesBaseService ist eine Instanz TablePackagesService oder DeskPackagesService. Dies basiert darauf, welcher Benutzer authentifiziert wurde (diese Anforderung kann nicht geändert werden).

Ich verstehe, ich könnte nur den authentifizierten Benutzer sogar in meinem Controller testen und meinen Dienst dort instanziieren, aber ich möchte das vermeiden.


Ich bin jedoch in der Lage, den Auth-Benutzer, der das selbe von irgendwo anders verwendet, zu holen.

Warum kann ich das nicht aus einer Konfigurationsdatei verwenden? Hat es etwas mit der Reihenfolge, in der die Beans geladen sind?

Wie kann ich das lösen?

Umsetzung:

Konfiguration:

@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 

} 

Controller:

@Autowired 
PackagesBaseService packagesService; 

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

    return response; 
} 
+0

In welchem ​​Zusammenhang versuchen Sie, dies zu tun? Sie erhalten nur dann eine Authentifizierung, wenn sie sich in einem Kontext befindet, der durch eine Benutzeraktion aufgerufen wird (z. B. HTTP-Anforderung). Kannst du die ganze Klasse/Methode posten? –

+0

Ich möchte einen 'PackagesBaseService' in meine Dienste einfügen: und ich benutze den authentifizierten Benutzer, um zu entscheiden, ob ich einen 'TablePackagesService' oder einen 'DeskPackagesService' zurückgeben soll. –

+0

@dur Danke! Klar, das würde erklären, warum es nicht funktioniert. =/Nachdenken über eine Lösung für mein Problem jetzt. –

Antwort

1

Sie müssen sich mit einem Werk gehen zu können, den Benutzerkontext verwenden. Dies könnte wie folgt aussehen: eine Fabrik Bohne definieren:

@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); 
    } 
} 

und verwendet es auf diese Weise

@Autowired 
PackageBaseServiceFactory packageBaseServiceFactory; 

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

    return response; 
} 
Verwandte Themen