• spring boot系列03--spring security (基于数据库)登录和权限控制(下)


    (接上篇)

    后台


     先说一下AuthConfig.java Spring Security的主要配置文件之一 AuthConfig

     1 @Configuration
     2 @EnableWebSecurity
     3 public class AuthConfig extends WebSecurityConfigurerAdapter {
     4     @Override
     5     protected void configure(HttpSecurity httpSecurity) throws Exception {
     6         httpSecurity.authorizeRequests()
     7         .antMatchers("/css/**","/staic/**", "/js/**","/images/**").permitAll()
     8         .antMatchers("/", "/login","/session_expired").permitAll()
     9            .and()
    10      .formLogin()
    11         .loginPage("/login")
    12         .defaultSuccessUrl("/main_menu")
    13         .failureUrl("/loginError")
    14         .usernameParameter("txtUserCd")
    15         .passwordParameter("txtUserPwd")
    16         .permitAll()
    17         .and()
    18         .logout()
    19         .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
    20         .logoutSuccessUrl("/")
    21         .deleteCookies("JSESSIONID")
    22         .invalidateHttpSession(true)
    23         .permitAll()
    24         .and()
    25         .sessionManagement()
    26         .invalidSessionUrl("/session_expired")
    27         .maximumSessions(1)
    28         .maxSessionsPreventsLogin(true)
    29         .expiredUrl("/session_expired");
    30         httpSecurity.logout().permitAll();
    31 
    32     }
    33     
    34      @Autowired
    35      AuthUserService authUserService;
    36     public void globalAuthConfig(AuthenticationManagerBuilder auth) throws Exception {
    37         auth.userDetailsService(authUserService);
    38       //auth.inMemoryAuthentication().withUser("user").password("password");
    39     }
    40     /*@Configuration
    41     protected static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter {
    42         @Autowired
    43         AuthUserService authUserService;
    44     
    45         @Override
    46         public void init(AuthenticationManagerBuilder auth) throws Exception {
    47             //auth.inMemoryAuthentication().withUser("user").password("password");
    48             auth.userDetailsService(authUserService);
    49         }
    50     }*/
    51 }

    一、configur方法 基本配置

    No Source Comment
    L1 @Configuration 这个就是java形式的bean spring3.0以后 允许以 @Configuration 注解来代替XML形式的bean
    L2 @EnableWebSecurity 用这个注解开启 spring security配置验证开启
    L3 WebSecurityConfigurerAdapter 这个需要我们继承WebSecurityConfigurerAdapter适配器且重写

     configure 函数 来实现访问的控制(那些访问/资源 需要哪些权限)和登录的验证(数据库验证/内存验证)

    L6 authorizeRequests() 通过authorizeRequests()配下的子函来完成访问/授权 配置
    L7,8 antMatchers/permitAll antMatchers里配置的资源是可以被所有用户访问(permitAll)的
    L9 and() 类似于结束标签
    L10 formLogin 通过formLogin()配下的函数对登录form进行配置
    L11 loginPage 设置登录页面
    L12 defaultSuccessUrl 默认登录成功跳转地址
    L13 failureUrl 默认登录失败跳转地址
    L14,15 usernameParameter
    passwordParameter
    用户名密码验证用 *这里的参数要和画面上控件名保持一致
    L18  logout() 通过logout()配下的函数对注销进行配置
    L19 .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) 设置注销用的请求URL
    L20 logoutSuccessUrl 设置注销成功后的跳转URL
    L21 deleteCookies 消除Cookie
    L22 invalidateHttpSession 销毁Session
    L25 sessionManagement 通过sessionManagement配下的函数对session配置
    L27 maximumSessions 同一用户session上限设定 *比如同一个用户 多次登录
    L28 maxSessionsPreventsLogin maximumSessions设定的上限启用 * 超出报错
    L29 expiredUrl

    超过session上限跳转URL设定

     二、globalAuthConfig方法 认证

    先说L38 这行注掉的 是内存认证模式  意思是创建了一个 名为user 密码 为password的用户

    然后是 L37 这也是认证核心

    先看一下这个 传入参数的的构成 也就是 AuthUserService 类

     1 @Service
     2 public class AuthUserService implements UserDetailsService{
     3 
     4     @Autowired
     5     MstUsersMapper mstUsersMapper;
     6     
     7     @Override
     8     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
     9         Users users =mstUsersMapper.selectByPrimaryKey(username);
    10         if(users == null) {
    11             throw new UsernameNotFoundException("User not found for name:"+username);
    12         }
    13         return new AuthUser(users);
    14     }
    15     
    16     public String getAuthorityByLoginId(String loginId ){
    17         //Map<String,String> authKindMap = new HashMap<String,String>();
    18         String auth = mstUsersMapper.selectAuthorityByLoginId(loginId); 
    19         return auth;
    20     }
    21 }

    可以看到我们是 实现了UserDetailsService 然后重写了一个loadUserByUsername和追加了一个 getAuthorityByLoginId函数

    关于 getAuthorityByLoginId 好说的基本上就是 当前用户的权限

    然后是loadUserByUsername

    可以通过名字基本上可以看的出是 通过name 取user 的信息 实际上也是这样 这里并不判断你输的密码对不对 主要是

    判断你输入的用户名在数据库里存不存在 不存在 报错 扔出 存在 实例化一个 AuthUser 返回

    这个AuthUser 类也很重要 实现了UserDetails  如下

     1 public class AuthUser implements UserDetails {
     2     private static final long serialVersionUID = 1L;
     3     
     4     private String userId;
     5     private String loginId;
     6     private String password;
     7     private String authorityKind;
     8     public AuthUser(Users users) {
     9         super();
    10         this.userId = users.getUserId();
    11         this.loginId = users.getLoginId();
    12         this.password = users.getPassword();
    13         this.authorityKind = users.getAuthorityKind();
    14     }
    15 
    16     @Override
    17     public Collection<GrantedAuthority> getAuthorities() {
    18         List<GrantedAuthority> list = new ArrayList<GrantedAuthority>();
    19         list.add(new SimpleGrantedAuthority(authorityKind));
    20         return list;
    21     }
    22 
    23     @Override
    24     public String getPassword() {
    25         return password;
    26     }
    27 
    28     @Override
    29     public String getUsername() {
    30         return loginId;
    31     }
    32 
    33     @Override
    34     public boolean isAccountNonExpired() {
    35         return true;
    36     }
    37 
    38     @Override
    39     public boolean isAccountNonLocked() {
    40         return true;
    41     }
    42 
    43     @Override
    44     public boolean isCredentialsNonExpired() {
    45         return true;
    46     }
    47 
    48     @Override
    49     public boolean isEnabled() {
    50         return true;
    51     }

     这里的几个点要注意一下

    L17 getAuthorities 它返回了一个权限集合 这个集合是和你在画面侧用的hasAnyAuthority('ROLE_USER','ROLE_ADMIN') 这个函数相呼应的

    换言之你之所以能在画面侧如上那样写也是因为你在这里吧把当前用户的权限set进去了

    然后看一下我们实现的 UserDetails这个父类,如下官网文档给的信息.

    NoModifier and TypeMethod and Description
    1 java.util.Collection<? extends GrantedAuthority> getAuthorities()
    Returns the authorities granted to the user.
    2 java.lang.String getPassword()
    Returns the password used to authenticate the user.
    3 java.lang.String getUsername()
    Returns the username used to authenticate the user.
    4 boolean isAccountNonExpired()
    Indicates whether the user's account has expired.
    5 boolean isAccountNonLocked()
    Indicates whether the user is locked or unlocked.
    6 boolean isCredentialsNonExpired()
    Indicates whether the user's credentials (password) has expired.
    7 boolean isEnabled()
    Indicates whether the user is enabled or disabled.

     前3个应该不用说了,从第四个开始说一下

    isAccountNonExpired():当前账号是否已经过期

    isAccountNonLocked()当前账号是否被锁

    isCredentialsNonExpired()当前账号证书(密码)是否过期

    isEnabled()当前账号是否被禁用

    都要给设成true 否则登录会报出来

    还有实现一个UserDetailsService类如下

     1 @Service
     2 public class AuthUserService implements UserDetailsService{
     3 
     4     @Autowired
     5     MstUsersMapper mstUsersMapper;
     6     
     7     @Override
     8     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
     9         Users users =mstUsersMapper.selectByPrimaryKey(username);
    10         if(users == null) {
    11             throw new UsernameNotFoundException("User not found for name:"+username);
    12         }
    13         return new AuthUser(users);
    14     }
    15     
    16     public String getAuthorityByLoginId(String loginId ){
    17         //Map<String,String> authKindMap = new HashMap<String,String>();
    18         String auth = mstUsersMapper.selectAuthorityByLoginId(loginId); 
    19         return auth;
    20     }
    21 }
    如你看到那样loadUserByUsername这函数并不做密码验证只是拿username取用户信息,当然取不到报错
    取到交给AuthUser,然后spring boot 自己再去判断密码,以及前面说的那个几个check
    剩下的就是 Controller这个就没有特别要说的到git上看代码就完了
    最后贴一下执行效果图及git地址

    (完)

  • 相关阅读:
    面板数据及其基本模型
    markdwon编辑公式入门
    向纳什大神致敬
    我和我的祖国观后感
    少年的你观后感
    特征选择学习笔记1(综述)
    时间序列学习笔记1
    《绿皮书》观后感
    《美丽心灵》观后感
    pycharm跨目录调用文件
  • 原文地址:https://www.cnblogs.com/zhufu9426/p/8086128.html
Copyright © 2020-2023  润新知