授予权限的@secured会抛出访问被拒绝的异常

时间:2012-02-15 22:54:08

标签: spring spring-security

我正在配置和测试spring security 3.1.0。

我有一个拥有ROLE_COMPANY_OWNER的用户。这个想法是只有拥有该权限的用户才能访问url:companies / list

所以,在方法列表的控制器中,我用@Secured(“hasRole('ROLE_COMPANY_OWNER')”注释了它))

我知道我可以在安全上下文文件中配置它 但我会用@Secured注释服务,所以我正在探讨控制器方法。

问题是,即使用户具有权限,也会抛出拒绝访问。

我错过了什么?每个选民都要回访弃权。

这是我的配置:

安全的applicationContext.xml

<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
      http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <global-method-security secured-annotations="enabled" pre-post-annotations="enabled" proxy-target-class = "true"/>
    <http pattern="/resources/**" security="none"/>
    <http use-expressions="true">
<!--          <intercept-url pattern="/**" access="isAuthenticated()" /> -->
         <form-login login-page='/spring_security_login' default-target-url='/index.html'
            always-use-default-target='true' />
        <logout delete-cookies="JSESSIONID" />  
    </http>

    <authentication-manager>
        <authentication-provider user-service-ref="AuthRepository">
            <password-encoder ref="passwordEncoder"/>
        </authentication-provider>
    </authentication-manager>

</beans:beans>

控制器

package ar.com.held.controller;


@Controller
@RequestMapping("companies")
public class CompanyController {




    @Autowired
    private CompanyRepository companyRepository;

    @Secured("hasRole('ROLE_COMPANY_OWNER')")
    @RequestMapping(value={"","list"})
    public String list(Model model){
        Long userId = getLoggedUser().getId();
        List<Company> companies = this.companyRepository.findOwnedBy(userId);
        model.addAttribute("companies", companies);
        return "company/list";
    }
}

我的自定义提供商

@Repository(value="AuthRepository")
public class AuthRepository extends JdbcDaoImpl {

        @Autowired
        private UserRepository userRepository;

        @Override
        public UserDetails loadUserByUsername(String username)
                        throws UsernameNotFoundException {
                User user = userRepository.findByUserName(username);
                if(user==null)
                        throw new UsernameNotFoundException(username+" no es un usuario registrado");                
                return new ar.com.held.auth.UserDetails(user);
        }



        @Override
        protected void checkDaoConfig() {
        }


}

我的自定义用户详细信息:

public class UserDetails implements
        org.springframework.security.core.userdetails.UserDetails {

    /**
         * 
         */
    private static final long serialVersionUID = -2636146093986968636L;

    private User user;

    private String userName;
    private String password;

    private List<SimpleGrantedAuthority> authorities;

    public User getUser() {
        return user;
    }

    public UserDetails(User user) {
        this.authorities = new ArrayList<>();
        this.user = user;
        this.userName = user.getUsername();
        this.password = user.getPassword();
        if(user.getAuthorities()!=null){
            for (Authority authotiry : user.getAuthorities()) {
                if(authotiry.isValid())
                    this.authorities.add(new SimpleGrantedAuthority(authotiry.getAuthority()));
            }
        }
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return this.authorities;
    }

    @Override
    public String getPassword() {
        return this.password;
    }

    @Override
    public String getUsername() {
        return this.userName;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }

}

以下是例外:

2012-02-15 19:39:11 DispatcherServlet [DEBUG] Last-Modified value for [/Held/companies/list] is: -1
2012-02-15 19:39:11 MethodSecurityInterceptor [DEBUG] Secure object: ReflectiveMethodInvocation: public java.lang.String ar.com.held.controller.CompanyController.list(org.springframework.ui.Model); target is of class [ar.com.held.controller.CompanyController]; Attributes: [hasRole('ROLE_COMPANY_OWNER')]
2012-02-15 19:39:11 MethodSecurityInterceptor [DEBUG] Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0634cab: Principal: ar.com.held.auth.UserDetails@1fd596b; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@21a2c: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: AEEB034DEEFA679FB64DC3BF3475928D; Granted Authorities: ROLE_COMPANY_OWNER
2012-02-15 19:39:11 AffirmativeBased [DEBUG] Voter: org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter@1201fe5, returned: 0
2012-02-15 19:39:11 AffirmativeBased [DEBUG] Voter: org.springframework.security.access.vote.RoleVoter@e11b6, returned: 0
2012-02-15 19:39:11 AffirmativeBased [DEBUG] Voter: org.springframework.security.access.vote.AuthenticatedVoter@1ace180, returned: 0
2012-02-15 19:39:11 ExceptionHandlerExceptionResolver [DEBUG] Resolving exception from handler [public java.lang.String ar.com.held.controller.CompanyController.list(org.springframework.ui.Model)]: org.springframework.security.access.AccessDeniedException: Access is denied
2012-02-15 19:39:11 ResponseStatusExceptionResolver [DEBUG] Resolving exception from handler [public java.lang.String ar.com.held.controller.CompanyController.list(org.springframework.ui.Model)]: org.springframework.security.access.AccessDeniedException: Access is denied
2012-02-15 19:39:11 DefaultHandlerExceptionResolver [DEBUG] Resolving exception from handler [public java.lang.String ar.com.held.controller.CompanyController.list(org.springframework.ui.Model)]: org.springframework.security.access.AccessDeniedException: Access is denied
2012-02-15 19:39:11 SimpleMappingExceptionResolver [DEBUG] Resolving exception from handler [public java.lang.String ar.com.held.controller.CompanyController.list(org.springframework.ui.Model)]: org.springframework.security.access.AccessDeniedException: Access is denied
2012-02-15 19:39:11 SimpleMappingExceptionResolver [DEBUG] Resolving to view 'errors/accessDenied' for exception of type [org.springframework.security.access.AccessDeniedException], based on exception mapping [.AccessDeniedException]
2012-02-15 19:39:11 SimpleMappingExceptionResolver [DEBUG] Exposing Exception as model attribute 'exception'
2012-02-15 19:39:11 DispatcherServlet [DEBUG] Handler execution resulted in exception - forwarding to resolved error view: ModelAndView: reference to view with name 'errors/accessDenied'; model is {exception=org.springframework.security.access.AccessDeniedException: Access is denied}
org.springframework.security.access.AccessDeniedException: Access is denied
    at org.springframework.security.access.vote.AbstractAccessDecisionManager.checkAllowIfAllAbstainDecisions(AbstractAccessDecisionManager.java:70)
    at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:88)
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:205)
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:59)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
    at ar.com.held.controller.CompanyController$$EnhancerByCGLIB$$5279c365.list(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:212)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at com.opensymphony.sitemesh.webapp.SiteMeshFilter.obtainContent(SiteMeshFilter.java:129)
    at com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:77)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:311)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:101)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:91)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:182)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:173)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
2012-02-15 19:39:11 DispatcherServlet [DEBUG] Rendering view [org.springframework.web.servlet.view.JstlView: name 'errors/accessDenied'; URL [/WEB-INF/view/errors/accessDenied.jsp]] in DispatcherServlet with name 'spring'
2012-02-15 19:39:11 JstlView [DEBUG] Added model object 'exception' of type [org.springframework.security.access.AccessDeniedException] to request in view with name 'errors/accessDenied'
2012-02-15 19:39:11 JstlView [DEBUG] Forwarding to resource [/WEB-INF/view/errors/accessDenied.jsp] in InternalResourceView 'errors/accessDenied'
2012-02-15 19:39:11 DispatcherServlet [DEBUG] Successfully completed request
2012-02-15 19:39:11 DefaultListableBeanFactory [DEBUG] Returning cached instance of singleton bean 'org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler#0'
2012-02-15 19:39:11 DefaultListableBeanFactory [DEBUG] Returning cached instance of singleton bean 'org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler#0'
2012-02-15 19:39:11 DefaultListableBeanFactory [DEBUG] Returning cached instance of singleton bean 'org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler#0'
2012-02-15 19:39:11 DefaultListableBeanFactory [DEBUG] Returning cached instance of singleton bean 'org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler#0'
2012-02-15 19:39:11 ExceptionTranslationFilter [DEBUG] Chain processed normally
2012-02-15 19:39:11 SecurityContextPersistenceFilter [DEBUG] SecurityContextHolder now cleared, as request processing completed

1 个答案:

答案 0 :(得分:3)

这是语法错误。 @Secured(在Spring 3.0中)的正确语法是

@Secured("ROLE_COMPANY_OWNER")