当前位置: 首页 > 知识库问答 >
问题:

在Spring Boot JPA应用程序中使用角色

郑正阳
2023-03-14

我目前正在使用Spring启动在Java中开发一个Web应用程序。

我在应用程序中使用的内容:

  • MySQL作为数据源
  • ORM的HibernateJPA
  • Thymeleaf模板

目前,我的数据库有一个用户和角色表。登录、注册和会话工作正常。

我在网站上创建了一个仅限管理员的页面。

我在为用户创建和使用角色时遇到了问题。

我希望数据库中的每个用户都有一个角色,并且能够在站点上使用它。注册时的默认角色是“USER”,我可以在MySQL管理员中将用户的角色手动更改为“ADMIN”。

这是当前我的用户实体类:

@Entity
@Table(name = "user")
public class User extends Auditable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private int id;

@Column(name = "email", nullable = false, unique = true)
@Email(message = "Please provide a valid e-mail")
@NotEmpty(message = "Please provide an e-mail")
private String email;

@Column(name = "password")
@Transient
private String password;

@Column(name = "first_name")
@NotEmpty(message = "Please provide your first name")
private String firstName;

@Column(name = "last_name")
@NotEmpty(message = "Please provide your last name")
private String lastName;

@Column(name = "enabled")
private boolean enabled;

@Column(name = "confirmation_token")
private String confirmationToken;

@OneToOne(mappedBy="user", cascade={CascadeType.ALL})
private Role role;


public User() {
}

public User(String firstName, String lastName, String email, String password, Role role) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.email = email;
    this.password = password;
    this.role = role;
}

/** Getters and setters */

}

这是我的角色实体:

@Entity(name="role")
public class Role {

@Id
private Long id;

@OneToOne
private User user;
private Integer role;

/** Getters and setters */
}

按用户服务中的用户名加载:

@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
    User user = userRepository.findByEmail(email);
    if (user == null){
        throw new UsernameNotFoundException("Invalid username or password.");
    }
    return new org.springframework.security.core.userdetails.User(user.getEmail(),
            user.getPassword(), getAuthorities(user.getRole().getRole()));
}

但由于某些原因,这不起作用。它在数据库中创建“role”表,其中有两行

ID名称
1ROLE_USER
2 ADMIN

问题是,当我将用户保存到数据库时,我需要做什么来为我保存的用户设置角色?目前,我的表中的用户行都没有角色列。我如何让它工作,以便当我的安全配置中有一个规则时;

.hasRole("ADMIN")

它不允许没有该角色的用户访问?目前,当我尝试使用该规则访问页面时,它总是返回我配置的无访问权页面。

共有1个答案

施权
2023-03-14

下面是我实现注册并将rolse分配给注册用户的代码。

1)User.java(@实体)

@Entity
@Table(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long user_id;
    private String username;
    private String password;
    private boolean active;
    private String email;

    // user roles
    @ElementCollection(targetClass = Role.class, fetch = FetchType.EAGER)
    @CollectionTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"))
    @Enumerated(EnumType.STRING)
    private Set<Role> roles;

    // Constructors
    private User() {}

    public User(String username, String password, String email) {
        this.username = username;
        this.password = password;
        this.email = email;
    }

    // if user is admin
    public boolean isAdmin() {
        return roles.contains(Role.ADMIN);
    }


    // Below you can generate getters & setters & toString method.

    // Getter and setter for user roles
    public Set<Role> getRoles() {
        return roles;
    }

    public void setRoles(Set<Role> roles) {
        this.roles = roles;
    }
}

角色.java(枚举类型)

public enum Role {
    USER,
    ADMIN;

}

用户控制器.java (@Controller)

@Controller
public class UserController{

    //login page
    @GetMapping("/signin")
    public String loginPage() {
        return "frontend/login";
    }

    // registration page
    @GetMapping("/signup")
    public String signUpPage() {
        return "frontend/registration";
    }

    // User Registration
    @PostMapping("/signup")
    public String addUser(User user, Map<String, Object> model) {

        User userFromDB = userRepository.findByUsername(user.getUsername());
        if(userFromDB !=null ) {
            model.put("alreadyexists", "Username already exists!");
            return "frontend/registration";
        }

        // Set user apssword (also you can implement BCrypt)
        user.setPassword(user.getPassword());

        // set user activa
        user.setActive(true);

        // assign Rolr USER to newly registered user
        user.setRoles(Collections.singleton(Role.USER));


        userRepository.save(user);

        return "redirect:/profile";
    }
}

WebsecurityConfig.java(Spring安全)

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private DataSource dataSource;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http

                .authorizeRequests()
                .antMatchers("/","/signup").permitAll()
                .anyRequest().authenticated()
                .and()
                    .formLogin()
                    .loginPage("/signin").defaultSuccessUrl("/profile")
                    .permitAll()
                .and()
                    .logout().logoutRequestMatcher(new AntPathRequestMatcher("/signout")).logoutSuccessUrl("/signin?bye")
                    .permitAll();
    }


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication()
                .dataSource(dataSource)
                .usersByUsernameQuery("SELECT username, password, active FROM users WHERE username=?")
                .authoritiesByUsernameQuery("SELECT u.username, ur.roles FROM users u INNER JOIN user_role ur ON u.user_id = ur.user_id WHERE u.username=?");
    }
}
 类似资料:
  • 问题内容: 我一直在从事一个更像框架的项目,并且可以安装几个应用程序/模块。像基本的应用商店或google.play商店一样看到它。这是一个Intranet应用程序,所有模块都可以添加到您的用户帐户中。 该框架已经在开发中,但是我现在正在围绕应用程序/模块的想法。(链接到开发中的概念证明,可以在这里找到) 一个应用程序应该是独立的,并且不能突然包含框架中的脚本,这可以通过在单独的模块中进行结构化来

  • 我正在使用keycloak来保护我的servlet。我必须添加新角色并动态地将它们分配给用户。它使用管理应用编程接口在keycloak中工作,但是我不知道如何在servlet中获得特定用户的角色。 我尝试了这个解决方案,但我得到了空集:

  • 我试图理解我们什么时候需要使用这个应用程序。在我们的node Express中使用 当我在网上搜索时,我在reddit上偶然发现了这个答案,它说明了应用程序之间的区别。获取和应用程序。使用 在此基础上,我总结了以下几点。 充当超级路由或中间件?这意味着它在? 此外,如果有人能添加更多关于app.use.的信息/练习,我将不胜感激

  • 【注意】Azure SQL Database 不支持应用程序角色。下列选项和选项卡会根据服务器版本而有所不同。 常规属性 角色名 定义应用程序角色的名。 默认模式 选择将拥有此应用程序角色创建之对象的默认模式。 密码 指定应用程序角色的密码。 确认密码 重新输入密码。 拥有的模式 在列表里,勾选应用程序角色拥有的模式。 数据库权限 在网格中,勾选“权限”列出的数据库权限,勾选“授予”、“含授予选项

  • 【注意】Azure SQL Database 不支持应用程序角色。下列选项和选项卡会根据服务器版本而有所不同。 常规属性 角色名 定义应用程序角色的名。 密码 指定应用程序角色的密码。 确认密码 重新输入密码。 默认模式 选择将拥有此应用程序角色创建之对象的默认模式。 拥有的模式 在列表里,勾选应用程序角色拥有的模式。 数据库权限 在网格中,勾选“权限”列出的数据库权限,勾选“授予”、“授予选项”

  • 【注意】Azure SQL Database 不支持应用程序角色。下列选项和选项卡会根据服务器版本而有所不同。 常规属性 角色名 定义应用程序角色的名。 默认模式 选择将拥有此应用程序角色创建之对象的默认模式。 密码 指定应用程序角色的密码。 确认密码 重新输入密码。 拥有的模式 在列表里,勾选应用程序角色拥有的模式。 数据库权限 在网格中,勾选“权限”列出的数据库权限,勾选“授予”、“含授予选项