Springbook 2.0 interceptor forward to controller - spring-boot

I am building a small application in which I am trying to manage user login session.
My question is, is it possible to forward the http request from HandlerInterceptor.preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) method to controller
Something like this..
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
request.getRequestDispatcher("someController").forward(request, response);
return true;
}

Related

Why RememberMeAuthenticationFilter does not redirect to requested url?

I'm new in Spring Security and I'm sorry for my English.
I have a rememberme cookie and when the request comes to the filter RememberMeAuthenticationFilter - it makes authentication, breaks the next processing and immediately returns to user only 200 status with defaultUrl, something like
{"redirectTo":"/","success":true,"username":"userName","roles":[listOfRoles]}
in here
public RememberMeAuthenticationFilter(AuthenticationManager authenticationManager,
RememberMeServices rememberMeServices) {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
...
if (successHandler != null) { // <<<<<<<<<<<<<<<<<In here the request breaks.
successHandler.onAuthenticationSuccess(request, response,
rememberMeAuth);
return;
}
...
chain.doFilter(request, response);
}
}
Tell me please how to do next: the request goes down throw the filter after successful authentication with rememberme cookie to chain.doFilter(request, response);
And after all filters go to controller method which user asks.
I find the solution, if somebody interesting. The solution was not to inject authenticationSuccessHandler to RememberMeAuthenticationFilter. I redefined the bean RememberMeAuthenticationFilter (thats by default defined inside grails) and not inject authenticationSuccessHandler. And thats why this code not processing and go to chain.doFilter.

AuthenticationFailureHandler HttpServletResponse.sendError url

I have developed single page web application using Spring Boot and Spring MVC. I am using Spring Security and JWT to authenticate users. I have written a custom AuthenticationFailureHandler which works but I want to know how I can control the url that a user gets redirect to when an exception is thrown. My AuthenticationFailureHandler looks like this:
public class JwtAuthenticationFailureHandler implements AuthenticationFailureHandler {
#Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
response.sendError(HttpStatus.UNAUTHORIZED.value(), exception.getMessage());
}
}
When the JWT expires the application throws an AccountExpiredException, the AuthenticationFailureHandler.onAuthenticationFailure method gets executed and the user gets redirected to the login page:
http://localhost:8080/login?sessionExpired=true
This is all good, but I have no idea how the sessionExpired=true query string is generated and I want to have some control over it. In the past I have used ExceptionMappingAuthenticationFailureHandlers like this:
Map<String, String> mappings = new HashMap<>();
mappings.put(BadCredentialsException.class.getCanonicalName(), BAD_CREDENTIALS_EXCEPTION_URL);
mappings.put(AccountExpiredException.class.getCanonicalName(), ACCOUNT_EXPIRED_EXCEPTION_URL);
mappings.put(CredentialsExpiredException.class.getCanonicalName(), CREDENTIALS_EXPIRED_EXCEPTION_URL);
mappings.put(DisabledException.class.getCanonicalName(), ACCOUNT_INACTIVE_EXCEPTION_URL);
mappings.put(LockedException.class.getCanonicalName(), ACCOUNT_LOCKED_EXCEPTION_URL);
mappings.put(ValidationException.class.getCanonicalName(), VALIDATION_EXCEPTION_URL);
ExceptionMappingAuthenticationFailureHandler exceptionMappingAuthenticationFailureHandler = new ExceptionMappingAuthenticationFailureHandler();
exceptionMappingAuthenticationFailureHandler.setExceptionMappings(mappings);
So based on the various exceptions above I would like to be able to redirect to the following URLs:
http://localhost:8080/login?error
http://localhost:8080/login?accountexpired
http://localhost:8080/login?credentialsexpired
http://localhost:8080/login?accountlocked
http://localhost:8080/login?accountinactive
http://localhost:8080/login?validationerror
I'm not sure who to do this with response.sendError and I don't know how the sessionExpired=true query string is being generated. I have tried throwing different exceptions but the url never changes.
I have a couple of questions. Is it possible to control the URL when using HttpServletResponse.sendError and if not is it possible ot set the HttpStatus code when using ExceptionMappingAuthenticationFailureHandler.sendRedirect?
Why don't you try to use the response.sendRedirect:
#Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
final HttpSession session = request.getSession(false);
if (session != null) {
request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception);
}
//here the logic to get the error type of the exception
String errorMessage = ????
redirectStrategy.sendRedirect(request, response,
"http://localhost:8080/login?" + errorMessage);
}

Spring HttpServletRequest unaccessible in HystrixCommand

Inside a Javanica annotated #HystrixCommand we are checking if the request was in an actual HTTP servlet request by checking:
RequestContextHolder.getRequestAttributes() != null;
However invoked from a #HystrixCommand this condition is always false, even if the request came from a Spring MVC request.
If I remove the #HystrixCommand annotation everything works fine.
We also tried to use the HttpServletRequest directly, this works fine (without #HystrixCommand):
LOGGER.info(request.getHeader("X-Client"));
With annotated #HystrixCommand we are facing exception indicating I am not in an valid HttpServletRequest. I know it is due to Hystrix running commands in separate Threads from its own ThreadPool and tried to do this, but doesn't work either:
public class RequestServletFilter implements Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {
// No Impl
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HystrixRequestContext context = HystrixRequestContext.initializeContext();
try {
chain.doFilter(request, response);
} finally {
context.shutdown();
}
}
#Override
public void destroy() {
// No Impl
}
Does someone have a clue how to delegate the Spring HttpServletRequest into HystrixCommands?
Any help is appreciated.
When using the RequestContextHolder by default it parameters are not shared (for good reasons!).
Assuming that you are using a DispatcherServlet to handle your request you can set its [threadContextInheritable] to true to have the RequestContext and LocaleContext shared between requests.
The same applies for the RequestContextFilter, it isn't possible with the RequestContextListener.
Note: I would consider sharing the HttpServletRequest between threads as something you shouldn't be doing and should be done with great care!

Set a redirect into a custom Authentication Failure Handler with Spring

Which is the properly way to set a redirect into a custom AuthenticationFailureHandler in Spring?
Is it possible to call a controller?
The code is as follows:
#Component
public class MyAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
#Override
public void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response, AuthenticationException exception)
throws IOException, ServletException {
super.onAuthenticationFailure(request, response, exception);
if (exception.getClass().isAssignableFrom(
CustomUsernameNotFoundException.class)) {
// TODO Set the redirect
}
}
}
Try soemthing like this
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
saveException(request, exception);
//do your things
getRedirectStrategy().sendRedirect(request, response, "/page/login?error=Retry");
}
You are calling super.onAuthenticationFailure which will peform a redirect to the configured URL. The response is thus already committed and you cannot decide to redirect somewhere else.
You can configure SimpleUrlAuthenticationFailureHandler to redirect to one URL and only call the super method if you aren't going to do a redirect yourself.
Alternatively, implement AuthenticationFailureHandler directly and implement all the logic you want in the failure method - once things get beyond a certain level of complexity I prefer to avoid inheritance altogether:
if (oneCondition) {
// redirect to IdP
} else {
// redirect to registration page
}
You can call a controller., a code snippet from you would help, but am getting this from the example that is discussed here.,
Spring Security Tutorial
#RequestMapping(value = "/login/failure")
public String loginFailure() {
String message = "Login Failure!";
return "redirect:/login?message="+message;
}
make sure you understand how the redirect works by looking at the mapping for login in the xml
Spring Mapping.xml
You can redirect to a specific URL.
response.sendRedirect("/redirect");

Need to pass value from interceptor to handller in spring

Hey I am new to spring and I need help on below:
I have interceptor with prehandle and posthandle mehtods in it.I want to send some values to handller from interceptor.
suggest any idea.
Thanks.
You can achieve this as:
In your interceptor prehandle method:
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
...
HttpSession session = request.getSession();
session.setAttribute("attributeName", objectYouWantToPassToHandler);
....
}
In your handler handleRequest method:
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
....
HttpSession session = request.getSession();
objectYouWantToPassToHandler objectYouWantToPassToHandler = session.getAttribute("attributeName");
....
}
Actually, your question ins't clear, sorry. Try start from Spring AOP
And, of course, you have to show your code: what you have and what you want to do.

Resources