Spring secuirty不允许我访问受保护的静态文件

时间:2016-05-28 23:44:00

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

我正在尝试保护一些静态HTML页面,因为我正在使用Angularjs,而某些HTML部分页面只能由具有特定角色的用户访问。

所以我尝试在我的WEB-INF文件夹中创建一个名为private的文件夹,然后将我的HTML文件放在那里,然后在我的Spring安全配置文件中输入这些带有注释hasAnyAuthority的文件的路径

.antMatchers("/privatePartials/protectedPartial.html").hasAnyAuthority("roleA")

我也试过像这样的hasROle注释

.antMatchers("/privatePartials/protectedPartial.html").access("hasRole('roleA')")

但是我收到了403错误,就好像我的用户没有“roleA”但它拥有它,因为我在我的控制台中打印了用户登录时所具有的所有角色。

我还尝试在我的资源文件夹中创建一个文件夹,但它也不起作用,因为任何用户都可以查看受保护的页面,这与用户的角色无关。我认为这是因为我在我的安全配置类中使用了这种方法,允许所有用户访问所有资源。

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

那么如何使用Spring Security保护这个HTML部分页面, 我正在使用Spring MVC 4.2.5.RELEASESpring Secuirty 4.1.0.RELEASE

这是我的文件夹结构

SpringMVCProject
--Web-Pages
  --WEB-INF
    --resources
      --angular
        --controllers
            userController.js
        --services
            userService.js
        --partials
          --userPartials
              deleteuser.html
        app.js
        permissionConstants.js
        routes.js
      --css
      --private
        --privatePartials
            protegida.html
    --views
      index.html
--Source Packages
  --controllers
--userControllers
    UserController.java
--secuirty
    SecuirtyConfig.java

这是我的整个安全配置类

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/angular/**",
            "/resources/bower_components/**",
            "/resources/css/**",
            "/resources/dist/**",
            "/resources/less/**",
            "/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("/resources/private/privatePartials/protegida.html").hasAuthority("administrador")
            .antMatchers("/views/partials/usuarioTemplates/crearUsuario.html").hasAuthority("administrador")
             .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();
}

这里是我的SpringConfig类

@Configuration
@EnableWebMvc
@ComponentScan({"config", "controllers", "security"})
public class ConfigMVC extends WebMvcConfigurerAdapter {

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/resources/**").addResourceLocations("/WEB-INF/resources/");
}
@Bean
public UrlBasedViewResolver setupViewResolver() {
    UrlBasedViewResolver resolver = new UrlBasedViewResolver();
    resolver.setPrefix("/WEB-INF/views/");
    resolver.setSuffix(".jsp");
    resolver.setViewClass(JstlView.class);
    return resolver;
}

我使用$routeChangeStarthttp-auth-interceptor来实现我的应用的登录 ehre是我的javascritp文件

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

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

            if (next.originalPath === "http://localhost:8080/SpringMVCTemplateAnn/login" && $rootScope.authenticated) {
                console.log('entre en el primer if del interceptor');
                event.preventDefault();
                console.log('registrese');
            } else if (next.access && next.access.loginRequired && !$rootScope.authenticated) {
                console.log('entre en el segundo  if del interceptor')
                event.preventDefault();
                $rootScope.$broadcast("event:auth-loginRequired", {});
            } else if (next.access && !AuthSharedService.isAuthorized(next.access.authorizedRoles)) {
                console.log('entre en el tercer  if del interceptor')
                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);
            alert(data.toSource());
            console.log('la URLVALE' + $rootScope.requestedUrl);
            $rootScope.loadingAccount = false;
            var nextLocation = ($rootScope.requestedUrl ? $rootScope.requestedUrl : "/crearRol");
            console.log('la URL2VALE' + $rootScope.requestedUrl);
            var delay = ($location.path() === "/loading" ? 1500 : 0);
//                console.log('la variable nextlocation vale ' + !!nextlocation);
                $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) {

            console.log("2do 401 segundo interceptor");
            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) {
           console.log("3 er 403 tercer interceptor");
            $rootScope.$evalAsync(function () {
                $location.path('/crearPermiso').replace();
            });
        });
    });

这是我的路线javascript文件

angular.module('SistemaActividades')
    .config(['$routeProvider', 'USER_ROLES', function ($routeProvider, USER_ROLES) {
            $routeProvider.
                    when('/', {
                        templateUrl: '/SpringMVCTemplateAnn/resources/angular/templates/dashboardTemplates/dashboardTemplate.html',
                        controller: 'DashBoardCtrl',
                        access: {
                            loginRequired: true,
                            authorizedRoles: "*"
                        }
                    }).
                    when('/login', {
                        templateUrl: '/SpringMVCTemplateAnn/resources/angular/templates/loginTemplate/login.html',
                        controller: 'LoginController',
                        access: {
                            loginRequired: false,
                            authorizedRoles: [USER_ROLES.all]
                        }
                    }).
                    when('/logout', {
                        templateUrl: '/SpringMVCTemplateAnn/resources/angular/templates/loginTemplate/login.html',
                        controller: 'LogoutController'
                    }).
                    when('/protegida', {
                        templateUrl: '/SpringMVCTemplateAnn/resources/private/privatePartials/protegida.html',
                        controller: 'UsuarioCtrl'
                    }).


 });
            }]);

angularjs中的我的身份验证服务

angular.module('SistemaActividades')
    .service('AuthSharedService', function ($rootScope, $http, authService, Session) {
        return {
            login: function (userName, password, rememberMe) {
                console.log('presione el click');
                var config = {
                    params: {
                        username: userName,
                        password: password,
                        rememberme: rememberMe
                    },
                    ignoreAuthModule: 'ignoreAuthModule'
                };
                $http.post('http://localhost:8080/SpringMVCTemplateAnn/login', '', config)
                        .success(function (data, status, headers, config) {
                            authService.loginConfirmed(data);
                        }).error(function (data, status, headers, config) {
                    $rootScope.authenticationError = true;
                    Session.invalidate();
                });
            },
            getAccount: function () {
                $rootScope.loadingAccount = true;
                $http.get('security/account')
                        .then(function (response) {
                            authService.loginConfirmed(response.data);
                        });
            },
            isAuthorized: function (authorizedRoles) {

                console.log('los roles valen ' + authorizedRoles);
                if (!angular.isArray(authorizedRoles)) {
                    if (authorizedRoles == '*') {
                        return true;
                    }
                    authorizedRoles = [authorizedRoles];
                }
                var isAuthorized = false;
                angular.forEach(authorizedRoles, function (authorizedRole) {
                    var authorized = (!!Session.login &&
                            Session.userRoles.indexOf(authorizedRole) !== -1);
                    if (authorized || authorizedRole == '*') {
                        isAuthorized = true;
                    }
                });
                return isAuthorized;
            }
            logout: function () {
                console.log('entre en el log de logut');
                $rootScope.authenticationError = false;
                $rootScope.authenticated = false;
                $rootScope.account = null;
                $http.get('http://localhost:8080/SpringMVCTemplateAnn/logout');
                Session.invalidate();
                authService.loginCancelled();
            }
        };
    });

我在angularjs中的登录服务

angular.module('SistemaActividades')
    .service('Session', function () {
        this.create = function (data) {
            this.id = data.id;
            this.login = data.login;
            this.firstName = data.firstName;
            this.lastName = data.familyName;
            this.email = data.email;
            this.userRoles = [];
            angular.forEach(data.authorities, function (value, key) {
                this.push(value.name);
            }, this.userRoles);
        };
        this.invalidate = function () {
            this.id = null;
            this.login = null;
            this.firstName = null;
            this.lastName = null;
            this.email = null;
            this.userRoles = null;
        };
        return this;
    });

我的登录控制器在angularjs

angular.module('SistemaActividades')
    .controller('LoginController', ['$rootScope', '$scope', 'AuthSharedService', function ($rootScope, $scope, AuthSharedService) {
            $scope.rememberMe = true;
            $scope.login = function () {
                console.log('pressione click');
                $rootScope.authenticationError = false;
                AuthSharedService.login(
                        $scope.username,
                        $scope.password,
                        $scope.rememberMe
                        );
            };
        }]);

我的logOut控制器在angularjs

angular.module('SistemaActividades')
        .controller('LogoutController', ['$rootScope', '$scope', 'AuthSharedService', function ($rootScope, $scope, AuthSharedService) {
                AuthSharedService.logout();
            }]);

我的登录页面

<div class="bg-extended">
<div class="align-vertical-center">

    <div class="container">

        <div class="row">

            <div class="well col-sm-offset-3 col-sm-6">

                <div class="well-heading well-primary">
                    <h1>Sign in your account</h1>
                </div>

                <form class="well-body">

                    <div class="alert alert-dismissible alert-info">
                        <button type="button" class="close" data-dismiss="alert">×</button>
                        <strong>Usuarios de Prueba!</strong> <br/>
                        <ul>
                            <li><strong>usuarioNormal / laclave</strong> usuario normal</li>
                            <li><strong>usuarioAdmin / clave123</strong> admin</li>
                        </ul>
                    </div>


                    <div class="form-group label-floating"
                         ng-class="{
                                     'has-error is-focused' : authenticationError}">
                        <label class="control-label" for="login">Login</label>
                        <input id="login" type="text" class="form-control" ng-model="username"
                               required="required"/>
                        <span ng-show="authenticationError" class="help-block">
                            Please check your credentials and try again.
                        </span>

                    </div>

                    <div class="form-group label-floating">
                        <label class="control-label" for="password">Password</label>
                        <input id="password" type="password" class="form-control" ng-model="password"
                               required="required"/>
                    </div>

                    <div class="checkbox">
                        <label>
                            <input type="checkbox" ng-model="rememberMe"/><span> Remember me</span>
                        </label>
                    </div>

                    <br/>

                    <div class="col-sm-offset-3 col-sm-6">
                        <button class="btn btn-lg btn-primary btn-block" ng-click="login()">
                            login
                        </button>
                    </div>

                </form>
            </div>
        </div>
    </div>
</div>

我在java中的登录控制器

@Controller

public class LoginController {

@RequestMapping(value = "/login", method = RequestMethod.GET)
public String login(ModelMap map) {

    return "login";
}

@RequestMapping(value = "/logout", method = RequestMethod.GET)
public String logout(ModelMap map, HttpServletRequest request, HttpServletResponse response)  {

    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    System.out.println("el usuario vale en logout" + auth.getName().toString());
    if (auth != null) {
        new SecurityContextLogoutHandler().logout(request, response, auth);
    }
    return "/login";
}

}

编辑:我设法让spring安全保护我资源中的私人文件夹中的部分,但是在我刷新页面或重新加载页面后我丢失了会话,无论什么角色,我都可以访问私有页面我有,当我刷新页面时,我被重定向到登录页面,如果我使用具有正常角色的用户登录,则该用户可以进入受管理的受保护页面

0 个答案:

没有答案