AngularJS 和 Spring MVC 安全性

Posted

技术标签:

【中文标题】AngularJS 和 Spring MVC 安全性【英文标题】:AngularJS and Spring MVC security 【发布时间】:2015-03-05 13:25:48 【问题描述】:

我有一个用 AngularJS 编写的前端和一个 Spring MVC 后端。我的想法是只保护 REST API 服务,并在进行未经授权的服务调用时使用 AngularJS 中的拦截器将用户重定向到登录页面。我现在面临的问题是,在调用服务时,页面会在用户被重定向之前短暂显示。有什么我可以做的吗?还是这种方法存在根本缺陷?

这是拦截器:

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

我的安全配置:

@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();
    


登录控制器:

@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();

【问题讨论】:

【参考方案1】:

我认为这种方法还可以,但您可能不得不忍受页面闪存,这反过来意味着您必须优雅地处理它。

我猜页面刷新大致如下:

进行导航,呈现模板并为新路线激活控制器 控制器调用服务;这是异步的,所以会显示没有任何数据的页面 服务返回 401/403,被拦截并出现新的登录页面导航

你不妨试试:

    在路由的resolve配置中收集页面所需的所有数据(ngRoute和angular-ui-router都支持),以便在获取所有数据之前导航不会完成。 在页面内处理它:当服务调用仍处于挂起状态时,显示一个微调器/消息,让用户知道某些后台活动正在进行。 当拦截器捕获 401/403 时,让它打开一个模式弹出窗口,解释情况并为用户提供登录或导航到登录页面作为单一选项。将此与微调器/消息结合起来。

【讨论】:

谢谢!我将对这两种方法进行一些试验。也许我可以显示一个微调器,直到成功调用至少一项服务。

以上是关于AngularJS 和 Spring MVC 安全性的主要内容,如果未能解决你的问题,请参考以下文章

Spring MVC 和 Angularjs

使用 Spring MVC 和 AngularJS 的方法 DELETE

使用 AngularJS 配置 Spring MVC

使用AngularJS配置Spring MVC

AngularJS和Spring MVC的Ajax GET错误

将 Spring MVC 应用程序从 JSP 迁移到 AngularJS