TS-*_*TS- 6 java spring spring-security
我已经按照很多线程将Spring Security实现到我的rest API.最初我被卡在@Secured注释被忽略,现在我已经解决了,我被困在获得拒绝访问.
感觉像我的问题听起来非常相似:@secured与授权的权限抛出访问被拒绝的异常 - 但我仍然被拒绝访问.
这是我的设置:
弹簧security.xml文件
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService">
<password-encoder ref="passwordEncoder" />
</authentication-provider>
</authentication-manager>
<beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.PlaintextPasswordEncoder"/>
<user-service id="userDetailsService">
<user name="john" password="john1" authorities="ROLE_USER, ROLE_ADMIN" />
<user name="jane" password="jane1" authorities="ROLE_USER" />
<user name="apiuser" password="apiuser" authorities="PERMISSION_TEST" />
</user-service>
Run Code Online (Sandbox Code Playgroud)
控制器:
@Controller
@RequestMapping("/secure")
public class SecureController
{
private static final Logger logger = Logger.getLogger(SecureController.class);
@Secured("PERMISSION_TEST")
@RequestMapping(value = "/makeRequest", method = RequestMethod.GET)
@ResponseBody
public SimpleDTO executeSecureCall()
{
logger.debug("[executeSecureCall] Received request to a secure method");
SimpleDTO dto = new SimpleDTO();
dto.setStringVariable("You are authorized!");
return dto;
}
}
Run Code Online (Sandbox Code Playgroud)
现在 - 没有正确的
<security:global-method-security secured-annotations="enabled"/>
Run Code Online (Sandbox Code Playgroud)
我的请求通过(这是因为@Secured注释被忽略).当我把它放入并使用"apiuser"/"apiuser"访问它时,我一直拒绝访问,调试日志:
11:42:43,899 [http-apr-8080-exec-4] DEBUG MethodSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@cc12af5d: Principal: org.springframework.security.core.userdetails.User@d059c8e5: Username: apiuser; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: PERMISSION_TEST; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: PERMISSION_TEST
11:42:43,899 [http-apr-8080-exec-4] DEBUG AffirmativeBased - Voter: org.springframework.security.access.vote.RoleVoter@2a9a42ef, returned: 0
11:42:43,900 [http-apr-8080-exec-4] DEBUG AffirmativeBased - Voter: org.springframework.security.access.vote.AuthenticatedVoter@75a06ec2, returned: 0
11:42:43,902 [http-apr-8080-exec-4] DEBUG AnnotationMethodHandlerExceptionResolver - Resolving exception from handler [com.test.webapp.spring.controller.SecureController@342d150f]: org.springframework.security.access.AccessDeniedException: Access is denied
11:42:43,905 [http-apr-8080-exec-4] DEBUG ResponseStatusExceptionResolver - Resolving exception from handler [com.test.webapp.spring.controller.SecureController@342d150f]: org.springframework.security.access.AccessDeniedException: Access is denied
11:42:43,906 [http-apr-8080-exec-4] DEBUG DefaultHandlerExceptionResolver - Resolving exception from handler [com.test.webapp.spring.controller.SecureController@342d150f]: org.springframework.security.access.AccessDeniedException: Access is denied
11:42:43,909 [http-apr-8080-exec-4] DEBUG DispatcherServlet - Could not complete request
org.springframework.security.access.AccessDeniedException: Access is denied
Run Code Online (Sandbox Code Playgroud)
思考?
提前致谢!
Mic*_*aev 24
我记得@Secured注释只适用于ROLE_默认开始的角色名称 .
您可以切换到@PreAuthorize("hasAuthority('PERMISSION_TEST')")(使用pre-post-annotations="enabled")或重命名您的角色.
我想再向Michail Nikolaev补充一点.我的答案来自源代码的观点.我希望您了解访问被拒绝的原因.
来自文档:
当您使用命名空间配置时,将自动为您注册AccessDecisionManager的默认实例,并将根据您在intercept-url和protect-pointcut声明中指定的访问属性,为方法调用和Web URL访问做出访问决策. (如果使用注释安全方法,则在注释中).默认策略是使用具有RoleVoter和AuthenticatedVoter的AffirmativeBased AccessDecisionManager.
RoleVoter使用ROLE_前缀(默认情况下)来决定它是否可以投票.您可以使用RoleVoter.setRolePrefix()方法更改该默认前缀.
来自源代码:
public class RoleVoter implements AccessDecisionVoter<Object> {
(...)
private String rolePrefix = "ROLE_";
(...)
public void setRolePrefix(String rolePrefix) {
this.rolePrefix = rolePrefix;
}
(...)
public boolean supports(ConfigAttribute attribute) {
if ((attribute.getAttribute() != null) &&
attribute.getAttribute().startsWith(getRolePrefix())) {
return true;
} else {
return false;
}
}
(...)
public int vote(Authentication authentication, Object object,
Collection<ConfigAttribute> attributes) {
int result = ACCESS_ABSTAIN;
Collection<? extends GrantedAuthority> authorities =
extractAuthorities(authentication);
for (ConfigAttribute attribute : attributes) {
if (this.supports(attribute)) {
result = ACCESS_DENIED;
// Attempt to find a matching granted authority
for (GrantedAuthority authority : authorities) {
if (attribute.getAttribute().equals(authority.getAuthority())) {
return ACCESS_GRANTED;
}
}
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
PERMISSION_TEST并不是从ROLE_如此RoleVoter弃权决定开始的.AuthenticatedVoter也弃权(因为你没有IS_AUTHENTICATED_在@Secured注释中使用前缀).
最后,投掷的AffirmativeBased实施因为都投了弃权票.AccessDecisionManagerAccessDeniedExceptionAccessDecisionVoters
Java文档AffirmativeBased:
org.springframework.security.access.AccessDecisionManager的简单具体实现,如果任何AccessDecisionVoter返回肯定响应,则授予访问权限.
| 归档时间: |
|
| 查看次数: |
4299 次 |
| 最近记录: |