How to Inject session bean in custom spring security login success handler - spring

i'm unable to inject a spring session bean in my custom success handler:
#Component
public class CustomSavedRequestAwareAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
#Resource
private SessionController sessionController;
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException {
super.onAuthenticationSuccess(request, response, authentication);
sessionController.setUtenteOnline();
}
that return a null pointer exception on sessionController.
Thank you in advance

Your success handler is probably a singleton so you can only inject singletons into it reliably. You can solve this problem using scoped dependencies. Basically, it involves Spring injecting a singleton dynamic proxy that manages fetching the real bean from session scope and delegating calls to it.

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

Not able to handler InternalAuthenticationServiceException in Spring Security

I am developing a rest api using Spring Boot. I have a class that extends UsernamePasswordAuthenticationFilter, where I override the attemptAuthentication method. In the process of authentication, Spring internally uses my CustomUserDetailsService that throws an exception in case no user is found. Spring internally handler that exception and throws InternalAuthenticationServiceException. The issue is, I am not able to catch that exception in my central place where I customize the response in case of errors. I am using #ControllerAdvice for that, but it seems Spring just ignore and always send default "Internal Server Error".
in order to capture a "failed authentication" just override the method unsuccessfulAuthentication in your filter
#Override
protected void unsuccessfulAuthentication(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException failed)
throws IOException, ServletException {
//handle errors
}

dynamically add param to userAuthorizationUri in oauth2

Sometimes user's refresh token in local DB becomes stale. To replenish I'm trying to add prompt=consent param while making the oauth2 call. I was trying to #Autowire AuthorizationCodeAccessTokenProvider in my config class and in the afterPropertiesSet I was doing a setTokenRequestEnhancer and then realized that this bean is not even initialized via spring container when i looked the following code in OAuth2RestTemplate
private AccessTokenProvider accessTokenProvider = new AccessTokenProviderChain(Arrays.<AccessTokenProvider> asList(
new AuthorizationCodeAccessTokenProvider(), new ImplicitAccessTokenProvider(),
new ResourceOwnerPasswordAccessTokenProvider(), new ClientCredentialsAccessTokenProvider()));
Searched if any spring code is calling org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.setAuthorizationRequestEnhancer(RequestEnhancer) to learn how to access it, but no one is calling it.
Question: How to dynamically add a param to userAuthorizationUri while making oauth2 call?
Unfortunately, I haven't found an elegant solution neither. I have noticed, however, that redirect is triggered by UserRedirectRequiredException.
I was able to dynamically add request params by registering custom filter that modifies this exception on the fly.
#Component
#Order(-102)
public class EnhanceUserRedirectFilter implements Filter {
#Override
public void init(final FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
try {
chain.doFilter(request, response);
} catch (final UserRedirectRequiredException ex) {
ex.getRequestParams().put("prompt", "consent");
throw ex;
}
}
#Override
public void destroy() {
}
}
Please note, such servlet filter has to have higher precedence than Spring Security. In my case, -102 is higher precedence than Spring Security default of -100.

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!

Call a bean AFTER successful spring security login?

If I have spring security working, how can I have it call a bean to initialize all my user data once it has logged in? I can do a Servlet Filter but it calls that on every request. I want to just call some init code to load some user data into the session after the user logs in.
When the user logs in correctly spring security call an instance of AuthenticationSuccessHandler. What you want to do is create your own bean and use that to perform whatever extra actions you want.
Your class would probably look something like this:
public class YourAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
//do whatever you want
super.onAuthenticationSuccess(request, response, authentication);
}
}
Also register your class as a spring bean
<beans:bean id="authenticationSuccessHandler"
class="your.package.YourAuthenticationSuccessHandler"/>
and add it to the form login security configuration as the value of authentication-success-handler-ref

Resources