Reputation: 1650
I have a custom AccessDecisionVoter for a custom Annotation, which restricts the access to certain methods, based on the scopes provided in the Annotation. This works without a problem, but the response I get when the Authentication is missing the scope is always the same and I am looking for a way to customize this. Thank you in advance.
ScopeVoter
public class ScopeVoter implements AccessDecisionVoter<MethodInvocation> {
@Override
public int vote(Authentication authentication, MethodInvocation object, Collection<ConfigAttribute> attributes) {
//custom logic here which decides to grant or deny the access. Here the message should be customized.
}
AuthenticationEntryPoint
@Component
public class AuthenticationEntryPointImp implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
This is where the response is generated and I am trying to get the custom message to this AuthenticationEntryPoint.
HTTPSecurety Configuration
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint()).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests().antMatchers("/auth/**").permitAll()
.anyRequest().authenticated();
http.addFilterBefore(authFilter(), UsernamePasswordAuthenticationFilter.class);
}
authenticationEntryPoint() is the described class above.
PS: I also want to get a custom message from the authFilter() to the EntryPoint.
EDIT: It was pointed out to me that this might not be possible, but if not in the AuthenticationEntryPoint there must be another place. And I also want to display a custom message from the AuthenticationFilter in the AuthenticationEntryPoint, which definitely gets called when the auth fails.
Upvotes: 0
Views: 645
Reputation: 7077
if use is authenticated successfully, and then the voter is denied, you can configure your AccessDeniedHandler
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().accessDeniedHandler(new AccessDeniedHandler() {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException, ServletException {
response.getWriter().println(accessDeniedException.getMessage());
}
}).authenticationEntryPoint(authenticationEntryPoint()).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests().antMatchers("/auth/**").permitAll()
.anyRequest().authenticated();
http.addFilterBefore(authFilter(), UsernamePasswordAuthenticationFilter.class);
}
then in ScopeVoter, you can throw AccessDeniedException by yourself
public class ScopeVoter implements AccessDecisionVoter<MethodInvocation> {
@Override
public int vote(Authentication authentication, MethodInvocation object, Collection<ConfigAttribute> attributes) {
//if the logic is not met, throw it directly
throw new AccessDeniedException("your customize message is here");
}
Upvotes: 1
Reputation: 158
For the customized error response part of your question: I have configured CustomAuthenticationEntryPoint
so that it invokes my general exception handler defined with @ControllerAdvice.
@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Autowired
@Qualifier("handlerExceptionResolver")
private HandlerExceptionResolver resolver;
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException ex) throws IOException, ServletException {
resolver.resolveException(request, response, null, ex);
}
}
Source code is available here.
Upvotes: 1
Reputation: 7077
I think it is impossible to do this, because AuthenticationEntryPoint.commence() and AccessDecisionVoter.voter() is mutual exclusion, when the authentication is failure, the voter will not be called, when the authentication is success, the commence will not be called()
Upvotes: 1