Hystrix fallback method for redirect from controller - spring-boot

I have a controller from which there is redirection to multiple other services. I was thinking of using hystrix fallback to redirect to a service not running page in case the service being redirected to is not running. But somehow the fallback is not working.
I have added #EnableCircuitBreaker to the main class. And using circuit breaker in my controller as below.
#HystrixCommand(fallbackMethod = "serviceNotRunning")
public ModelAndView jbotMS(final ModelMap modelMap, final HttpServletResponse response) throws JSONException {
return new ModelAndView(ParentConstants.REDIRECT + this.jbotxMicroServices +"/");
}
fallback method :
public ModelAndView serviceNotRunning(final ModelMap modelMap, final HttpServletResponse response)
{
System.out.println("Fallback called");
return new ModelAndView(Constants.LOGIN_PATH);
}
But somehow it is not working and each time I am getting the unable to connect page.
Is it not possible to use fallback on redirect or controller?

Related

spring mvc: applying #ModelAttribute on non-#Controller endpoints

I've read this suggestion on using #ModelAttribute for injecting parameters to the model globally. Is my understading correct, that such an approach will not cover views rendered by, e.g. <mvc:view-controller>, or a form-login custom login page?
If so, is there a way to extend such a mechanism to include all views?
Thanks
Ended-up using an Interceptor, as laid-out in this reply. Registered interceptor to intercept all non-resource endpoints (using mvc:exclude-mapping).
public class HandlerInterceptor extends HandlerInterceptorAdapter {
#Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
if (modelAndView == null)
return;
modelAndView.addObject("foo", "bar");
}

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 Security in single page app

I am new to the world of web development and my latest task requires me to use backbonesjs and requirejs on front end and spring boot on back end.I am supposed to have two pages one serving the login template and after its successful authentication I am supposed to show index.html which will show me username and password of logedin user.I am able to submitt loginform using ajax in my loginview and on its authentication I want to serve the index1.html.But when i do windows.location.href to serve index.html nothing happens.I guess spring security is redirecting to he same page again.How can I achieve that.
maybe this is help for you.
Spring 3 with No xml.
I have two pages. These are login and index jsp.
Spring WebSecurityConfiguerer configure method like this.
#Override
protected void configure( HttpSecurity http ) throws Exception{
http.exceptionHandling().
accessDeniedPage( "/login?accessDeniedError=1").and().
authorizeRequests().anyRequest().authenticated().and().
formLogin().loginPage( "/login" ).
defaultSuccessUrl( "/index", true ).
failureUrl( "/login?authenticationFailure" ).permitAll().and().
logout().deleteCookies( "JSESSIONID" ).
invalidateHttpSession( true).permitAll();
}
Spring Mvc Controller's methods is :
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String login( ModelMap model, HttpServletRequest request ){
//business logic
return "login";
}
#RequestMapping(value = "/index", method = RequestMethod.GET)
public String index( ModelMap model, Principal principal, HttpServletRequest request ){
//business logic
return "index";
}

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");

Spring MVC - Handling redirection

I want to redirect a page in server side (using spring), but the URL should remain the same.
For ex: if user tries http://www.example.com/page1, I want to render content of http://www.example.com/page2 in browser but the URL should still point to http://www.example.com/page1.
I tried 301, 302, 307 redirects, but all page URLs are changing to http://www.example.com/page2.
Is there anyway to achieve this?
It's a problem of terminology. What you're looking for is forward rather than redirect. If you're interested you may want to look that up e.g. here: http://www.javapractices.com/topic/TopicAction.do?Id=181.
There are at least two ways of doing this:
Traditional, RequestDispatcher can be used outside a Spring WebMVC application, too.
public class MyController extends AbstractController {
#Override
protected void handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
throws Exception {
request.getRequestDispatcher("/new/path").forward(request, response);
}
}
Spring WebMVC notation:
public class MyController extends AbstractController {
#Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
throws Exception {
return new ModelAndView("forward:/new/path");
}
}

Resources