2017-04-06 64 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 –

相關問題