Reputation: 2061
I have a front end written in AngularJS, and a Spring MVC backend. The idea I had was to only secure the REST API services and use an interceptor in AngularJS to redirect the user to the login page when an unauthorized service call is made. The problem I'm facing now is that, while a service is called, the page is briefly displayed before the user is redirected. Is there anything I can do about that? Or is this approach fundamentally flawed?
This is the interceptor:
$httpProvider.interceptors.push(function ($q, $location) {
return {
'responseError': function(rejection) {
var status = rejection.status;
if (status == 401 || status == 403) {
$location.path( "/login" );
} else {
}
return $q.reject(rejection);
}
};});
My security configuration:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/api/**")
.authorizeRequests()
.anyRequest().authenticated();
}
@Bean(name="myAuthenticationManager")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
The login controller:
@RequestMapping(value = "/login", method = RequestMethod.POST, produces="application/json")
@ResponseBody
public String login(@RequestBody User user) {
JSONObject result = new JSONObject();
UsernamePasswordAuthenticationToken token =
new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());
try {
Authentication auth = authenticationManager.authenticate(token);
SecurityContext securityContext = SecurityContextHolder.getContext();
securityContext.setAuthentication(auth);
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
HttpSession session = attr.getRequest().getSession(true);
session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
result.put("isauthenticated", true);
} catch (BadCredentialsException e) {
result.put("isauthenticated", false);
}
return result.toString();
}
Upvotes: 1
Views: 575
Reputation: 40296
I think this approach is OK, but you may have to live with the page flash, which in turn means you will have to handle it gracefully.
I guess the page flush happens roughly as follows:
You may want to try:
resolve
configuration of the route (supported both by ngRoute and angular-ui-router), so that the navigation will not complete before all data is fetched.Upvotes: 2