spring-security 403在 Spring Boot 托上引入授权时禁止

wvmv3b1j  于 2022-11-11  发布在  Spring
关注(0)|答案(1)|浏览(158)

我正在进行我的第一个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状态代码响应
我做错了什么?

syqv5f0l

syqv5f0l1#

已验证用户的Authentication对象为:

UsernamePasswordAuthenticationToken [Principal=LdapUserDetailsImpl [Dn=cn=ivr_apl_user,ou=IVR,ou=Aplicaciones,dc=pre,dc=aplssib; Username=ivr_apl_user; Password=[PROTECTED]; Enabled=true; AccountNonExpired=true; CredentialsNonExpired=true; AccountNonLocked=true; Granted Authorities=[AGNI_OIMIVR]], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[AGNI_OIMIVR]]

注意,GrantedAuthoritiesGranted 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,如下所示:

@Bean
GrantedAuthorityDefaults grantedAuthorityDefaults() {
    return new GrantedAuthorityDefaults("");
}

1.使用@PreAuthorize("hasAuthority('AGNI_OIMIVR')")
另一个技巧是使用新的@EnableMethodSecurity(jsr250Enabled = true),它使用简化的AuthorizationManager API,改进日志记录等。

相关问题