我正在进行我的第一个spring-boot项目。我成功地配置了它来检查身份验证;如果用户/口令是错误的,则不调用该方法(状态401未授权),如果是正确的,则成功。
现在,我已经添加了JSR 250授权,我只得到403访问被拒绝。
WS:
@RestController
@RequestMapping("/password")
public class ServicioPassword {
@GetMapping(path = "ldap")
public ResponseEntity<String> getLdap() {
var authentication = SecurityContextHolder.getContext().getAuthentication();
System.out.println("EN LDAP " + authentication.getPrincipal() + " - " + authentication.isAuthenticated());
for (var authority : authentication.getAuthorities()) {
System.out.println("Authority= " + authority);
}
return ResponseEntity.ok("DE LDAP");
}
当调用时,我在控制台上得到以下内容:
用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码,用户名和密码用户名=ivr_apl_user;密码=[受保护];已启用=真;未过期帐户=真;凭据未过期=true;帐户未锁定=真;已授予的权限=[AGNI_OIMIVR]] - true
权限= AGNI_OIMIVR
然而,如果我添加@RolesAllowed("AGNI_OIMIVR")
,当我调用它时,我会得到一个403禁止。
将MethodSecurityConfig
:
@Configuration
@EnableGlobalMethodSecurity(jsr250Enabled = true, prePostEnabled = true)
public class MethodSecurityConfig
extends GlobalMethodSecurityConfiguration{
}
我保留了WebSecurityConfig
:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Autowired
private Environment environment;
@Bean
BindAuthenticator bindAuthenticator(
final BaseLdapPathContextSource contextSource) {
var bindAuthenticator = new BindAuthenticator(contextSource);
bindAuthenticator.setUserDnPatterns(new String[]{environment.getRequiredProperty("spring.ldap.userdnpattern")});
return bindAuthenticator;
}
@Bean
AuthenticationProvider ldapAuthenticationProvider(
final LdapAuthenticator ldapAuthenticator) {
var ldapAuthenticationProvider = new LdapAuthenticationProvider(ldapAuthenticator);
var ldapUserDetailsMapper = new CustomUserDetailsMapper();
var ldapMemberRoles = environment.getRequiredProperty("spring.ldap.roleattributes");
ldapUserDetailsMapper.setRoleAttributes(ldapMemberRoles.split(","));
ldapUserDetailsMapper.setRolePrefix("");
ldapAuthenticationProvider.setUserDetailsContextMapper(ldapUserDetailsMapper);
return ldapAuthenticationProvider;
}
@Bean
SecurityFilterChain filterChain(
final HttpSecurity http)
throws Exception {
http.csrf().disable()
.cors().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER).and()
.authorizeRequests()
.anyRequest().authenticated().and()
.httpBasic();
return http.build();
}
UPDATE:设置logging.level.org.springframework.security=TRACE
后添加日志:
请注意以下行:2022-07-07 13:04:27.464 WARN 81968 --- [nio-8080-exec-2] e.s.d.o.s.ws.CustomUserDetailsMapper : createAuthority agni_oimivr
来自我的一个自定义类的日志。
2022-07-07 13:04:27.441跟踪81968 --- [nio-8080-exec-2]操作系统和软件在基本授权标头中找到用户名“ivr_apl_user”
2022-07-07 13:04:27.442跟踪81968 --- [nio-8080-exec-2]操作系统认证。提供商管理器:正在使用LdapAuthenticationProvider验证请求(1/1)
2022-07-07 13:04:27.444跟踪81968 --- [nio-8080-exec-2] o.s.s.l.a.绑定身份验证器:正在尝试绑定为cn=ivr_apl_user,ou=[已删除]
2022-07-07 13:04:27.444追踪81968 --- [nio-8080-exec-2] s.s.l.默认Spring安全上下文来源:正在删除用户cn=ivr_apl_user,ou=[已删除]的池标记
2022-07-07 13:04:27.463调试81968 --- [nio-8080-exec-2] o.s.s.l.a.绑定身份验证器:绑定cn=ivr_apl_user,ou=[已删除]
2022-07-07 13:04:27.463调试81968 --- [nio-8080-exec-2] o. s. s. l. u. Ldap用户详细信息Map器:从DN为cn=ivr_apl_user,ou=[已删除]的上下文Map用户详细资料
2022-07-07 13:04:27.464警告81968 --- [nio-8080-exec-2]电子邮件地址.自定义用户详细信息Map器:创建授权机构agni_oimivr
2022-07-07 13:04:27.464调试81968 --- [nio-8080-exec-2] o.s.s.l.a. Ldap身份验证提供商:已验证的用户
2022-07-07 13:04:27.465调试81968 --- [nio-8080-exec-2]操作系统软件将安全上下文持有者设置为用户名密码验证令牌[主体=LdapUserDetailsImpl][Dn=cn=ivr_apl_user,ou=IVR,ou=应用程序,dc=pre,dc=aplssib;用户名=ivr_apl_user;密码=[受保护];已启用=真;未过期帐户=真;凭据未过期=true;帐户未锁定=真;授予的授权=[AGNI_OIMIVR]],凭据=[PROTECTED],已验证=true,详细信息= Web验证详细信息[远程IP地址=0:0:0:0:0:0:1,会话ID =空],授予的授权=[AGNI_OIMIVR]]
2022-07-07 13:04:27.465跟踪81968 --- [nio-8080-exec-2]操作系统安全.网络.过滤器链代理服务器:正在调用请求缓存感知过滤器(7/12)
2022-07-07 13:04:27.465跟踪81968 --- [nio-8080-exec-2]操作系统和软件。HTTP会话请求缓存:没有保存的请求
2022-07-07 13:04:27.465跟踪81968 --- [nio-8080-exec-2]操作系统安全.网络.过滤器链代理服务器:调用安全上下文持有者感知请求过滤器(8/12)
2022-07-07 13:04:27.466跟踪81968 --- [nio-8080-exec-2]操作系统安全.网络.过滤器链代理服务器:正在调用匿名身份验证筛选器(9/12)
2022-07-07 13:04:27.466跟踪81968 --- [nio-8080-exec-2]匿名身份验证过滤器:由于已验证用户名密码验证令牌,因此未设置安全上下文保持器。用户名=ivr_apl_user;密码=[受保护];已启用=真;未过期帐户=真;凭据未过期=true;帐户未锁定=真;授予的授权=[AGNI_OIMIVR]],凭据=[PROTECTED],已验证=true,详细信息= Web验证详细信息[远程IP地址=0:0:0:0:0:0:1,会话ID =空],授予的授权=[AGNI_OIMIVR]]
2022-07-07 13:04:27.466跟踪81968 --- [nio-8080-exec-2]操作系统安全.网络.过滤器链代理服务器:正在调用会话管理过滤器(10/12)
2022-07-07 13:04:27.467 TRACE 81968 --- [nio-8080-exec-2] s.复合会话身份验证策略:正在使用更改会话ID验证策略准备会话(1/1)
2022-07-07 13:04:27.467调试81968 --- [nio-8080-exec-2] w.c. Http会话安全上下文存储库:HttpSession当前为空,并且禁止HttpSessionSecurityContextRepository创建HttpSession(因为allowSessionCreation属性为false)-因此不会为下一个请求存储SecurityContext
2022-07-07 13:04:27.467跟踪81968 --- [nio-8080-exec-2]操作系统安全.网络.过滤器链代理服务器:调用异常转换过滤器(11/12)
2022-07-07 13:04:27.467跟踪81968 --- [nio-8080-exec-2]操作系统安全.网络.过滤器链代理服务器:正在调用过滤器安全拦截器(12/12)
2022-07-07 13:04:27.468跟踪81968 --- [nio-8080-exec-2] o.s.s.w.a. i.过滤器安全拦截器:没有重新验证用户名密码验证令牌[主体=LdapUserDetailsImpl [Dn=cn=ivr_apl_user,ou=IVR,ou=应用程序,dc=pre,dc=aplssib;用户名=ivr_apl_user;密码=[受保护];已启用=真;未过期帐户=真;凭据未过期=true;帐户未锁定=真;授权前授予的权限=[AGNI_OIMIVR]],凭据=[PROTECTED],已验证=true,详细信息= Web验证详细信息[RemoteIpAddress=0:0:0:0:0:0:1,会话ID =null],授予的权限=[AGNI_OIMIVR]]
2022-07-07 13:04:27.468跟踪81968 --- [nio-8080-exec-2] o.s.s.w.a. i.过滤器安全拦截器:使用属性[authenticated]授权过滤器调用[GET /password/ldap]
2022-07-07 13:04:27.469调试81968 --- [nio-8080-exec-2] o.s.s.w.a. i.过滤器安全拦截器:使用属性[authenticated]的授权过滤器调用[GET /password/ldap]
2022-07-07 13:04:27.470跟踪81968 --- [nio-8080-exec-2] o.s.s.w.a. i.过滤器安全拦截器:未切换RunAs身份验证,因为RunAsManager返回空值
2022-07-07 13:04:27.470调试81968 --- [nio-8080-exec-2]操作系统安全性.web.过滤器链代理服务器:安全的GET /密码/LDAP
2022-07-07 13:04:27.471跟踪81968 --- [nio-8080-exec-2] o.s.s.a.i.a.方法安全性拦截器:没有重新验证用户名密码验证令牌[主体=LdapUserDetailsImpl [Dn=cn=ivr_apl_user,ou=IVR,ou=应用程序,dc=pre,dc=aplssib;用户名=ivr_apl_user;密码=[受保护];已启用=真;未过期帐户=真;凭据未过期=true;帐户未锁定=真;授权前授予的权限=[AGNI_OIMIVR]],凭据=[PROTECTED],已验证=true,详细信息= Web验证详细信息[RemoteIpAddress=0:0:0:0:0:0:1,会话ID =null],授予的权限=[AGNI_OIMIVR]]
2022-07-07 13:04:27.472跟踪81968 --- [nio-8080-exec-2] o.s.s.a.i.a.方法安全性拦截器:正在受权反射方法叫用:这个方法是一个很好的例子,它可以让你在一个很短的时间内完成所有的工作。目标属于具有属性[ROLE_AGNI_OIMIVR]的类[es.ssib.dtic.oimivr.service.ws.v1.ServicioPassword]
2022-07-07 13:04:27.475跟踪81968 --- [nio-8080-exec-2] o.s.s.a.i.a.方法安全性拦截器:无法授权反射方法调用:这个方法是一个很好的例子,它可以让你在一个很短的时间内完成所有的工作。目标属于类[es.ssib.dtic.oimivr.service.ws.v1.ServicioPassword],其属性为[ROLE_AGNI_OIMIVR],使用基于肯定的[决策投票者=[如果所有人弃权,则允许决策=false]
2022-07-07 13:04:27.484追踪81968 --- [nio-8080-exec-2] o.s.s.w.a.异常翻译过滤器:发送用户名密码验证令牌[委托人=LdapUserDetailsImpl [Dn=cn=ivr_apl_user,ou=IVR,ou=应用程序,dc=pre,dc=aplssib;用户名=ivr_apl_user;密码=[受保护];已启用=真;未过期帐户=真;凭据未过期=true;帐户未锁定=真;由于访问被拒绝,已授予访问被拒绝处理程序的权限=[AGNI_OIMIVR]],凭据=[PROTECTED],已验证=true,详细信息= Web验证详细信息[RemoteIpAddress=0:0:0:0:0:0:0:1,会话ID =null],授予的权限=[AGNI_OIMIVR]]
org.springframework.security.access.AccessDeniedException:拒绝接受
请在这里输入您的密码,然后在这里输入您的密码。请输入您的密码。
这是一个很好的例子,它可以帮助你更好地理解如何使用这个框架。
[...]
2022-07-07 13:04:27.497调试81968 --- [nio-8080-exec-2]操作系统软件访问。访问被拒绝的处理程序实现:以403状态代码响应
我做错了什么?
1条答案
按热度按时间syqv5f0l1#
已验证用户的
Authentication
对象为:注意,
GrantedAuthorities
是Granted Authorities=[AGNI_OIMIVR]
,这里没有ROLE_
前缀。当您将@RolesAllowed("AGNI_OIMIVR")
添加到方法中时,ROLE_
前缀将自动添加到您作为参数传递给注解的权限中,成为ROLE_AGNI_OIMIVR
。Spring Security将尝试将注解中的
ROLE_AGNI_OIMIVR
与授权机构属性中的AGNI_OIMIVR
进行匹配,但是它们不匹配。您有三个选项:
1.将LDAP中的角色更改为具有
ROLE_
前缀1.公开
GrantedAuthorityDefaults
的Bean,移除rolePrefix
,如下所示:1.使用
@PreAuthorize("hasAuthority('AGNI_OIMIVR')")
另一个技巧是使用新的
@EnableMethodSecurity(jsr250Enabled = true)
,它使用简化的AuthorizationManager
API,改进日志记录等。