-1

Ich verwende Spring Security in meiner Anwendung. Ich authentifiziere APIs basierend auf der Rolle (ADMIN, USER). Es gibt einen API-Endpunkt, auf den ich den Zugriff beschränken möchte, indem ich den Wert einer Variablen verwende, die als Parameter an ihn übergeben wurde.Spring Security mit Wert der Variablen in der Klasse zu authentifizieren

Ich habe

@Override 
protected void configure(HttpSecurity httpSecurity) throws Exception { 

    httpSecurity.csrf().disable().exceptionHandling().authenticationEntryPoint(this.unauthorizedHandler).and() 
      .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests() 
      .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() 
      .antMatchers("/api/**").authenticated() 
      .anyRequest().permitAll(); 

    httpSecurity.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class); 
} 

Ich habe einen Anruf

@PostMapping("/something") 
public ResponseEntity<BotResponse> handleRequest(@Valid @RequestBody SomeClass someClass) { 
     // if someClass.getSomeValue() is not present in the User permissions, then it should give an unauthorized response. 
     return value(someClass); 
} 

Der Nutzer in Spring Security ist:

public Class User { 
    String userId; 
    String userName; 
    String authorities; 
    List<String> someList; 
    //Getters and setters for variables 
} 

Und die Someclass verwendet wird:

public Class SomeClass { 
    String someValue; 
    String userName; 
    ... 
    // Getters and Setters 
} 

Wie erlaube ich Benutzern nicht basierend darauf, ob der Wert von someClass.getSomeValue in der someList von User vorhanden ist?

Antwort

0

Gemäß Ihrer Frage wäre ein Ansatz, die UserDetails in Ihrem Spring Security Authentication Context zu speichern und dann die betroffenen Daten in diesem Kontextobjekt mit dem Wert zu vergleichen, der als Parameter übergeben wurde. Ich nehme an, dass Sie alle erforderlichen Werte im Sicherheitskontext gespeichert haben.
Diese Überprüfung kann im Endpunktcode selbst vorgenommen werden (wenn Sie eine kleine Anzahl solcher APIs haben). Wenn es mehrere APIs gibt, die dieselbe Logik benötigen, müssen Sie entweder einen Filter implementieren, der nur diese API filtert (config kann in web.xml geschrieben werden) oder eine Pointcut (über AOP).

0

Vielleicht könnten Sie eine solche Autorisierung mit der globalen Methodensicherheit des Frühlings machen.

Um die Methode Level Authorization zu verwenden, müssen Sie Ihrer Klasse für die Sicherheitskonfiguration die folgende Annotation hinzufügen.

@EnableGlobalMethodSecurity(prePostEnabled = true) 

Dann bewerben @PreAuthorize Frühling Expression Language verwenden, zu Ihrem Endpunkt. So etwas wie ..

@PostMapping("/something") 
@PreAuthorize("@someService.checkUserAccess(principal, #someClass)") 
public ResponseEntity<BotResponse> handleRequest(@Valid @RequestBody SomeClass someClass) { 
     // if someClass.getSomeValue() is not present in the User permissions, then it should give an unauthorized response. 
     return value(someClass); 
} 

@someService ist eine Bean, die Sie im Controller und definieren checkUserAccess() -Methode in dieser gewesen autowired würde. So etwas wie ..

public boolean checkUserAccess(Pricipal principal, SomeClass someClass) { 
     // here you can fetch your full user object from db or session (depending on your application architecture) 
     // apply what ever logic you want to apply, return true if user has access and false if no. 
} 

Note/Suggestion- Sie können diese checkUserAccess() Methode, um Ihren bestehenden Benutzer-Dienst hinzufügen, wenn Ihre Anwendung Design erlaubt es, und autowire Benutzerservice in der Steuerung.

Verwandte Themen