Issue
When (in Spring Security / MVC) the access to a page is denied, as the user has not enough privileges (though he is authenticated), I need to offer to login as another user via showing the login page (instead of the standard behaviour of showing a 403 access denied page).
I can write an AccessDeniedHandler
, that redirects to the login page. But how will Spring Security react, when it finds out, that there is alrady another user logged in? Can I somehow logout the old user when the new one has successfully authenticated?
Solution
I've tried to log in a new user when there is already another user logged in. It works - without logging out the first user. His authorization is replaced by the new one's. This is the simple answer to my own question.
If someone is interested, how to forward to login page in case of access denied - here is my solution:
First define a custom RequestCache:
@Component("myRequestCache")
public class MyRequestCache extends HttpSessionRequestCache {
public MyRequestCache() {
super();
}
}
Second define a custom AccessDeniedHandler:
@Component("myAccessDeniedHandler")
public class MyAccessDeniedHandler implements AccessDeniedHandler {
@Autowired
@Qualifier("myRequestCache")
private RequestCache myRequestCache;
public MyAccessDeniedHandler() {
}
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException exc)
throws IOException, ServletException {
if (!response.isCommitted()) {
//Save Target-Request
myRequestCache.saveRequest(request, response);
//Forward to the login page
request.getRequestDispatcher("/loginPage").forward(request, response);
}
}
}
Third configure these two into Spring Security:
@Configuration
@EnableWebSecurity
public class myConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("myRequestCache")
RequestCache myRequestCache;
@Autowired
@Qualifier("myAccessDeniedHandler")
AccessDeniedHandler myAccessDeniedHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestCache()
.requestCache(myRequestCache)
.and()
.exceptionHandling()
.accessDeniedHandler(myAccessDeniedHandler)
}
}
What is happening here?
The MyAccessDeniedHandler
forwards in the case of an AccessDeniedException
to the login page. As this forward is invoked by this self-programmed class and not by Spring in the filter chain, we have to tell spring, what the target request is - to where it has to redirect after succesful authentication. This we do via the RequestCache
.
Answered By - olivmir