2017-04-06 3 views
1

Ich schreibe eine RESTful Api mit Spring Boot. Ich benutze Spring Boot, Trikot, Mongo Db, Swagger, Spring Boot Sicherheit und JWT.Spring Boot, wie eine Benutzerrolle Verwaltung mit JWT

Ich habe die Modelle, die Repositories für die Anfragen an die DB geschrieben. Jetzt habe ich das Security und JWT Token integriert.

Jetzt muss ich die Rolle der Benutzer zu diskretisieren, weil ein Benutzer eine Route nicht anrufen kann, die ein Admin-Privilegien benötigen.

Ich habe eine Route für die Anmeldung, es gibt ein Token zurück. Dies ist der Code meiner SecurityConfig

... 
@Configuration 
@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter{ 

    @Autowired 
    UserRepository userRepository; 

    @Override 
    public void configure(HttpSecurity httpSecurity) throws Exception { 
     httpSecurity.csrf().disable().authorizeRequests() 
       .antMatchers("/").permitAll() 
       .antMatchers("/api/swagger.json").permitAll() 
       .antMatchers(HttpMethod.POST, "/login").permitAll() 
       .antMatchers("/api/*").authenticated() 
       .and() 

       .addFilterBefore(new JWTLoginFilter("/login", authenticationManager(), userRepository), 
         UsernamePasswordAuthenticationFilter.class) 

       .addFilterBefore(new JWTAuthenticationFilter(), 
         UsernamePasswordAuthenticationFilter.class); 
    } 

} 

ich die JWTLoginFilter geschrieben, dass mir das Token zurück, wenn Benutzer macht Login

... 
@Override 
public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) throws AuthenticationException, IOException, ServletException { 
    Credential creds = new ObjectMapper().readValue(req.getInputStream(), Credential.class); 

    User user = userRepository.login(creds); 

    if (user == null) 
     throw new BadCredentialsException(""); 

    UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
     creds.getUsername(), 
     creds.getPassword() 
    ); 

    return token; 
} 
... 

Ich möchte diese auf Verfahren auf meinem Endpunkt Klasse einfügen

@PreAuthorize("hasRole('ROLE_ADMIN')") 

Dies ist ein Teil eines Endpunkts

.... 

@Component 
@Path("story") 
@Api(value = "Story", produces = "application/json") 
public class StoryEndpoint { 

    private static final Logger LOGGER = LoggerFactory.getLogger(StoryEndpoint.class); 

    @Autowired 
    StoryRepository storyRepository; 


    @GET 
    @Path("/") 
    @Produces(MediaType.APPLICATION_JSON) 
    @PreAuthorize("hasRole('ROLE_ADMIN')") <--- I want insert here 
    @ApiOperation(value = "Get All Story", response = Story.class) 
    @ApiResponses(value = { 
      @ApiResponse(code = 200, message = "hello resource found"), 
      @ApiResponse(code = 404, message = "Given admin user not found") 
    }) 
    public Response getAllStory(){ 
     Iterable<Story> stories = storyRepository.findAll(); 
     LOGGER.info("getAllStory"); 
     return (stories!=null) ? Response.ok(stories).build() : Response.ok(ResponseErrorGenerator.generate(Response.Status.NOT_FOUND)).status(Response.Status.NOT_FOUND).build(); 
    } 
.... 

Wie kann ich einen Mechanismus für die Zuweisung an den Benutzer die Rolle und wie kann ich die Rolle in Token übergeben und Diskretisierung auf der Route die Rolle des Benutzers?

+0

Mischen Sie keine Behörden und Rollen (Behörden mit dem Präfix "ROLE_"), verwenden Sie entweder 'hasRole ('ADMIN') 'oder' hasAuthority (' ROLE_ADMIN ') '. –

Antwort

2

Sie benötigen Benutzerrollen innerhalb JWT Token als zusätzliche Ansprüche speichern, so dass sie nach dem Token-Validierung extrahieren und übergeben als ‚Behörden‘ für Auftraggeber:

Collection<? extends GrantedAuthority> authorities 
       = Arrays.asList(claims.get(AUTHORITIES_KEY).toString().split(",")).stream() 
       .map(authority -> new SimpleGrantedAuthority(authority)) 
       .collect(Collectors.toList()); 

     User principal = new User(claims.getSubject(), "", 
       authorities); 

     UsernamePasswordAuthenticationToken t 
       = new UsernamePasswordAuthenticationToken(principal, "", authorities); 
+0

Ich muss meine Benutzerklasse ändern? Ich habe den ersten Teil des Codes nicht verstanden. Wo füge ich diesen Code ein? @Alex Chemyshev –

+0

Der erste Teil des Codes handelt von der Extraktionsliste der Rollennamen, getrennt durch ','. Sie sollten diesen Code anstelle von 'UsernamePasswordAuthenticationToken token = new BenutzernamePasswordAuthenticationToken ( creds.getUsername(), creds.getPassword() );' –

+0

, aber Sie müssen auch eine Liste von Rollen in das JWT-Token hinzufügen, sonst wird es nicht funktionieren. Vielleicht hilft Ihnen die vollständige Lösung mit Spring & JWT auth besser: https://github.com/jhipster/jhipster-sample-app-token/blob/master/src/main/java/io/github/jhipster/sample/web /rest/UserJWTController.java –

Verwandte Themen