Spring Security 访问被拒绝角色或其他啥?

Posted

技术标签:

【中文标题】Spring Security 访问被拒绝角色或其他啥?【英文标题】:Spring Security access denied roles or what else?Spring Security 访问被拒绝角色或其他什么? 【发布时间】:2015-06-23 10:52:51 【问题描述】:

我正在尝试使我的应用程序与 Spring Security 一起工作,我能够登录,从 Active Directory 服务器获取角色。但是,验证成功后,我无法访问我的主页,我从日志中不明白原因。

这是我的 security.xml 文件中与此问题相关的部分:

<http pattern='/resources/css/**' security="none" />
<http pattern='/resources/fonts/**' security="none" />
<http pattern='/resources/images/**' security="none" />
<http pattern='/resources/js/**' security="none" />

<http use-expressions="true" disable-url-rewriting="true">

    <!-- Limitation à une seule session utilisateur concurrente -->
    <session-management invalid-session-url="/identite?expiree=1">
        <concurrency-control max-sessions="1" expired-url="/identite?expiree=1" />
    </session-management>

    <!-- Définitions pour le formulaire de la page JSP d'identification -->
    <form-login login-page="/identite" login-processing-url="/identite.proc" default-target-url="/" always-use-default-target="true" authentication-failure-url="/identite?err=1" username-parameter="username" password-parameter="password" />
    <csrf disabled="true" />

    <logout logout-url="/logout" logout-success-url="/identite?termine=1" delete-cookies="JSESSIONID" invalidate-session="true" />

    <!-- Utiliser un canal chiffré pour les échanges -->
    <intercept-url requires-channel="https" pattern="/identite*" access="permitAll()" />
    <intercept-url requires-channel="https" pattern="/**" access="hasRole('SecRole-Utilisateurs-HPAM')" />
    <access-denied-handler error-page="/erreur403" />
</http>

这是认证成功完成后,直到到达AccessDeniedException的日志中的相关部分:

2015-04-16 15:18:03,851 DEBUG (o.s.s.w.a.AbstractAuthenticationProcessingFilter.successfulAuthentication) [http-8443-1] Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@ce672a83: Principal: org.springframework.security.ldap.userdetails.LdapUserDetailsImpl@644dcdae: Dn: CN=MYUSERNAME,OU=Utilisateurs,DC=fsapps,DC=companyX,DC=uni; Username: myusername; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; CredentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: SecRole-Utilisateurs-HPAM, SecRole-AdminSysteme; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@ffff6a82: RemoteIpAddress: 127.0.0.1; SessionId: AB7D98894DEA3BF993FB01DD845AE132; Granted Authorities: SecRole-Utilisateurs-HPAM, SecRole-AdminSysteme MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.DefaultRedirectStrategy.sendRedirect) [http-8443-1] Redirecting to '/Atarget/' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.c.HttpSessionSecurityContextRepository$SaveToSessionResponseWrapper.saveContext) [http-8443-1] SecurityContext 'org.springframework.security.core.context.SecurityContextImpl@ce672a83: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@ce672a83: Principal: org.springframework.security.ldap.userdetails.LdapUserDetailsImpl@644dcdae: Dn: CN=MYUSERNAME,OU=Utilisateurs,DC=fsapps,DC=companyX,DC=uni; Username: myusername; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; CredentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: SecRole-Utilisateurs-HPAM, SecRole-AdminSysteme; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@ffff6a82: RemoteIpAddress: 127.0.0.1; SessionId: AB7D98894DEA3BF993FB01DD845AE132; Granted Authorities: SecRole-Utilisateurs-HPAM, SecRole-AdminSysteme' stored to HttpSession: 'org.apache.catalina.session.StandardSessionFacade@6b38dba MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.c.SecurityContextPersistenceFilter.doFilter) [http-8443-1] SecurityContextHolder now cleared, as request processing completed MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.u.m.AntPathRequestMatcher.matches) [http-8443-1] Checking match of request : '/'; against '/resources/css/**' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.u.m.AntPathRequestMatcher.matches) [http-8443-1] Checking match of request : '/'; against '/resources/fonts/**' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.u.m.AntPathRequestMatcher.matches) [http-8443-1] Checking match of request : '/'; against '/resources/images/**' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.u.m.AntPathRequestMatcher.matches) [http-8443-1] Checking match of request : '/'; against '/resources/js/**' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter) [http-8443-1] / at position 1 of 12 in additional filter chain; firing Filter: 'ChannelProcessingFilter' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.u.m.AntPathRequestMatcher.matches) [http-8443-1] Checking match of request : '/'; against '/identite*' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.u.m.AntPathRequestMatcher.matches) [http-8443-1] Request '/' matched by universal pattern '/**' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.a.c.ChannelProcessingFilter.doFilter) [http-8443-1] Request: FilterInvocation: URL: /; ConfigAttributes: [REQUIRES_SECURE_CHANNEL] MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter) [http-8443-1] / at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.c.HttpSessionSecurityContextRepository.readSecurityContextFromSession) [http-8443-1] Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@ce672a83: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@ce672a83: Principal: org.springframework.security.ldap.userdetails.LdapUserDetailsImpl@644dcdae: Dn: CN=MYUSERNAME,OU=Utilisateurs,DC=fsapps,DC=companyX,DC=uni; Username: myusername; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; CredentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: SecRole-Utilisateurs-HPAM, SecRole-AdminSysteme; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@ffff6a82: RemoteIpAddress: 127.0.0.1; SessionId: AB7D98894DEA3BF993FB01DD845AE132; Granted Authorities: SecRole-Utilisateurs-HPAM, SecRole-AdminSysteme' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter) [http-8443-1] / at position 3 of 12 in additional filter chain; firing Filter: 'ConcurrentSessionFilter' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter) [http-8443-1] / at position 4 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter) [http-8443-1] / at position 5 of 12 in additional filter chain; firing Filter: 'LogoutFilter' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.u.m.AntPathRequestMatcher.matches) [http-8443-1] Checking match of request : '/'; against '/logout' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter) [http-8443-1] / at position 6 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.u.m.AntPathRequestMatcher.matches) [http-8443-1] Request 'GET /' doesn't match 'POST /identite.proc MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter) [http-8443-1] / at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter) [http-8443-1] / at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter) [http-8443-1] / at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.a.AnonymousAuthenticationFilter.doFilter) [http-8443-1] SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@ce672a83: Principal: org.springframework.security.ldap.userdetails.LdapUserDetailsImpl@644dcdae: Dn: CN=MYUSERNAME,OU=Utilisateurs,DC=fsapps,DC=companyX,DC=uni; Username: myusername; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; CredentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: SecRole-Utilisateurs-HPAM, SecRole-AdminSysteme; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@ffff6a82: RemoteIpAddress: 127.0.0.1; SessionId: AB7D98894DEA3BF993FB01DD845AE132; Granted Authorities: SecRole-Utilisateurs-HPAM, SecRole-AdminSysteme' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter) [http-8443-1] / at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter) [http-8443-1] / at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter) [http-8443-1] / at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.u.m.AntPathRequestMatcher.matches) [http-8443-1] Checking match of request : '/'; against '/identite*' MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.a.i.AbstractSecurityInterceptor.beforeInvocation) [http-8443-1] Secure object: FilterInvocation: URL: /; Attributes: [hasRole('SecRole-Utilisateurs-HPAM')] MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.a.i.AbstractSecurityInterceptor.authenticateIfRequired) [http-8443-1] Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@ce672a83: Principal: org.springframework.security.ldap.userdetails.LdapUserDetailsImpl@644dcdae: Dn: CN=MYUSERNAME,OU=Utilisateurs,DC=fsapps,DC=companyX,DC=uni; Username: myusername; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; CredentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: SecRole-Utilisateurs-HPAM, SecRole-AdminSysteme; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@ffff6a82: RemoteIpAddress: 127.0.0.1; SessionId: AB7D98894DEA3BF993FB01DD845AE132; Granted Authorities: SecRole-Utilisateurs-HPAM, SecRole-AdminSysteme MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.a.v.AffirmativeBased.decide) [http-8443-1] Voter: org.springframework.security.web.access.expression.WebExpressionVoter@4af08d0f, returned: -1 MDC
2015-04-16 15:18:03,851 DEBUG (o.s.s.w.a.ExceptionTranslationFilter.handleSpringSecurityException) [http-8443-1] Access is denied (user is not anonymous); delegating to AccessDeniedHandler MDC

似乎在某些时候我的应用程序期望我的用户是匿名且未经身份验证的。如果这是原因,我需要一些帮助来找出原因,否则我需要一些提示来调查我的配置的适当部分。

这似乎与角色验证有关。如果我将 hasRole() 替换为 isAuthenticated(),我可以在遇到生成相同消息的 hasRole() PreAuthorize 条件之前走得更远。

我如何才能更深入地了解角色验证的情况?我的日志记录处于跟踪级别。

我在 servlet 中插入了几行代码,我将 PreAuthorize 注释更改为 isAuthenticated() 以使其执行并记录发生的情况。这是我添加的代码行:

@PreAuthorize("isAuthenticated()")
@RequestMapping(value="/", method = RequestMethod.GET)
public String Welcome(HttpServletRequest requete, ModelMap model) 
    log.info("\t\tRoles connus:");
    for ( GrantedAuthority ga : SecurityContextHolder.getContext().getAuthentication().getAuthorities() ) 
        log.info("\t\t\t" + ga.getAuthority() + "\t" + requete.isUserInRole(ga.getAuthority()));
    
    //Authentication auth = (Authentication) requete.getUserPrincipal();
    log.debug("The USER: " + requete.getRemoteUser());
(...)

这是日志中的输出:

2015-04-16 17:22:45,749 DEBUG (o.s.s.a.i.AbstractSecurityInterceptor.beforeInvocation) [http-8443-1] RunAsManager did not change Authentication object MDC
2015-04-16 17:22:45,765 INFO (c.d.g.w.c.ControleurCaissesDispo.Welcome) [http-8443-1]       Roles connus: MDC
2015-04-16 17:22:45,765 INFO (c.d.g.w.c.ControleurCaissesDispo.Welcome) [http-8443-1]           SecRole-Support-ABC true MDC
2015-04-16 17:22:45,765 INFO (c.d.g.w.c.ControleurCaissesDispo.Welcome) [http-8443-1]           SecRole-Utilisateurs-ABC    true MDC
2015-04-16 17:22:45,765 INFO (c.d.g.w.c.CCD.Welcome) [http-8443-1]          SecRole-Utilisateurs-HPAM   true MDC
2015-04-16 17:22:45,765 INFO (c.d.g.w.c.CCD.Welcome) [http-8443-1]          SecRole-AdminSysteme    true MDC
2015-04-16 17:22:45,781 INFO (c.d.g.w.c.CCD.Welcome) [http-8443-1]          Another_One true MDC
2015-04-16 17:22:45,781 INFO (c.d.g.w.c.CCD.Welcome) [http-8443-1]          Another_Two true MDC
2015-04-16 17:22:45,781 INFO (c.d.g.w.c.CCD.Welcome) [http-8443-1]          SoOn    true MDC
2015-04-16 17:22:45,781 INFO (c.d.g.w.c.CCD.Welcome) [http-8443-1]          AndSoOn true MDC
2015-04-16 17:22:45,781 DEBUG (c.d.g.w.c.CCD.Welcome) [http-8443-1] The USER: myusername MDC
2015-04-16 17:22:45,781 INFO (c.d.g.w.c.CCD.Welcome) [http-8443-1] Session id: 1F1865F73F20A623DED099754B28AB11 MDC

此时,null defaultRolePrefix 似乎可以正常工作,因为 servlet 调用可以识别角色。那么,我的 @PreAuthorize("hasRole('SecRole-Utilisateurs-HPAM')") 注释有什么问题?

看完这个http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/faq.html#faq-method-security-in-web-context问题2.16后,我有点疑惑。我对 Spring 有点陌生,我看不出我的错误在哪里。因此,如果有人可以提供帮助,这就是我的 web.xml 中的内容:

<!-- Configuration du contexte applicatif Spring -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/mvc-applicationContext.xml
        /WEB-INF/security-applicationContext.xml
    </param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<listener>
    <display-name>My App</display-name>
    <listener-class>com.company.gisti.web.myapp.ContexteApplicatifMyApp</listener-class>
</listener>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- MVC Filter -->
<servlet>
    <servlet-name>mvc-dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextAttribute</param-name>
        <param-value>org.springframework.web.context.WebApplicationContext.ROOT</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/identite</url-pattern>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<!-- Filtres de sécurité -->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>contextAttribute</param-name>
        <param-value>org.springframework.web.context.WebApplicationContext.ROOT</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<!-- JSPs -->
<servlet>
    <servlet-name>403Jsp</servlet-name>
    <jsp-file>/403.jsp</jsp-file>
</servlet>
<servlet-mapping>
    <servlet-name>403Jsp</servlet-name>
    <url-pattern>/403</url-pattern>
</servlet-mapping>

<!-- Page d'erreur -->
<error-page>
    <error-code>403</error-code>
    <location>/erreur403</location>
</error-page>

然后在 mvc-applicationContext.xml 我有:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:security="http://www.springframework.org/schema/security"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    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-4.1.xsd
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://www.springframework.org/schema/security
        http://www.springframework.org/schema/security/spring-security-4.0.xsd">

    <context:annotation-config />
    <mvc:resources mapping="/resources/**" location="/resources/theme_company/" />
    <mvc:annotation-driven />   

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <context:component-scan base-package="com.company.gisti.web.myapp" />

</beans>

而且上面已经发布了security-applicationContext.xml。

最后是我的日志中的内容:

2015-04-17 09:57:11,548 INFO (o.s.s.c.SpringSecurityCoreVersion.performVersionChecks) [main] You are running with Spring Security Core null MDC
2015-04-17 09:57:11,548 INFO (o.s.s.c.SecurityNamespaceHandler.<init>) [main] Couldn't determine package version information. MDC
2015-04-17 09:57:11,580 INFO (o.s.s.c.m.GlobalMethodSecurityBeanDefinitionParser.parse) [main] Expressions were enabled for method security but no SecurityExpressionHandler was configured. All hasPermision() expressions will evaluate to false. MDC
2015-04-17 09:57:11,642 INFO (o.s.s.c.h.FilterInvocationSecurityMetadataSourceParser.parseInterceptUrlsForFilterInvocationRequestMap) [main] Creating access control expression attribute 'permitAll()' for /identite* MDC
2015-04-17 09:57:11,642 INFO (o.s.s.c.h.FilterInvocationSecurityMetadataSourceParser.parseInterceptUrlsForFilterInvocationRequestMap) [main] Creating access control expression attribute 'isAuthenticated()' for /** MDC
2015-04-17 09:57:11,659 INFO (o.s.s.c.h.HttpSecurityBeanDefinitionParser.checkFilterChainOrder) [main] Checking sorted filter chain: [Root bean: class [org.springframework.security.web.access.channel.ChannelProcessingFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 100, Root bean: class [org.springframework.security.web.context.SecurityContextPersistenceFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 200, Root bean: class [org.springframework.security.web.session.ConcurrentSessionFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 300, Root bean: class [org.springframework.security.web.header.HeaderWriterFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 500, Root bean: class [org.springframework.security.web.authentication.logout.LogoutFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 700, <org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0>, order = 1100, Root bean: class [org.springframework.security.web.savedrequest.RequestCacheAwareFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 1600, Root bean: class [org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 1700, Root bean: class [org.springframework.security.web.authentication.AnonymousAuthenticationFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 2000, Root bean: class [org.springframework.security.web.session.SessionManagementFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 2100, Root bean: class [org.springframework.security.web.access.ExceptionTranslationFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 2200, <org.springframework.security.web.access.intercept.FilterSecurityInterceptor#0>, order = 2300] MDC

第三条消息清楚地说明了问题。但是,为什么第一条和第二条消息?无法确定我的 Spring Security Core 版本缺少什么?我正在使用 Maven 来管理依赖项,我查看了目录并且库似乎是正确的版本,我看不出我的命名空间中是否缺少某些东西,因为那里也报告了这些版本。第三条消息是否与它无法确定 Spring Security Core 的版本有关,或者它是两个独立的问题?

注意:我更正了描述中的角色。正如我在下面的回答中所解释的,这两个角色都存在,并且我有一个 OR 条件,我删除并保留了错误的角色来解释我的问题。为了避免进一步混淆,我什至将注释中的所有内容都更改为只选择一个角色属性:[[authorize: 'hasRole('SecRole-Utilisateurs-HPAM')', filter: 'null', filterTarget: 'null'] ](来自日志)。总而言之,这不是问题。


我在 security-applicationContext.xml 中添加了以下 bean 来设置角色前缀,即使我将其更改为“none”、“”、“PHILEMON_”或其他任何内容,它似乎也完全没有效果。

<b:bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter">
    <b:property name="rolePrefix" value="">
</b:property>

2015-04-20 11:35 更新:

这是拒绝访问的日志输出,而其他所有内容都表明应授予用户访问权限。尽管用户实际上拥有该角色,但 RoleVoter 返回 -1。

2015-04-20 11:33:05,926 DEBUG (o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter) [http-8443-2] /telechargement reached end of additional filter chain; proceeding with original chain MDC
2015-04-20 11:33:05,926 DEBUG (o.s.s.a.i.AbstractSecurityInterceptor.beforeInvocation) [http-8443-2] Secure object: ReflectiveMethodInvocation: public java.lang.String com.companyX.gisti.web.app.ControleurCD.TraitementTelechargement(javax.servlet.http.HttpServletRequest,org.springframework.ui.ModelMap) throws javax.servlet.ServletException,java.io.IOException; target is of class [com.companyX.gisti.web.app.ControleurCD]; Attributes: [[authorize: 'hasRole('SecRole-Utilisateurs-HPAM')', filter: 'null', filterTarget: 'null']] MDC
2015-04-20 11:33:05,926 DEBUG (o.s.s.a.i.AbstractSecurityInterceptor.beforeInvocation) [http-8443-1] Secure object: ReflectiveMethodInvocation: public java.lang.String com.companyX.gisti.web.app.ControleurCD.TraitementTelechargement(javax.servlet.http.HttpServletRequest,org.springframework.ui.ModelMap) throws javax.servlet.ServletException,java.io.IOException; target is of class [com.companyX.gisti.web.app.ControleurCD]; Attributes: [[authorize: 'hasRole('SecRole-Utilisateurs-HPAM')', filter: 'null', filterTarget: 'null']] MDC
2015-04-20 11:33:05,926 DEBUG (o.s.s.a.i.AbstractSecurityInterceptor.authenticateIfRequired) [http-8443-2] Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@ce672a83: Principal: org.springframework.security.ldap.userdetails.LdapUserDetailsImpl@644dcdae: Dn: CN=MYUSERNAME,OU=Utilisateurs,DC=fsapps,DC=companyX,DC=uni; Username: myusername; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; CredentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: SecRole-Support-DDMI, SecRole-Utilisateurs-DDMI, SecRole-Utilisateurs-HPAM; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@ffff6a82: RemoteIpAddress: 127.0.0.1; SessionId: C8D81A8CF479F9DD2C789AB37DA6CFAF; Granted Authorities: SecRole-Support-DDMI, SecRole-Utilisateurs-DDMI, SecRole-Utilisateurs-HPAM MDC
2015-04-20 11:33:05,926 DEBUG (o.s.s.a.i.AbstractSecurityInterceptor.authenticateIfRequired) [http-8443-1] Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@ce672a83: Principal: org.springframework.security.ldap.userdetails.LdapUserDetailsImpl@644dcdae: Dn: CN=MYUSERNAME,OU=Utilisateurs,DC=fsapps,DC=companyX,DC=uni; Username: myusername; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; CredentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: SecRole-Support-DDMI, SecRole-Utilisateurs-DDMI, SecRole-Utilisateurs-HPAM; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@ffff6a82: RemoteIpAddress: 127.0.0.1; SessionId: C8D81A8CF479F9DD2C789AB37DA6CFAF; Granted Authorities: SecRole-Support-DDMI, SecRole-Utilisateurs-DDMI, SecRole-Utilisateurs-HPAM MDC
2015-04-20 11:33:05,926 DEBUG (o.s.s.a.v.AffirmativeBased.decide) [http-8443-2] Voter: org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter@69af0fcf, returned: -1 MDC
2015-04-20 11:33:05,926 DEBUG (o.s.s.a.v.AffirmativeBased.decide) [http-8443-1] Voter: org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter@69af0fcf, returned: -1 MDC
2015-04-20 11:33:05,926 DEBUG (o.s.s.a.v.AffirmativeBased.decide) [http-8443-2] Voter: org.springframework.security.access.vote.RoleVoter@2dcc5af0, returned: 0 MDC
2015-04-20 11:33:05,926 DEBUG (o.s.s.a.v.AffirmativeBased.decide) [http-8443-1] Voter: org.springframework.security.access.vote.RoleVoter@2dcc5af0, returned: 0 MDC
2015-04-20 11:33:05,926 DEBUG (o.s.s.a.v.AffirmativeBased.decide) [http-8443-1] Voter: org.springframework.security.access.vote.AuthenticatedVoter@43665a0d, returned: 0 MDC
2015-04-20 11:33:05,926 DEBUG (o.s.s.a.v.AffirmativeBased.decide) [http-8443-2] Voter: org.springframework.security.access.vote.AuthenticatedVoter@43665a0d, returned: 0 MDC
2015-04-20 11:33:05,926 DEBUG (o.s.s.w.a.ExceptionTranslationFilter.handleSpringSecurityException) [http-8443-2] Access is denied (user is not anonymous); delegating to AccessDeniedHandler MDC

2015-04-20 16:35 更新:

如何检查用户详细信息以确保一切都符合预期?它看起来与角色前缀相关,但是日志中的输出从不显示有关前缀的任何内容,即使我明确地为具有默认角色前缀的安全表达式处理程序和具有角色前缀的角色投票者创建 bean,它就像什么都没发生一样。我怎样才能了解正在发生的事情?如果我将它从 PreAuthorize 注释移动到 url 拦截过滤器,hasRole() 子句也不起作用。只有 isAuthenticated() 似乎有效。与 Ldap/ActiveDirectory 构建用户详细信息的方式有关吗?我即将把所有这些东西扔进垃圾桶,并为这个应用程序编写我自己的简单安全系统。我没有想法。


2015-04-20 22:14 更新:

我解决了我的问题,而且解决方案并不简单。我会尽快发布详细信息以备记录。

【问题讨论】:

【参考方案1】:

那么,我有什么问题 @PreAuthorize("hasRole('SecRole-Administrateur-HPAM')") 注释?

您的注释没有问题,但如果您仔细监控登录用户的角色日志。没有角色SecRole-Administrateur-HPAM,只有以下可用。

SecRole-Support-ABC 
SecRole-Utilisateurs-ABC
SecRole-Utilisateurs-HPAM         
SecRole-AdminSysteme   
Another_One          
Another_Two           
SoOn             
AndSoOn

请检查您的角色。

【讨论】:

好的,你找到我了。我犯了一个错误。由于我的 PreAuthorize 有一个 or 条件和另一个 hasRole('SecRole-Utilisateurs-HPAM') 条目,我删除了错误的条目以简化描述。实际上,您有两个角色,我的测试用户拥有其中一个角色,而我的 PreAuthorize 实际上要求一个或另一个角色如下:@PreAuthorize("hasRole('SecRole-Utilisateurs-HPAM') 或 hasRole('SecRole- Administrateur-HPAM')") 我将修复原帖中的错误角色。

以上是关于Spring Security 访问被拒绝角色或其他啥?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security Authorization - 管理员被拒绝访问

拒绝Spring Security中具有相同角色的多个用户的访问

Spring Security 角色不起作用

如何为 Spring Security 启用日志记录?

如何为 Spring Security 启用日志记录?

Spring Security - 访问被拒绝(用户不是匿名的)spring-security-core-4.0.3.RELEASE