我目前正在使用Spring启动在Java中开发一个Web应用程序。
我在应用程序中使用的内容:
目前,我的数据库有一个用户和角色表。登录、注册和会话工作正常。
我在网站上创建了一个仅限管理员的页面。
我在为用户创建和使用角色时遇到了问题。
我希望数据库中的每个用户都有一个角色,并且能够在站点上使用它。注册时的默认角色是“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")
它不允许没有该角色的用户访问?目前,当我尝试使用该规则访问页面时,它总是返回我配置的无访问权页面。
下面是我实现注册并将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 不支持应用程序角色。下列选项和选项卡会根据服务器版本而有所不同。 常规属性 角色名 定义应用程序角色的名。 默认模式 选择将拥有此应用程序角色创建之对象的默认模式。 密码 指定应用程序角色的密码。 确认密码 重新输入密码。 拥有的模式 在列表里,勾选应用程序角色拥有的模式。 数据库权限 在网格中,勾选“权限”列出的数据库权限,勾选“授予”、“含授予选项