允许用户使用 jwt 在 Spring Boot 中选择资源

Posted

技术标签:

【中文标题】允许用户使用 jwt 在 Spring Boot 中选择资源【英文标题】:Allowing users to selected resources in spring boot using jwt 【发布时间】:2018-09-18 16:04:28 【问题描述】:

如标题所示,我正在尝试只让我的应用程序上的“ROLE_ADMIN”有权创建锦标赛。

我的用户:

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public long id;

private String username;

@Length(min = 2, max = 60)
private String password;

private String email;

private Long tsRegistration;

private Long tslLastLogin;

private Long bonusCredit;

private boolean enabled;

@ManyToMany
@JoinTable(name = "user_intournament", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
        inverseJoinColumns = @JoinColumn(name = "tournament_id", referencedColumnName = "id"))
public List<Tournament> tournament;

@ManyToMany
@JoinTable(
        name = "users_roles",
        joinColumns = @JoinColumn(
                name = "user_id", referencedColumnName = "id"),
        inverseJoinColumns = @JoinColumn(
                name = "role_id", referencedColumnName = "id"))
private Collection<Role> roles;



private boolean tokenExpired;

角色:

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

private String name;
@ManyToMany(mappedBy = "roles")
private Collection<ApplicationUser> users;

@ManyToMany
@JoinTable(
        name = "roles_privileges",
        joinColumns = @JoinColumn(
                name = "role_id", referencedColumnName = "id"),
        inverseJoinColumns = @JoinColumn(
                name = "privilege_id", referencedColumnName = "id"))
private Collection<Privilege> privileges;

和特权等级:

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

private String name;

@ManyToMany(mappedBy = "privileges")
private Collection<Role> roles;

我创建了一个具有管理员权限的示例测试用户:

    @Override
    @Transactional
    public void onApplicationEvent(ContextRefreshedEvent event) 

        if (alreadySetup)
            return;
        Privilege readPrivilege
                = createPrivilegeIfNotFound("READ_PRIVILEGE");
        Privilege writePrivilege
                = createPrivilegeIfNotFound("WRITE_PRIVILEGE");

        List<Privilege> adminPrivileges = Arrays.asList(
                readPrivilege, writePrivilege);
        createRoleIfNotFound("ROLE_ADMIN", adminPrivileges);
        createRoleIfNotFound("ROLE_USER", Arrays.asList(readPrivilege));

        Role adminRole = roleRepository.findByName("ROLE_ADMIN");
        ApplicationUser user = new ApplicationUser();
        user.setUsername("Test");
        // user.setLastName("Test");
        user.setPassword(passwordEncoder.encode("test"));
        user.setEmail("test@test.com");
        user.setRoles(Arrays.asList(adminRole));
        user.setEnabled(true);
        userRepository.save(user);

        alreadySetup = true;

    

之后,在我的WebSecurity 上,我只允许具有admin 角色的用户执行操作。

@Override
protected void configure(HttpSecurity http) throws Exception 
    http.cors().and().csrf().disable().authorizeRequests()
            .antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll()
            .antMatchers(HttpMethod.POST, "/tournaments").access("hasRole('ROLE_ADMIN')")
            .anyRequest().authenticated()
            .and()
            .addFilter(new JWTAuthenticationFilter(authenticationManager()))
            .addFilter(new JWTAuthorizationFilter(authenticationManager()))
            // this disables session creation on Spring Security
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

我尝试使用 .hasRole("ADMIN")hasAuthority("ROLE_ADMIN") 但它不起作用,因为我收到 403 禁止消息。

我设法通过邮递员使用“测试”和“测试”凭据登录并检索不记名令牌,这使我可以访问所有需要身份验证的资源,但需要管理员角色的资源除外。

【问题讨论】:

【参考方案1】:

你可以试试这个

.antMatchers(HttpMethod.POST, "/tournaments/**").access("hasRole('ROLE_ADMIN')")

【讨论】:

以上是关于允许用户使用 jwt 在 Spring Boot 中选择资源的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 安全配置忽略允许的端点

Spring Boot 自定义 JWT 过滤器不允许任何没有令牌的请求

如何在使用 Spring Boot 的 JWT 令牌时禁用同一用户帐户的多个登录

在 Spring Boot 中使用 JWT 进行简单的身份验证

来自文件的 Spring Boot http 安全 jwt 密钥

Spring Boot认证:整合Jwt