如何使用Spring Security保护AngularJS部分页面

时间:2016-05-21 21:44:43

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

我正在使用Spring MVC网络应用程序并且我使用AngularJS,我想基于角色保护我的视图,例如,如果我登录和管理员角色我可以看到删除用户部分页面,如果我使用用户角色登录,则无法观看删除用户的部分页面。

我知道如何使用spring security来实现这一点,但是使用普通的Web应用程序而不是使用angularJS的宁静单页应用程序,因为使用angular你不是真的从服务器请求视图而是只加载部分html页面一个ng-view标签。

我也使用ngRoute路由我的部分。

这是我的ngRoute.jS文件

angular.module('MyApp')
        .config(['$routeProvider', 'USER_ROLES' ,function ($routeProvider, USER_ROLES) {
                $routeProvider.
                        when('/', {
                            templateUrl: '/SpringMVCTemplateAnn/resources/angular/templates/dashboardTemplates/dashboardTemplate.html',
                            controller: 'DashBoardCtrl',
                            access: {
                            loginRequired: true,
                            authorizedRoles: [USER_ROLES.all]
                        }
                        }).
                        when('/login', {
                            templateUrl: '/SpringMVCTemplateAnn/resources/angular/templates/loginTemplate/login.html',
                            controller: 'LoginController', 
                            access: {
                            loginRequired: false,
                            authorizedRoles: [USER_ROLES.all]
                        }
                        }).
                         when('/createUser', {
                        templateUrl: '/SpringMVCTemplateAnn/views/partials/userTemplates/createUser.html',
                        controller: 'UserCtrl'
                    }).
                    when('/deleteUser', {
                        templateUrl: '/SpringMVCTemplateAnn/views/partials/userTemplates/deleteUser.html',
                        controller: 'UserCtrl'
                    }).
     }]);

这是我的spring安全配置我使用java注释配置,我已经调整了配置来转换它以便它可以适合其他应用程序

这是扩展WebSecuirtyConfigureAdapter

的Security类
public class SegurityConfig extends WebSecurityConfigurerAdapter {



public SegurityConfig() {
    super();
}
@Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private RestUnauthorizedEntryPoint restAuthenticationEntryPoint;

    @Autowired
    private AccessDeniedHandler restAccessDeniedHandler;

    @Autowired
    private AuthenticationSuccessHandler restAuthenticationSuccessHandler;

    @Autowired
    private AuthenticationFailureHandler restAuthenticationFailureHandler;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }


    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/resources/**", "/index.jsp", "/login.jsp",
                "/template/**", "/", "/error/**");
    }
//

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .headers().disable()
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/failure").permitAll()
                .antMatchers("/v2/api-docs").hasAnyAuthority("admin")
                .antMatchers("/users/**").hasAnyAuthority("admin")
                .antMatchers("/views/partials/userTemplates/createUser.html").access("hasRole('create users')")
                .anyRequest().authenticated()
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(restAuthenticationEntryPoint)
                .accessDeniedHandler(restAccessDeniedHandler)
                .and()
                .formLogin()
                .loginProcessingUrl("/login")
                .successHandler(restAuthenticationSuccessHandler)
                .failureHandler(restAuthenticationFailureHandler)
                .usernameParameter("username")
                .passwordParameter("password")
                .permitAll()
                .and()
                .logout()
                .logoutUrl("/logout")
                .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler())
                .deleteCookies("JSESSIONID")
                .permitAll()
                .and();
    }
}

我还使用了angularjs的http-auth-interceptor插件 这是MyApp模块

angular.module('MyApp', ['ngRoute', 'ui.bootstrap', 'smart-table', 'http-auth-interceptor']);

这是我的js文件,阻止用户在未经过身份验证的情况下浏览网站

angular.module('MyApp')
    .run(function ($rootScope, $location, $http, AuthSharedService, Session,
            USER_ROLES, $q, $timeout) {

        $rootScope.$on('$routeChangeStart', function (event, next) {

            if (next.originalPath === "/login" && $rootScope.authenticated) {
                event.preventDefault();
                console.log('registrese');
            } else if (next.access && next.access.loginRequired && !$rootScope.authenticated) {
                event.preventDefault();
                $rootScope.$broadcast("event:auth-loginRequired", {});
            } else if (next.access && !AuthSharedService.isAuthorized(next.access.authorizedRoles)) {
                event.preventDefault();
                $rootScope.$broadcast("event:auth-forbidden", {});
            }
        });

        // Call when the the client is confirmed
        $rootScope.$on('event:auth-loginConfirmed', function (event, data) {
            console.log('login confirmed start ' + data);
            $rootScope.loadingAccount = false;
            var nextLocation = ($rootScope.requestedUrl ? $rootScope.requestedUrl : "/home");
            var delay = ($location.path() === "/loading" ? 1500 : 0);

            $timeout(function () {
                Session.create(data);
                $rootScope.account = Session;
                $rootScope.authenticated = true;
                $location.path(nextLocation).replace();
            }, delay);

        });

        // Call when the 401 response is returned by the server
        $rootScope.$on('event:auth-loginRequired', function (event, data) {
            if ($rootScope.loadingAccount && data.status !== 401) {
                $rootScope.requestedUrl = $location.path()
                $location.path('/loading');
            } else {
                Session.invalidate();
                $rootScope.authenticated = false;
                $rootScope.loadingAccount = false;
                $location.path('/login');
            }
        });

        // Call when the 403 response is returned by the server
        $rootScope.$on('event:auth-forbidden', function (rejection) {
            $rootScope.$evalAsync(function () {
                $location.path('/error/403').replace();
            });
        });
    });

这是我的USER_ROLES常量js文件

angular.module('MyApp')
        .constant('USER_ROLES', {
            all: '*',
            admin: 'admin',
            user: 'user'
        });

如果我使用具有普通用户角色的用户登录,我希望保护我的部分页面我希望无法观看删除或创建用户部分页面,

我尝试将我的局部文件移到资源文件夹之外并将其放入我的secuirty类.antMatchers("/views/partials/userTemplates/createUser.html").access("hasRole('create users')")中,但如果它阻止部分,即使我使用具有该角色的用户登录,我仍然会得到403错误,我想要发生这种情况,但是如果我登录的用户没有该角色,但为什么当我向具有该角色的用户登录时发生这种情况就像它没有认识到我有这个角色。

有没有办法根据普通网络应用中的角色保护这些部分,因为该配置适用于我工作的普通网络应用,但看起来它不适用于单页休息应用。

如果可以从服务器端保护这些部分,我知道我可以使用@PreAuthorize("hasRole('create users')")保护服务器端的Rest方法,但有没有办法放置.antMatchers("/my partials/**").hasAnyAuthority("admin")或在安全配置类中类似的东西来保护部分?

我的文件夹结构

SpringMVCProject
--Web-Pages
  --WEB-INF
    --resources
      --angular
        --controllers
            userController.js
        --services
            userService.js
        --partials
          --userPartials
              deleteuser.html
        app.js
        permissionConstants.js
        routes.js
      --css
    --views
      --partials (I experimented putting this the folder but I 403 error)
        --userpartials
            deleteuser.html
    index.html
--Source Packages
  --controllers
    --userControllers
        UserController.java
  --secuirty
      SecuirtyConfig.java

0 个答案:

没有答案