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

在这个Spring Boot项目中Spring Security配置到底是如何工作的?

左丘烨烁
2023-03-14

我对Spring安全没那么感兴趣。我正在进行一个Spring Boot项目(实现一些REST web服务),在这个项目中,其他人已经实现了Spring Security来执行身份验证。它看起来工作得很好,但我对它到底是如何工作的(架构)有些怀疑。

所以基本上我有以下几个班:

1)表示用户的我的模型类User:

@Entity
@Table(name = "user",
        uniqueConstraints = {
        @UniqueConstraint(columnNames = {"email","username"})
})
public class User  {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;


    //@Pattern(regexp="\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b",flags = Pattern.Flag.CASE_INSENSITIVE)
    @Column(name="email", unique=true,nullable=false)
    private String email;

    @NotNull
    @Column(name="registration_date",nullable=false)
    private Date registration_date;

    @NotBlank
    @Column(name="username",nullable = false,unique=true)
    private String username;

    @NotBlank
    @Column(name="password",nullable = false)
    private String password;


    @Column(name="enabled", nullable = false)
    private boolean enabled;

    @ManyToMany
    @JoinTable(name = "user_user_roles", joinColumns = {
            @JoinColumn(name = "id_user", updatable = true) },
            inverseJoinColumns = { @JoinColumn(name = "id_roles",
                    updatable = true)},
            uniqueConstraints={@UniqueConstraint(columnNames = {"id_user","id_roles"})}
    )
    @Cascade({CascadeType.DETACH,CascadeType.MERGE,CascadeType.REFRESH,CascadeType.PERSIST,
            CascadeType.SAVE_UPDATE})
    private List<UserRole> userRoles;

    // CONSTRUCTOR, GETTER AND SETTER METHODS
}

因此,它意味着将包含与特定用户相关的所有信息(其中包括与此用户关联的角色),并实现在UserDetails接口中声明的所有方法。

public class CustomUserDetails extends User implements UserDetails {

    private static final long serialVersionUID = 1L;


    public CustomUserDetails(User user){
        super(user);
    }


    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
        for(UserRole role : this.getUserRoles() ){
            GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role.getName());
            authorities.add(grantedAuthority);
        }

        return authorities;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }
    @Override
    public boolean isEnabled() {
        return true;
    }

    @Override
    public String getUsername() {
        return super.getUsername();
    }

}

在我看来,这个类代表了Spring application和Spring Security之间的桥梁(类似的东西承载了与特定用户相关的角色信息,是吗?)。

在该类中,与用户角色列表相关的信息包含在扩展GrantedAuthority的泛型对象集合中。

@Transactional
@Service("customUserDetailsService")
public class CustomUserDetailsService implements UserDetailsService{
    @Autowired
    private UserDAO userDao;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userDao.findByUsername(username);
        if(user == null){
            throw new UsernameNotFoundException("No user present with username: "+username);
        }else{
            return new CustomUserDetails(user);
        }
    }

}

基本上,这是一个只实现loadUserByUsername(String username)方法的服务,该方法执行:

>

  • 首先检索与用户(用户对象)相关的信息,包括他的角色列表(list userRoles)。

    然后使用此User对象生成以前的CustomUserDetails,该CustomUserDetails用于检索与用户相关的GrantedAuthority的集合。

    然后我还有一个WebSecurityConfig,我认为它代表Spring Security配置:

    @Configuration
    @EnableWebSecurity
    @ComponentScan(basePackageClasses = CustomUserDetailsService.class)
    @EnableAutoConfiguration
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Autowired 
        private UserDetailsService userDetailsService;
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
        }
    }
    

    这对我来说很难理解。到底是什么?

    根据我的理解,它是通过**@enablewebsecurity**启用REST web服务安全性。

  • 共有1个答案

    曹乐意
    2023-03-14

    你的推理是正确的。

    Spring-security要求您创建一个实现UserDetailsService的服务。它希望service具有loadUserByUsername方法,该方法返回user对象(需要实现Spring的user类)。此user实例用于获取权限,以便您可以限制对某些URL的访问。即可以将url访问映射到具有特定权限的用户。

    就空方法configure()而言,它用于对URL进行身份验证和授权(上面提到过),其他的很少。事实上,在安全性方面,这是最灵活和最强大的方法。

     @Override
        protected void configure(HttpSecurity http) throws Exception {
    
            http
                    .authorizeRequests()
                        .antMatchers("/","/static/**").permitAll()
                        .mvcMatchers("/admin").access("hasAuthority('ROLE_ADMIN')")
                        .mvcMatchers("/employees").access("hasAuthority('ROLE_STAFF')")
                        .anyRequest().authenticated()
                        .and()
                    .httpBasic()
                        .and()
                      .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                        .and()
                        .logout().logoutSuccessUrl("/")
                        .and()
                    .headers().contentSecurityPolicy("default-src 'self' " +
                                                     "https://ajax.googleapis.com " +
                                                     "https://cdnjs.cloudfare.com " +
                                                     "style-src 'self' 'unsafe-inline' ");
    
    
        }
    

    上述示例

    • 确保所有请求都经过身份验证和授权。
    • 允许自由访问静态资源
    • 确保url/ADMIN只能由具有ADMIN角色的用户访问
    • 设置身份验证的基本登录提示
    • 设置注销URL
    • 设置基于cookie的CSRF令牌系统
    • 设置内容安全策略

    要了解更多关于所有spring-security特性的信息,我强烈推荐使用这些资源。

      null
     类似资料:
    • 这是对二分搜索树的wrt。我以两种方式遍历树。1)顺序遍历树t的顺序遍历是一种递归算法,它遵循左子树;一旦没有更多的左子树要处理,我们就处理右子树。元素按左-根-右顺序处理。2)后顺序遍历树t的后顺序遍历是一种递归算法,它在处理根元素之前遵循左和右子树。元素按左-右-根顺序处理。 我对递归方法和print语句是如何工作的感到困惑。你能给我开导一下吗?

    • 我们知道主存域很少:年轻的、终生的(旧的gen)和PermGen。 年轻领域分为伊甸园和幸存者(有两个)。 OldGen用于生存的对象。 MaxTenuringThreshold防止对象过早地被最终复制到OldGen空间。这很清楚,也很容易理解。 但是它是如何工作的呢?垃圾回收器如何处理这些在MaxTenuringThreshold之前仍然存在的对象,以何种方式?它们位于何处? 对象被复制回幸存者

    • 我正在学习Spring核心认证,我对Spring如何处理bean生命周期有一些疑问,特别是bean后处理器。 所以我有了这个模式: 我很清楚这意味着什么: 然后在bean创建阶段执行以下步骤: > 每个bean都在缺省情况下被急切地实例化(按照正确的顺序创建,并注入其依赖项)。 在依赖注入之后,每个bean都会经历一个后处理阶段,在这个阶段中可能会进行进一步的配置和初始化。 > 初始化器:如果指示

    • 我正在为Spring Core认证学习,对于使用Java配置方式配置Bean的相关练习,我有以下疑问。 Java配置的正确解释是Spring吗? 例如,我可以说RewardNetwork是声明的bean,而RewardNetworkImpl是这个bean的当前实现吗? 所有的3Beans(AccountRepository,RestaurantRepository和RewardRepository

    • 我正在学习Spring核心认证,不清楚如何将Spring Security项目配置到应用程序中。 在课程留档中,我发现了以下2个代码片段: 1) 在web中进行配置。xml: 我对JavaEE(以及Spring)非常陌生,所以在网上阅读时,我明白这个过滤器有点像Servlet,它对资源(servlet或静态内容)的请求或来自资源或两者的响应。因此,如果标准Servlet是用于处理请求、创建内容和给

    • 问题内容: 我一直在阅读其手册页,但尚未成功弄清其工作原理。在调用system()时,是否分叉了一个新的子进程,并在其中添加了shell二进制文件exec()?但这可能是一个愚蠢的猜测。 问题答案: 是的,system()本质上是传递的命令字符串的fork()和exec()“ sh -c”。可以在此处找到示例实现(来自eglibc,最近来自glibc)。