【问题标题】:AngularJS and Spring MVC securityAngularJS 和 Spring MVC 安全性
【发布时间】: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();
}

【问题讨论】:

    标签: java javascript angularjs spring-mvc spring-security


    【解决方案1】:

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

    我猜页面刷新大致如下:

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

    你不妨试试:

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

    【讨论】:

    • 谢谢!我将对这两种方法进行一些试验。也许我可以显示一个微调器,直到成功调用至少一项服务。
    猜你喜欢
    • 2015-09-01
    • 2017-09-22
    • 2015-02-26
    • 1970-01-01
    • 2013-03-03
    • 2015-10-21
    • 2013-08-21
    • 2015-06-20
    • 1970-01-01
    相关资源
    最近更新 更多