简体   繁体   English

AngularJS和Spring MVC安全性

[英]AngularJS and Spring MVC security

I have a front end written in AngularJS, and a Spring MVC backend. 我有一个用AngularJS编写的前端和一个Spring MVC后端。 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. 我的想法是只保护REST API服务,并在进行未经授权的服务调用时使用AngularJS中的拦截器将用户重定向到登录页面。 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();
}

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: 我猜页面刷新大致如下:

  • A navigation takes place, rendering a template and activating a controller for the new route 进行导航,渲染模板并激活新路线的控制器
  • The controller calls a service; 控制器调用服务; this is asynchronous, so the page without any data is displayed 这是异步的,因此显示没有任何数据的页面
  • The service returns 401/403, it is intercepted and the new navigation to the login page occurs 该服务返回401/403,它被拦截并发生新的登录页面导航

You may want to try: 您可能要尝试:

  1. Collecting all data required by the page in the 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. 在路由的resolve配置中收集页面所需的所有数据( ngRouteangular-ui-router均支持 ),以便在获取所有数据之前导航不会完成。
  2. Handle it from within the page: while the service call is still pending, display a spinner/message whatever to let the user know that some background activity is going on. 从页面内进行处理:在服务呼叫仍待处理时,显示微调器/消息以使用户知道正在进行某些后台活动。
  3. When the interceptor catches a 401/403, have it open a modal popup, explaining the situation and offering the user to login or navigate to the login page as a single option. 当拦截器捕获到401/403时,让它打开一个模式弹出窗口,说明情况并为用户提供登录或导航到登录页面的单个选项。 Combine this with the spinner/message. 结合微调器/消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM