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

来源:互联网 发布:2016淘宝网红店铺排名 编辑:程序博客网 时间:2024/06/15 21:50

序言

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

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 例

@Servicepublic 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. 总结

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