2015-09-01 29 views
1

我使用Spring @RolesAllowed來保護我的API(方法),但我想更改從未授權用戶調用方法時發生的情況。目前的行爲是Spring引發HTTP 403錯誤。這很好,但我只是想在403響應的主體中添加一個額外的錯誤代碼,以便能夠區分不同場景中的拒絕訪問錯誤。修改Spring @RolesAllowed的行爲

我很難搞清楚@RolesAllowed註釋的實現位於何處。有沒有人遇到過它?或試圖修改其行爲?

在我的控制器的方法目前看起來如下:

@RolesAllowed({"ROLE_DEFENDANT", "ROLE_ADMIN"}) 
@RequestMapping(method = RequestMethod.POST, value = "/{caseId}/owner") 
public ResponseEntity<?> assignOwner(@PathVariable String caseId) { 

    // method implementation 

} 

回答

1

你正在嘗試做的,可以在不修改批註來完成。

在您的Spring配置中,您可以指定一個AccessDeniedHandler bean,當Spring Security確定您的用戶不被允許執行他們嘗試執行的操作時將被調用。

訪問被拒絕的處理程序是非常簡單的:

public class CustomDefaultAccessDeniedHandler implements AccessDeniedHandler { 
    @Override 
    public void handle(HttpServletRequest request, HttpServletResponse response, 
     AccessDeniedException accessDeniedException) throws IOException, ServletException { 
     response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); 
    } 

} 

AuthenticationProvider,讓你什麼失敗將提供更多的信息的一個例子:

public class CustomAuthenticationProvider implements AuthenticationProvider { 
    @Autowired 
    private UserService userService; 

    @Override 
    public Authentication authenticate(Authentication authentication) throws AuthenticationException { 
     UsernamePasswordAuthenticationToken auth = (UsernamePasswordAuthenticationToken) authentication; 
     String username = String.valueOf(auth.getPrincipal().toString()); 
     String password = String.valueOf(auth.getCredentials()); 

     if(username.isEmpty() || password.isEmpty()){ 
      throw new UsernameNotFoundException("You pudding, there is no username or password"); 
     } else { 
      SystemUser user = userService.findByUsername(username); 
      if(user == null){ 
       throw new UsernameNotFoundException("No user exists, stop hacking"); 
      } 
      //Do more stuff here to actually apply roles to the AuthToken etc 
      return new UsernamePasswordAuthenticationToken(username, null, authorities); 

     } 
    } 
} 
+1

感謝您的迴應!我其實已經有了一個AuthenticationFailureHandler。我缺少的是一個AccessDeniedHandler。在你的回答中,你正確地提到了AccessDeniedHandler,但是給出了一個AuthenticationFailureHandler的例子。如果您更新了代碼示例以確保準確,我會將您的答案標記爲選定的答案。 – AlexG

+0

@AlexG明天我會在工作 – JamesENL

+0

@AlexG,爲您更新。這非常簡單 – JamesENL

0

另一種方式做,這是有一個異常處理程序類和@ExceptionHandler註解。

@ControllerAdvice 
public class GlobalExceptionHandler { 

    @ExceptionHandler(AccessDeniedException.class) 
    public ResponseEntity<?> handleAccessDenied(HttpServletRequest request, AccessDeniedException ex) { 

     // exception handling logic 
     if (request.getUserPrincipal() == null) { 
      // user is not logged in 
     } else { 
      // user is logged in but doesn't have permission to the requested resource 
     } 

     // return whatever response you'd like 
     return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); 
    } 

}