我使用Spring 2015-09-01 12:02:43.976 App Name[91111:2205337] Unknown class ContactPage in Interface Builder file.
2015-09-01 12:02:44.078 App Name[91111:2205337] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UIViewController 0x7ff781d0a110> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key Message.'
*** First throw call stack:
(
0 CoreFoundation 0x00000001051a99b5 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x00000001071ffdeb objc_exception_throw + 48
2 CoreFoundation 0x00000001051a95f9 -[NSException raise] + 9
3 Foundation 0x0000000105573fdb -[NSObject(NSKeyValueCoding) setValue:forKey:] + 288
4 UIKit 0x0000000105f9c418 -[UIViewController setValue:forKey:] + 88
5 UIKit 0x00000001061af2c7 -[UIRuntimeOutletConnection connect] + 109
6 CoreFoundation 0x00000001050ea590 -[NSArray makeObjectsPerformSelector:] + 224
7 UIKit 0x00000001061adcaa -[UINib instantiateWithOwner:options:] + 1864
8 UIKit 0x0000000105fa2df4 -[UIViewController _loadViewFromNibNamed:bundle:] + 381
9 UIKit 0x0000000105fa3720 -[UIViewController loadView] + 178
10 UIKit 0x0000000105fa3a22 -[UIViewController loadViewIfRequired] + 138
11 UIKit 0x0000000105fa4054 -[UIViewController view] + 27
12 UIKit 0x00000001066d36d2 -[_UIFullscreenPresentationController _setPresentedViewController:] + 87
13 UIKit 0x0000000105f74a4e -[UIPresentationController initWithPresentedViewController:presentingViewController:] + 133
14 UIKit 0x0000000105fb65ca -[UIViewController _presentViewController:withAnimationController:completion:] + 3736
15 UIKit 0x0000000105fb94b3 -[UIViewController presentViewController:animated:completion:] + 343
16 UIKit 0x00000001064eee8b __67-[UIStoryboardModalSegueTemplate newDefaultPerformHandlerForSegue:]_block_invoke + 243
17 UIKit 0x00000001064dd523 -[UIStoryboardSegueTemplate _perform:] + 449
18 UIKit 0x00000001064dd5ea -[UIStoryboardSegueTemplate perform:] + 156
19 UIKit 0x0000000105e1f522 -[UIApplication sendAction:to:from:forEvent:] + 92
20 UIKit 0x0000000105f7ec06 -[UIControl sendAction:to:forEvent:] + 67
21 UIKit 0x0000000105f7eeac -[UIControl _sendActionsForEvents:withEvent:] + 273
22 UIKit 0x0000000105f7e008 -[UIControl touchesEnded:withEvent:] + 601
23 UIKit 0x0000000105e8715f -[UIWindow _sendTouchesForEvent:] + 835
24 UIKit 0x0000000105e87d4d -[UIWindow sendEvent:] + 865
25 UIKit 0x0000000105e3c2ae -[UIApplication sendEvent:] + 263
26 UIKit 0x0000000105e1836c _UIApplicationHandleEventQueue + 6693
27 CoreFoundation 0x00000001050d5b21 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
28 CoreFoundation 0x00000001050cba4c __CFRunLoopDoSources0 + 556
29 CoreFoundation 0x00000001050caf03 __CFRunLoopRun + 867
30 CoreFoundation 0x00000001050ca918 CFRunLoopRunSpecific + 488
31 GraphicsServices 0x000000010acdcad2 GSEventRunModal + 161
32 UIKit 0x0000000105e1d99e UIApplicationMain + 171
33 App Name 0x0000000104fa749d main + 109
34 libdyld.dylib 0x0000000107d6492d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
来保护我的API(方法),但我想改变从未经授权的用户调用方法时会发生什么。当前的行为是Spring抛出HTTP 403错误。这很好,但我只想在403响应的主体中添加一个额外的错误代码,以便能够区分不同场景中的访问被拒绝错误。
我很难弄清楚@RolesAllowed
注释的实现位置。有没人遇到过它?或试图修改其行为?
我的控制器中的方法目前如下所示:
@RolesAllowed
答案 0 :(得分:1)
您尝试做的事情可以在不修改注释的情况下完成。
在Spring配置中,您可以指定一个AccessDeniedHandler
bean,当Spring Security确定您的用户不允许执行他们尝试执行的操作时,将调用该bean。
访问被拒绝处理程序非常简单:
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 :(得分: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);
}
}