Spring Security 4 (02)—— 用户信息

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/NameGGG/article/details/76349828

序言

这一篇主要讲的是怎么加载用户信息,以及用户信息的认证

1.加载用户信息

1.1 内存加载

 <!--认证管理器 -->
    <security:authentication-manager alias="authenticationManager"> 
        <security:authentication-provider>
         <security:user-service>
           <security:user name="user" password="user" authorities="ROLE_USER" />
           <security:user name="admin" password="admin" authorities="ROLE_ADMIN" />
        </security:user-service>          
      </security:authentication-provider>        
    </security:authentication-manager>  
  • authentication-manage(认证管理器) 顾名思义就是用来管理认证的,不管是用户角色还是资源角色,还是其他的认证都是由authenticationManage来管理的。
  • authentication-provider(认证提供者) ,认证管理器不直接提供认证,而是有认证提供者来实现具体的认证。

1.2 数据库加载

在我们的实际项目中内存加载的方式肯定是不行的,我们用户信息都是存在数据库中的。
这时我们就要改写authentication-provider中的user-service,注入我们自己的UserDetailsService类来加载用户信息


    <security:authentication-manager alias="authenticationManager">     
        <!-- 数据库方式加载用户信息  -->     
        <security:authentication-provider user-service-ref="sysUserDetailsService"/>                 
    </security:authentication-manager>  

1.2.1 UserDetailsService

可以看到这是一个接口,用来加载用户信息的
这里写图片描述
可以看到这个类很简单就一个方法,只要继承这个类,实现这个方法就可以。

1.2.2 UserDetails

在UserDetailsService的返回值类型中我们可以知道UserDetails就是我们的用户信息了,我们要做的就是实现这个接口。UserDetails类中方法如下:

public interface UserDetails extends Serializable {
    Collection<? extends GrantedAuthority> getAuthorities(); //角色集合
    String getPassword(); 
    String getUsername(); 
    boolean isAccountNonExpired(); 
    boolean isAccountNonLocked();
    boolean isCredentialsNonExpired();
    boolean isEnabled();

1.2.3 GrantedAuthority

从UserDetails的getAuthorities() 方法我们可以看出来,用户角色是一个集合,同时集合中元素必须继了GrantedAuthority.
这里写图片描述
可以看到GrantedAuthority方法也很简单,只有一个getAuthority() 方法。如果我们不想实现GrantedAuthority接口也没有关系,毕竟为了一个字段实现一个接口是没有必要的。Spring Security为我们提供了三个默认的实现,我们通常用的是SimpleGrantedAuthority类。

1.2.4 SimpleGrantedAuthority

我们来看看SimpleGrantedAuthority类
这里写图片描述
可以看到SimpleGrantedAuthority只有一个接受String类型的构造器,说明我们在使用的过程中只需传入一个String类型的字符串。

1.2.5 例:

UserDetailsService
这里写图片描述
可以看到findUserByName方法返回一个SysUserDetails,SysUserDetails继承了UserDetails。同时在用户登录时使用SimpleGrantedAuthority类加入登录角色。

UserDetails
这里写图片描述
在这里我没有直接实现UserDetails方法,而是使用抽象类SysUserDetails实现了UserDetails的getAuthorities(),同时新增了getRoles和setRoles方法,因为Spring Security中要在权限中加入ROLE 前缀,这样可以在抽象类中统一处理。

然后我在继承SysUserDetails类,同时加入自定义的字段。
这里写图片描述


2. 用户信息认证

我们加载了用户信息后,下一步就进行用户信息的验证。我们先配置自己的认证实现,改写上面的authentication-manager

    <!--认证管理器 (自定义 )  -->
    <security:authentication-manager alias="sysAuthenticationManager">  
       <!--   身份验证(自定义) -->
        <security:authentication-provider ref="sysAuthenticationProvider"/> 
    </security:authentication-manager>

2 .1 AuthenticationProvider

要自定义认证,首先实现AuthenticationProvider接口。

public interface AuthenticationProvider {

    Authentication authenticate(Authentication authentication)
            throws AuthenticationException;

    boolean supports(Class<?> authentication);
}

2.2 例

@Service
public class SysAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String name = authentication.getName(); // 用户名
        String password =authentication.getCredentials().toString(); //密码

        //这里是我们自定义的用户加载方法   
        UserDetails userDetails =userDetailsService.loadUserByUsername(name);

        if(userDetails == null){
            throw new AuthenticationServiceException("用户名不存在!!!");
        }

        Mademd5 mad=new Mademd5();//MD5加密

        if(!userDetails.getPassword().equals(mad.toMd5(password))){
            throw new BadCredentialsException("密码错误");
        }

        if(userDetails.getAuthorities() == null){
            throw new AuthenticationServiceException(userDetails.getUsername()+"尚未分配角色!!!");
        }   
        //把用户信息封装成UsernamePasswordAuthenticationToken对象。
       return new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities());
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}

3. 总结

以上就是用户信息的加载和验证了。

猜你喜欢

转载自blog.csdn.net/NameGGG/article/details/76349828