简体   繁体   English

Spring Boot项目中的Spring Security配置如何工作?

[英]How exactly works Spring Security configuration in this Spring Boot project?

I am not so into Spring Security . 我不太喜欢Spring Security I am working on a Spring Boot project (implementing some REST web sercices) where someone else have implemented Spring Security to perform authentication. 我正在一个Spring Boot项目(实现一些REST Web服务)中,其他人已经实现了Spring Security来执行身份验证。 It seems works fine but I have some doubts about how it exactly works (the architecture). 看起来不错,但我对它的工作原理(体系结构)有些怀疑。

So basically I have the following classes: 所以基本上我有以下课程:

1) User that is my model class representing a user: 1) 用户是我代表用户的模型类

@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
}

It is an hibernate class that provide the join with the user_user_roles database table containing the list of user rool associated to the specific user (I think the ROLE_ADMIN , ROLE_USER , etcetc) 这是一个休眠类,提供联接包含关联到特定的用户(我觉得ROLE_ADMIN,ROLE_USER,etcetc)用户ROOL列表中user_user_roles数据库表

2) Then I have CustomUserDetails class that extends User and implements Spring Security UserDetails interface. 2)然后我有CustomUserDetails类,该类扩展了User并实现了Spring Security UserDetails接口。

So it means that will contain all the information related to a specific user (among which the role associated to this user) and implement all the methods declared in the UserDetails interface. 因此,这意味着它将包含与特定用户有关的所有信息(其中包括与此用户相关联的角色),并实现在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();
    }

}

It seems to me that this class represent the bridge between Spring application and Spring Security (something like that carry the roles information related to a specific user, is it?). 在我看来,该类代表了Spring应用程序与Spring Security之间的桥梁(类似的东西带有与特定用户有关的角色信息,是吗?)。

In this class the information related to the list of roles of an user is contained into a collection of generic object that extends GrantedAuthority . 在此类中,与用户角色列表有关的信息包含在扩展GrantedAuthority的通用对象的集合中。

I think that the GrantedAuthority objects represents the roles of a user (infact are builded by role.getName() that is the string representing a role of the current user). 我认为GrantedAuthority对象表示用户的角色(实际上是由role.getName()构建的 ,该字符串是表示当前用户角色的字符串)。 Is it this reasoning correct? 这个推理正确吗?

Basically the prvious implementation only return the collection of GrantedAuthority related to a specific user, is it? 基本上,以前的实现只返回与特定用户相关的GrantedAuthority的集合,对吗?

3) The CustomUserDetailsService class implementing Spring Security UserDetailsService interface: 3)实现Spring Security UserDetailsS​​ervice接口的CustomUserDetailsS​​ervice类:

@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);
        }
    }

}

Basically this is a service that only implements the loadUserByUsername(String username)) method that do: 基本上,这是一个仅实现loadUserByUsername(String username))方法的服务,该方法执行以下操作:

  • First retrieve the information related the user (a User object) including the list of his roles ( List userRoles ). 首先检索与用户(一个User对象)有关的信息,包括他的角色列表List userRoles )。

  • Then use this User object to build the previous CustomUserDetails used to retrieve the collection of the GrantedAuthority related to the user. 然后,使用此User对象构建先前的CustomUserDetails,CustomUserDetails用于检索与该用户相关的GrantedAuthority的集合。

Is all these reasoning correct? 所有这些推理都正确吗?

Then I also have this WebSecurityConfig that I think represent the Spring Security configuration: 然后我还有这个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 {
    }
}

This is pretty obsucre for me. 这对我来说太晦涩了。 What exactly does? 到底是什么?

From what I have understand it is enabling the REST web services security by ** @EnableWebSecurity**. 据我了解,它通过** @ EnableWebSecurity **来启用REST Web服务安全性。

But why does the autowire of the UserDetailsService bean? 但是,为什么要自动装配UserDetailsS​​ervice Bean?

And what exactly foes this empty configure() method? 究竟该空的configure()方法是什么呢?

Your reasoning is correct. 您的推论是正确的。

Spring-security requires you to create a service which implements UserDetailsService . Spring-security要求您创建一个实现UserDetailsS​​ervice的服务。 It expects service to have loadUserByUsername method which returns user object (which needs to implement Spring's User class). 它期望服务具有loadUserByUsername方法,该方法返回用户对象(需要实现Spring的User类)。 This instance of user is used to get authorities so that you can restrict access to certain urls. 该用户实例用于获取权限,以便您可以限制对某些URL的访问。 ie you can map url access to users with specific authorities. 即,您可以将URL访问映射到具有特定权限的用户。

In terms of the empty method configure(), it is used to for authentication and authorisation of the urls (mentioned above) and few more things. 就空方法configure()而言,它用于url的身份验证和授权(如上所述)以及其他一些事情。 In fact, in terms of security, this is most flexible & powerful method available. 实际上,就安全性而言,这是最灵活,最强大的方法。

My project's config method looks like this: 我项目的config方法如下所示:

 @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' ");


    }

The above example 上面的例子

  • Ensures all requests are authenticated and authorized. 确保所有请求都经过身份验证和授权。
  • Permits free access to static resources 允许免费访问静态资源
  • Ensures url /admin is accessible only by users with role ADMIN 确保只有角色ADMIN的用户才能访问url / admin
  • Setup basic login prompt for authentication 设置基本登录提示以进行身份​​验证
  • Sets logout url 设置注销网址
  • Sets up cookie based CSRF token system 设置基于cookie的CSRF令牌系统
  • Sets content security policy 设置内容安全策略

To understand more about all spring-security features, I highly recommend these resources. 要了解有关所有春季安全性功能的更多信息,我强烈建议您使用这些资源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM