2017-04-06 48 views
1

我正在使用spring引导写一个RESTful api。 我使用的是spring boot,jersey,mongo db,swagger,spring boot security和jwt。Spring引导如何使用jwt管理用户角色

我已经将模型,请求的存储库写入数据库。现在我已经集成了安全性和jwt令牌。

现在我需要离散用户的角色,因为用户不能调用需要管理员权限的路由。

我有一个登录路由,它返回一个令牌。这是

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

} 

我写了回我的令牌JWTLoginFilter我SecurityConfig的代码,当用户进行登录

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

我想在方法上我的端点类插入此

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

这是一个端点的一部分

.... 

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

我怎样才能让一个机制分配给用户的角色,以及我可以如何传递角色在令牌和离散路径上的用户角色?

+0

不要混合权限和角色(即具有“ROLE_”前缀的权限),使用hasRole('ADMIN')或hasAuthority('ROLE_ADMIN')'。 –

回答

2

您需要存储里面JWT令牌作为附加的权利要求的用户角色,令牌验证后提取出来,并通过作为“当局对校长:

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

我需要修改我的用户类?我还没有理解代码的第一部分。 我在哪里插入这段代码? @Alex Chemyshev –

+0

代码的第一部分是关于角色名称的提取列表,由','分隔。你应该把这个代码,而不是 'UsernamePasswordAuthenticationToken令牌=新UsernamePasswordAuthenticationToken( creds.getUsername(), creds.getPassword() );' –

+0

但您还需要将角色列表添加到JWT令牌中,否则它将无法工作。也许Spring和JWT认证的完整解决方案可以帮助您更好地实现:https://github.com/jhipster/jhipster-sample-app-token/blob/master/src/main/java/io/github/jhipster/sample/web /rest/UserJWTController.java –